diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..1f3b963c9 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,19 @@ +version: 2 +updates: + # Enable checks for the default vendor folder + - package-ecosystem: "composer" + directory: "/" + schedule: + interval: "weekly" + + # Enable checks for Google API Client package + - package-ecosystem: "composer" + directory: "/lib/Google" + schedule: + interval: "weekly" + + # Enable checks for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml new file mode 100644 index 000000000..cae1fa971 --- /dev/null +++ b/.github/workflows/publish-release.yml @@ -0,0 +1,150 @@ +name: Publish Release +run-name: Publish Release + +on: + workflow_dispatch: + inputs: + release: + description: 'Release version (e.g. 1.2.3)' + required: true + prerelease: + description: 'Pre-release version (e.g. RC1, beta, etc...)' + required: false + +permissions: + contents: write + +env: + TAG: ${{ github.event.inputs.release }} + PRETAG: ${{ github.event.inputs.prerelease }} + BRANCH: temp-release-${{ github.event.inputs.release }} + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Prepare vars + id: vars + uses: actions/github-script@v7 + with: + script: | + const full_tag = [ + process.env.TAG, + process.env.PRETAG + ].filter(Boolean).join('-'); + const branch = `temp-release-${full_tag}`; + const is_prerelease = !!process.env.PRETAG; + + core.setOutput('full_tag', full_tag ); + core.setOutput('branch', branch ); + core.setOutput('is_prerelease', is_prerelease ); + + # 'ref' and 'repository' are required, otherwise repo could appear in detached head state + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ github.head_ref }} + repository: ${{ github.repository }} + + - name: Parse Changelog Entries + uses: actions/github-script@v7 + id: changelog + with: + script: | + const { open } = require('fs/promises'); + + const version = process.env.TAG; + const delimiter = '#### '; + const file = await open('./changes.md'); + + let description = []; + let found = false; + + for await (let line of file.readLines()) { + line = line.trim(); + + if ( line.startsWith(`${delimiter}${version}`) ) { + found = true; + continue; + } + + if (!found) continue; + if ( line.startsWith(delimiter) ) break; + + description.push(line); + } + + if ( !description.length ) core.setFailed(`Release ${version} not found in the changelog!`); + + core.setOutput('description', description.join('\n') ); + + + # cleanup files that are not needed for the release + # but keep the .git folder, because we need it for the next step + - name: Cleanup files + run: | + rm -f composer.lock || true + rm -rf vendor/composer/installers || true + find ./ -name '.git*' -not -path './.git' -type f -delete || true + find ./ -name '.git*' -not -path './.git' -type d -exec rm -rf {} \; || true + find ./vendor -name .svn -exec rm -rf {} \; || true + + # cleanup files, specific to Google API PHP library + - name: Cleanup files for Google API library + run: | + rm -f lib/Google/phpstan.neon.dist || true + rm -f lib/Google/vendor/paragonie/random_compat/build-phar.sh || true + find ./lib/Google/ -name '.repo-metadata.json' -type f -delete || true + find ./lib/Google/vendor -name .svn -exec rm -rf '{}' \; || true + + # commit changes to temporary release branch and create a new tag + - name: Commit changes + uses: EndBug/add-and-commit@v9 + with: + message: Cleanup files for release + new_branch: ${{ steps.vars.outputs.branch }} + tag: ${{ steps.vars.outputs.full_tag }} + + # generate SBOM that will be attached to a release as an artifact + - name: Create SBOM + id: sbom + uses: anchore/sbom-action@v0 + with: + path: . + output-file: sbom.spdx.json + format: spdx-json + + # create a draft release with the version changelog as a description + - name: Create Draft Release + id: draft_release + uses: softprops/action-gh-release@v1 + with: + name: "Release ${{ steps.vars.outputs.full_tag }}" + body: "${{ steps.changelog.outputs.description }}" + tag_name: ${{ steps.vars.outputs.full_tag }} + draft: true + prerelease: ${{ steps.vars.outputs.is_prerelease }} + + # attach SBOM to release + - name: Upload SBOM to release + uses: actions/upload-release-asset@v1.0.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.draft_release.outputs.upload_url }} + asset_path: ./sbom.spdx.json + asset_name: sbom.spdx.json + asset_content_type: application/json + + # publish release using an ID from the 'draft_release' step + - name: Publish Release + uses: eregon/publish-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + release_id: ${{ steps.draft_release.outputs.id }} + + # delete temporary release branch + - name: Delete temporary release branch + run: | + git push origin --delete ${{ steps.vars.outputs.branch }} diff --git a/.github/workflows/security-scan.yml b/.github/workflows/security-scan.yml new file mode 100644 index 000000000..5f54c716f --- /dev/null +++ b/.github/workflows/security-scan.yml @@ -0,0 +1,25 @@ +name: Security Scan +run-name: Security Scan + +on: + push: + pull_request: + workflow_dispatch: + +jobs: + code-scanning: + name: Code Scanning (grype) + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Run Security Check + id: test + uses: anchore/scan-action@v3 + with: + path: . + output-format: table + + diff --git a/Gruntfile.js b/Gruntfile.js deleted file mode 100644 index f86814ee3..000000000 --- a/Gruntfile.js +++ /dev/null @@ -1,237 +0,0 @@ -/** - * Build Plugin - * - * @author Usability Dynamics, Inc. - * @version 2.0.0 - * @param grunt - */ -module.exports = function build( grunt ) { - - // Automatically Load Tasks. - require( 'load-grunt-tasks' )( grunt, { - pattern: 'grunt-*', - config: './package.json', - scope: 'devDependencies' - }); - - grunt.initConfig( { - - package: grunt.file.readJSON( 'composer.json' ), - - markdown: { - all: { - files: [ - { - expand: true, - src: 'readme.md', - dest: 'static/', - ext: '.html' - } - ], - options: { - markdownOptions: { - gfm: true, - codeLines: { - before: '', - after: '' - } - } - } - } - }, - - // Compile LESS - less: { - production: { - options: { - yuicompress: true, - relativeUrls: true - }, - files: {} - }, - development: { - options: { - relativeUrls: true - }, - files: {} - } - }, - - watch: { - options: { - interval: 100, - debounceDelay: 500 - }, - less: { - files: [ - 'static/styles/src/*.*' - ], - tasks: [ 'less' ] - }, - js: { - files: [ - 'static/scripts/src/*.*' - ], - tasks: [ 'uglify' ] - } - }, - - uglify: { - production: { - options: { - mangle: false, - beautify: false - }, - files: [ - { - expand: true, - cwd: 'static/scripts/src', - src: [ '*.js' ], - dest: 'static/scripts' - } - ] - }, - staging: { - options: { - mangle: false, - beautify: true - }, - files: [ - { - expand: true, - cwd: 'static/scripts/src', - src: [ '*.js' ], - dest: 'static/scripts' - } - ] - } - }, - - 'json-minify': { - build: { - files: 'composer.json' - } - }, - - clean: { - update: [ - "composer.lock" - ], - all: [ - "vendor", - "composer.lock" - ] - }, - - shell: { - /** - * Make Production Build and create new tag ( release ) on Github. - */ - release: { - command: function( tag ) { - return [ - 'sh build.sh ' + tag - ].join( ' && ' ); - }, - options: { - encoding: 'utf8', - stderr: true, - stdout: true - } - }, - /** - * Runs PHPUnit test, creates code coverage and sends it to Scrutinizer - */ - coverageScrutinizer: { - command: [ - 'grunt phpunit:circleci --coverage-clover=coverage.clover', - 'wget https://scrutinizer-ci.com/ocular.phar', - 'php ocular.phar code-coverage:upload --format=php-clover coverage.clover' - ].join( ' && ' ), - options: { - encoding: 'utf8', - stderr: true, - stdout: true - } - }, - /** - * Runs PHPUnit test, creates code coverage and sends it to Code Climate - */ - coverageCodeClimate: { - command: [ - 'grunt phpunit:circleci --coverage-clover build/logs/clover.xml', - 'CODECLIMATE_REPO_TOKEN='+ process.env.CODECLIMATE_REPO_TOKEN + ' ./vendor/bin/test-reporter' - ].join( ' && ' ), - options: { - encoding: 'utf8', - stderr: true, - stdout: true - } - }, - /** - * Composer Install - */ - install: { - command: function( env ) { - if( typeof env !== 'undefined' && env == 'dev' ) { - return [ - "COMPOSER_CACHE_DIR=/dev/null composer install" - ].join( ' && ' ); - } else { - return [ - "COMPOSER_CACHE_DIR=/dev/null composer install --no-dev", - "rm -rf ./vendor/composer/installers", - "find ./vendor -name .git -exec rm -rf '{}' \\;", - "find ./vendor -name .svn -exec rm -rf '{}' \\;", - ].join( ' && ' ); - } - }, - options: { - encoding: 'utf8', - stderr: true, - stdout: true - } - } - }, - - // Runs PHPUnit Tests - phpunit: { - classes: {}, - options: { - bin: './vendor/bin/phpunit', - }, - local: { - configuration: './test/php/phpunit.xml' - }, - circleci: { - configuration: './test/php/phpunit-circle.xml' - } - } - - }); - - // Register tasks - grunt.registerTask( 'default', [ 'markdown', 'less' , 'uglify' ] ); - - // Run default Tests - grunt.registerTask( 'localtest', [ 'phpunit:local' ] ); - grunt.registerTask( 'test', [ 'phpunit:circleci' ] ); - - // Run coverage tests - grunt.registerTask( 'testscrutinizer', [ 'shell:coverageScrutinizer' ] ); - grunt.registerTask( 'testcodeclimate', [ 'shell:coverageCodeClimate' ] ); - - // Install Environment - grunt.registerTask( 'install', 'Run all my install tasks.', function( env ) { - if ( env == null ) env = 'no-dev'; - grunt.task.run( 'clean:all' ); - grunt.task.run( 'shell:install:' + env ); - }); - - // Make Production Build and create new tag ( release ) on Github. - grunt.registerTask( 'release', 'Run all my release tasks.', function( tag ) { - if ( tag == null ) grunt.warn( 'Release tag must be specified, like release:1.0.0' ); - grunt.task.run( 'shell:release:' + tag ); - }); - -}; diff --git a/Makefile b/Makefile deleted file mode 100644 index c33519a33..000000000 --- a/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -## Build Plugin -## -## - -NAME = stateless-media - -# Default Install Action -default: - npm install - -# Install project -# - Removes composer.lock, vendor -# - Runs composer install --no-dev -# - Removes extra files. -install: - echo Install $(NAME). - make default - grunt install - -# Creates Release with Build Distribution -# Example: -# make TAG=1.0.0 release -release: - @echo Releasing $(NAME). - make default - sh build.sh $(TAG) \ No newline at end of file diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..bf9646448 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,23 @@ +# Security Policy Overview + +Thank you for using and contributing to our product. At [UDX](https://udx.io), we take the security of our products seriously and appreciate collaborative efforts to ensure the safety of our users and contributors. + +## Reporting a Security Vulnerability + +**Please do not report security vulnerabilities through public GitHub issues.** + +If you find a security vulnerability, please [submit a vulnerability report](https://github.com/udx/wp-stateless/security/advisories/new). Provide detailed information about the vulnerability to help us understand and address the issue promptly. We kindly request that you avoid public disclosure until we've had the opportunity to analyze and resolve the reported issue. + +## Responsible Disclosure + +Responsible disclosure is crucial to maintaining the security of our product. We ask for your cooperation in allowing us sufficient time to investigate and address the reported vulnerability before making it public. We will keep you informed of our progress and make every effort to address the issue promptly. + +## Supported Versions + +Security updates are provided for the latest stable release. Please ensure that you are using a supported version before reporting a security vulnerability. + +## Contact Information + +For security-related matters, please contact our security team at [security@udx.io](mailto:security@udx.io). For general inquiries, feature requests, and other non-security-related discussions, please use our regular [issue tracker](https://github.com/udx/wp-stateless/issues). + +Thank you for helping us ensure the security of WP-Stateless. Your contributions are greatly appreciated. diff --git a/build.sh b/build.sh deleted file mode 100644 index 6fcbf6793..000000000 --- a/build.sh +++ /dev/null @@ -1,233 +0,0 @@ -#!/bin/bash - -############################################################################################ -# -# Automatic Distribution Build and Tag creating on GitHub -# -############################################################################################ -# -# Script by default does the following steps: -# - creates temp directory -# - clones git repository there -# - creates temp branch -# - installs composer and nodes dependencies -# - adds vendor directory ( composer dependencies ) to commit -# - clears out build -# - commits build to temp branch -# - creates new tag -# - removes temp branch -# - removes temp directory -# -############################################################################################ -# -# Options: -# - $1 ( $RELEASE_VERSION ) - Required. Tag version which will be created for current build -# -############################################################################################ -# -# Features: -# - The current script generates new Tag on GitHub for your build (Distributive). -# - circleci compatible. It can use the latest commit log for creating new tag via CircleCI. -# Log message should contain [release:{tag}] shortcode -# -############################################################################################ -# -# Examples: -# -# Run remote sh file: -# curl -s https://url-to-release-sh-file.sh | RELEASE_VERSION=1.2.3 sh -# -# Run local sh file -# sh build.sh 1.2.3 -# -# Run grunt task ( see information about gruntfile.js below ) -# grunt release:1.2.3 -# -############################################################################################ -# -# CircleCi -# The current script can be triggered on CircleCi. -# Add the following settings to your circle.yml file: -# -# deployment: -# production: -# branch: master -# commands: -# - sh build.sh -# -# Notes: -# - Log ( commit ) message should contain [release:{tag}] shortcode for running script. -# - script will be triggered only on successful (green) build for 'master' branch in -# current example. -# - in random cases gist file is not available on curl request, I suggest to -# download script and call it directly. -# -# More details about CircleCi deployment: -# https://circleci.com/docs/configuration#deployment -# -############################################################################################ -# -# Gruntfile.js -# -# module.exports = function release( grunt ) { -# -# grunt.initConfig( { -# -# shell: { -# release: { -# command: function( tag ) { -# return 'sh build.sh ' + tag; -# }, -# options: { -# encoding: 'utf8', -# stderr: true, -# stdout: true -# } -# } -# } -# -# } ); -# -# grunt.registerTask( 'release', 'Run release tasks.', function( tag ) { -# if ( tag == null ) grunt.warn( 'Release tag must be specified, like release:1.0.0' ); -# grunt.task.run( 'shell:release:' + tag ); -# }); -# -# } -# -# -###################################################################################### - -echo " " -echo "Running build script..." -echo "---" - -if [ -z $RELEASE_VERSION ] ; then - - # Try to get Tag version which should be created. - if [ -z $1 ] ; then - echo "Tag version parameter is not passed." - echo "Determine if we have [release:{version}] shortcode to deploy new release" - RELEASE_VERSION="$( git log -1 --pretty=%s | sed -n 's/.*\[release\:\(.*\)\].*/\1/p' )" - else - echo "Tag version parameter is "$1 - RELEASE_VERSION=$1 - fi - -else - - echo "Tag version parameter is "$RELEASE_VERSION - -fi - -echo "---" - -if [ -z $RELEASE_VERSION ] ; then - - echo "No [release:{tag}] shortcode found." - echo "Finish process." - exit 0 - -else - - echo "Determine current branch:" - if [ -z $CIRCLE_BRANCH ]; then - CIRCLE_BRANCH=$(git rev-parse --abbrev-ref HEAD) - fi - echo $CIRCLE_BRANCH - echo "---" - - # Remove temp directory if it already exists to prevent issues before proceed - if [ -d temp-build-$RELEASE_VERSION ]; then - rm -rf temp-build-$RELEASE_VERSION - fi - - echo "Create temp directory" - mkdir temp-build-$RELEASE_VERSION - cd temp-build-$RELEASE_VERSION - - echo "Do production build from scratch to temp directory" - ORIGIN_URL="$( git config --get remote.origin.url )" - git clone $ORIGIN_URL - cd "$( basename `git rev-parse --show-toplevel` )" - # Be sure we are on the same branch - git checkout $CIRCLE_BRANCH - echo "---" - - #echo "Clean up structure ( remove composer relations )" - #rm -rf composer.lock - #rm -rf vendor - - #echo "Running: composer install --no-dev --no-interaction" - #composer install --no-dev --no-interaction --quiet - #echo "---" - - echo "Create local and remote temp branch temp-automatic-branch-"$RELEASE_VERSION - git checkout -b temp-branch-$RELEASE_VERSION - git push origin temp-branch-$RELEASE_VERSION - git branch --set-upstream-to=origin/temp-branch-$RELEASE_VERSION temp-branch-$RELEASE_VERSION - echo "---" - - # It's used only by CircleCi. Should not be called directly. - # - #echo "Set configuration to proceed" - #git config --global push.default simple - #git config --global user.email "$( git log -1 --pretty=%an )" - #git config --global user.name "$( git log -1 --pretty=%ae )" - #echo "---" - - echo "Install Node modules to minify composer.json" - npm install - grunt json-minify - - echo "Be sure we do not add node and other specific files needed only for development" - rm -rf vendor/composer/installers - rm -rf coverage.clover - rm -rf ocular.phar - rm -rf build - rm -rf node_modules - rm -rf composer.lock - rm -rf .scrutinizer.yml - rm -rf circle.yml - rm -rf build.sh - rm -rf gruntfile.js - rm -rf makefile - rm -rf package.json - rm -rf test - rm -rf package-lock.json - echo "Be sure we do not add .git directories" - find ./vendor -name .git -exec rm -rf '{}' \; - echo "Be sure we do not add .svn directories" - find ./vendor -name .svn -exec rm -rf '{}' \; - echo "Git Add" - git add --all - echo "Be sure we added vendor directory" - git add -f vendor - echo "---" - - echo "Now commit our build to remote branch" - git commit -m "[ci skip] Distributive Auto Build" --quiet - git pull - git push --quiet - echo "---" - - echo "Finally, create tag "$RELEASE_VERSION - git tag -a $RELEASE_VERSION -m "v"$RELEASE_VERSION" - Distributive Auto Build" - git push origin $RELEASE_VERSION - echo "---" - - echo "Remove local and remote temp branches, but switch to previous branch before" - git checkout $CIRCLE_BRANCH - git push origin --delete temp-branch-$RELEASE_VERSION - git branch -D temp-branch-$RELEASE_VERSION - echo "---" - - # Remove temp directory. - echo "Remove temp directory" - cd ../.. - rm -rf temp-build-$RELEASE_VERSION - echo "---" - - echo "Done" - -fi diff --git a/changelog.txt b/changelog.txt index b27651c59..502198405 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,4 +1,52 @@ == Changelog == += 4.0.0 = +* NEW - use custom database tables to store GCS file data. This increases plugin performance and will be used for future improvements. +* NEW - added filter `wp_stateless_get_file`, retrieves the GCS file data, should be used instead of getting `sm_cloud` postmeta directly. +* NEW - added filter `wp_stateless_get_file_sizes`, retrieves the GCS file data for image sizes, should be used instead of getting `sm_cloud` postmeta directly. +* NEW - added filter `wp_stateless_get_file_meta`, retrieves all GCS file meta data, should be used instead of getting `sm_cloud` postmeta directly. +* NEW - added filter `wp_stateless_get_file_meta_value`, retrieves the GCS file meta data by meta_key, should be used instead of getting `sm_cloud` postmeta directly. +* NEW - added setting allowing to change email for WP-Stateless notifications. +* NEW - added new Settings tab `Addons`, which contains the list of WP-Stateless Addons, which replace Compatibilities. +* NEW - added new Settings tab `Status`, which contains status and health information related to Google Cloud Storage and WP-Stateless. +* NEW - CLI command `wp stateless migrate` to list and operate data optimizations. +* NEW - configuration constant [`WP_STATELESS_POSTMETA`](https://stateless.udx.io/docs/constants/#wp_stateless_postmeta) allows to read the GCS file data from postmeta instead of the new custom database tables. +* NEW - configuration constant [`WP_STATELESS_BATCH_HEALTHCHECK_INTERVAL`](https://stateless.udx.io/docs/constants/#wp_stateless_batch_healthcheck_interval) defines an interval in minutes for periodical health checks of a batch background process (like data optimization). +* COMPATIBILITY - BuddyBoss Compatibility replaced with [WP-Stateless – BuddyBoss Platform Addon](https://wordpress.org/plugins/wp-stateless-buddyboss-platform-addon/). +* COMPATIBILITY - Elementor Compatibility replaced with [WP-Stateless – Elementor Website Builder Addon](https://wordpress.org/plugins/wp-stateless-elementor-website-builder-addon/). +* COMPATIBILITY - Gravity Form Compatibility does not support older version of Gravity Forms (< 2.3). +* ENHANCEMENT - Allow dismissing notices in Admin Panel only for logged in users. +* ENHANCEMENT - Updated `wp-background-processing` library from from 1.0.2 to 1.1.1. +* ENHANCEMENT - Updated `phpseclib` 3.0.34 to 3.0.37. +* FIX - proper use of infinite timeout in `set_time_limit` function to avoid issues with PHP 8.1 and above [#704](https://github.com/udx/wp-stateless/issues/704). + += 3.4.1 = +* FIX - improve security while processing AJAX requests in Admin Panel + += 3.4.0 = +* ENHANCEMENT - removed `udx/lib-settings` package dependency for security reasons. +* ENHANCEMENT - removed `udx/lib-utility` package dependency for security reasons. +* ENHANCEMENT - refactored `Settings` admin page to remove Angular dependency. +* ENHANCEMENT - including Software Bill of Materials (SBOM) to GitHub release. +* FIX - updated package dependencies for Google Client Library for security reasons. +* FIX - replaced `utf8_encode` with `mb_convert_encoding` to support PHP 8.2 and above [#678](https://github.com/udx/wp-stateless/issues/678). +* FIX - Fatal Error in `Stateless` mode if GCP access credentials are wrong [#693](https://github.com/udx/wp-stateless/issues/693). +* COMPATIBILITY - preventing PHP warnings while working with WooCommerce version 8.4.0 and above [696](https://github.com/udx/wp-stateless/issues/696). +* COMPATIBILITY - avoiding conflicts between builtin compatibilities and WP-Stateless Addon plugins. + += 3.3.0 = +* NEW - Added new filter `wp_stateless_attachment_url`. Allows to customize attachment URL after WP-Stateless generates it based on it's internal conditions. +* FIX - Stateless mode Incompatible with Media Uploader in Media Library Grid mode [#675](https://github.com/udx/wp-stateless/issues/675). +* FIX - Prevent duplicating messages in Admin Panel. +* COMPATIBILITY - Dynamic Image Support is now part of the core. +* COMPATIBILITY - Google App Engine is now part of the core. Automatically enables **Stateless** mode when Google App Engine detected. Can be disabled using `WP_STATELESS_COMPATIBILITY_GAE` constant. +* COMPATIBILITY - Removed compatibility with "Advanced Custom Fields: Image Crop Add-on", because plugin is deprecated. +* COMPATIBILITY - Removed compatibility with "VidoRev" plugin. +* COMPATIBILITY - Removed compatibility with "WP Retina 2x" plugin. +* ENHANCEMENT - Updated Client library for Google APIs from 2.15.0 to 2.15.1. +* ENHANCEMENT - Updated Meta Box library from 5.6.3 to 5.8.2. +* ENHANCEMENT - Updated Meta Box Tabs to version 1.1.17. +* ENHANCEMENT - Updated PHP JWT library from 6.6.0 to 6.9.0. + = 3.2.5 = * FIX - Folder setting does not allow custom structure [#608](https://github.com/udx/wp-stateless/issues/608). * FIX - Stateless mode Incompatible with Inline Uploader [#675](https://github.com/udx/wp-stateless/issues/675). @@ -43,9 +91,9 @@ = 3.1.0 = * NEW - Completely rewritten the synchronization tool. GitHub issue [#523](https://github.com/udx/wp-stateless/issues/523). -* NEW - New configuration constant `WP_STATELESS_SYNC_MAX_BATCH_SIZE`. Sets the maximum size of a background sync batch of items to be saved in a single row in the database. [More details](https://wp-stateless.github.io/docs/constants/#wp_stateless_sync_max_batch_size). -* NEW - New configuration constant `WP_STATELESS_SYNC_LOG`. Sets a path to a log file where to output logging information during the background sync. [More details](https://wp-stateless.github.io/docs/constants/#wp_stateless_sync_log). -* NEW - New configuration constant `WP_STATELESS_SYNC_HEALTHCHECK_INTERVAL`. Defines an interval in minutes for a cron task that periodically checks the health of a particular background sync process. [More details](https://wp-stateless.github.io/docs/constants/#wp_stateless_sync_healthcheck_interval). +* NEW - New configuration constant `WP_STATELESS_SYNC_MAX_BATCH_SIZE`. Sets the maximum size of a background sync batch of items to be saved in a single row in the database. [More details](https://stateless.udx.io/docs/constants/#wp_stateless_sync_max_batch_size). +* NEW - New configuration constant `WP_STATELESS_SYNC_LOG`. Sets a path to a log file where to output logging information during the background sync. [More details](https://stateless.udx.io/docs/constants/#wp_stateless_sync_log). +* NEW - New configuration constant `WP_STATELESS_SYNC_HEALTHCHECK_INTERVAL`. Defines an interval in minutes for a cron task that periodically checks the health of a particular background sync process. [More details](https://stateless.udx.io/docs/constants/#wp_stateless_sync_healthcheck_interval). * FIX - Fixed an issue when original files were not deleted from the server in the Ephemeral mode. GitHub issue [#484](https://github.com/udx/wp-stateless/issues/484). * FIX - Fixed an incorrect behavior of image `srcset` attribute in the Backup mode. GitHub issue [#558](https://github.com/udx/wp-stateless/issues/558). * COMPATIBILITY - Litespeed Cache - Fixed an incorrect upload folder determination. GitHub issue [#527](https://github.com/udx/wp-stateless/issues/527). diff --git a/changes.md b/changes.md index 8f1163fd6..9160496e5 100644 --- a/changes.md +++ b/changes.md @@ -1,3 +1,51 @@ +#### 4.0.0 +* NEW - use custom database tables to store GCS file data. This increases plugin performance and will be used for future improvements. +* NEW - added filter `wp_stateless_get_file`, retrieves the GCS file data, should be used instead of getting `sm_cloud` postmeta directly. +* NEW - added filter `wp_stateless_get_file_sizes`, retrieves the GCS file data for image sizes, should be used instead of getting `sm_cloud` postmeta directly. +* NEW - added filter `wp_stateless_get_file_meta`, retrieves all GCS file meta data, should be used instead of getting `sm_cloud` postmeta directly. +* NEW - added filter `wp_stateless_get_file_meta_value`, retrieves the GCS file meta data by meta_key, should be used instead of getting `sm_cloud` postmeta directly. +* NEW - added setting allowing to change email for WP-Stateless notifications. +* NEW - added new Settings tab `Addons`, which contains the list of WP-Stateless Addons, which replace Compatibilities. +* NEW - added new Settings tab `Status`, which contains status and health information related to Google Cloud Storage and WP-Stateless. +* NEW - CLI command `wp stateless migrate` to list and operate data optimizations. +* NEW - configuration constant [`WP_STATELESS_POSTMETA`](https://stateless.udx.io/docs/constants/#wp_stateless_postmeta) allows to read the GCS file data from postmeta instead of the new custom database tables. +* NEW - configuration constant [`WP_STATELESS_BATCH_HEALTHCHECK_INTERVAL`](https://stateless.udx.io/docs/constants/#wp_stateless_batch_healthcheck_interval) defines an interval in minutes for periodical health checks of a batch background process (like data optimization). +* COMPATIBILITY - BuddyBoss Compatibility replaced with [WP-Stateless – BuddyBoss Platform Addon](https://wordpress.org/plugins/wp-stateless-buddyboss-platform-addon/). +* COMPATIBILITY - Elementor Compatibility replaced with [WP-Stateless – Elementor Website Builder Addon](https://wordpress.org/plugins/wp-stateless-elementor-website-builder-addon/). +* COMPATIBILITY - Gravity Form Compatibility does not support older version of Gravity Forms (< 2.3). +* ENHANCEMENT - Allow dismissing notices in Admin Panel only for logged in users. +* ENHANCEMENT - Updated `wp-background-processing` library from from 1.0.2 to 1.1.1. +* ENHANCEMENT - Updated `phpseclib` 3.0.34 to 3.0.37. +* FIX - proper use of infinite timeout in `set_time_limit` function to avoid issues with PHP 8.1 and above [#704](https://github.com/udx/wp-stateless/issues/704). + +#### 3.4.1 +* FIX - improve security while processing AJAX requests in Admin Panel + +#### 3.4.0 +* ENHANCEMENT - removed `udx/lib-settings` package dependency for security reasons. +* ENHANCEMENT - removed `udx/lib-utility` package dependency for security reasons. +* ENHANCEMENT - refactored `Settings` admin page to remove Angular dependency. +* ENHANCEMENT - including Software Bill of Materials (SBOM) to GitHub release. +* FIX - updated package dependencies for Google Client Library for security reasons. +* FIX - replaced `utf8_encode` with `mb_convert_encoding` to support PHP 8.2 and above [#678](https://github.com/udx/wp-stateless/issues/678). +* FIX - Fatal Error in `Stateless` mode if GCP access credentials are wrong [#693](https://github.com/udx/wp-stateless/issues/693). +* COMPATIBILITY - preventing PHP warnings while working with WooCommerce version 8.4.0 and above [696](https://github.com/udx/wp-stateless/issues/696). +* COMPATIBILITY - avoiding conflicts between builtin compatibilities and WP-Stateless Addon plugins. + +#### 3.3.0 +* NEW - Added new filter `wp_stateless_attachment_url`. Allows to customize attachment URL after WP-Stateless generates it based on it's internal conditions. +* FIX - Stateless mode Incompatible with Media Uploader in Media Library Grid mode [#675](https://github.com/udx/wp-stateless/issues/675). +* FIX - Prevent duplicating messages in Admin Panel. +* COMPATIBILITY - Dynamic Image Support is now part of the core. +* COMPATIBILITY - Google App Engine is now part of the core. Automatically enables **Stateless** mode when Google App Engine detected. Can be disabled using `WP_STATELESS_COMPATIBILITY_GAE` constant. +* COMPATIBILITY - Removed compatibility with "Advanced Custom Fields: Image Crop Add-on", because plugin is deprecated. +* COMPATIBILITY - Removed compatibility with "VidoRev" plugin. +* COMPATIBILITY - Removed compatibility with "WP Retina 2x" plugin. +* ENHANCEMENT - Updated Client library for Google APIs from 2.15.0 to 2.15.1. +* ENHANCEMENT - Updated Meta Box library from 5.6.3 to 5.8.2. +* ENHANCEMENT - Updated Meta Box Tabs to version 1.1.17. +* ENHANCEMENT - Updated PHP JWT library from 6.6.0 to 6.9.0. + #### 3.2.5 * FIX - Folder setting does not allow custom structure [#608](https://github.com/udx/wp-stateless/issues/608). * FIX - Stateless mode Incompatible with Inline Uploader [#675](https://github.com/udx/wp-stateless/issues/675). @@ -49,9 +97,9 @@ #### 3.1.0 - NEW - Completely rewritten the synchronization tool. GitHub issue [#523](https://github.com/udx/wp-stateless/issues/523). -- NEW - New configuration constant `WP_STATELESS_SYNC_MAX_BATCH_SIZE`. Sets the maximum size of a background sync batch of items to be saved in a single row in the database. [More details](https://wp-stateless.github.io/docs/constants/#wp_stateless_sync_max_batch_size). -- NEW - New configuration constant `WP_STATELESS_SYNC_LOG`. Sets a path to a log file where to output logging information during the background sync. [More details](https://wp-stateless.github.io/docs/constants/#wp_stateless_sync_log). -- NEW - New configuration constant `WP_STATELESS_SYNC_HEALTHCHECK_INTERVAL`. Defines an interval in minutes for a cron task that periodically checks the health of a particular background sync process. [More details](https://wp-stateless.github.io/docs/constants/#wp_stateless_sync_healthcheck_interval). +- NEW - New configuration constant `WP_STATELESS_SYNC_MAX_BATCH_SIZE`. Sets the maximum size of a background sync batch of items to be saved in a single row in the database. [More details](https://stateless.udx.io/docs/constants/#wp_stateless_sync_max_batch_size). +- NEW - New configuration constant `WP_STATELESS_SYNC_LOG`. Sets a path to a log file where to output logging information during the background sync. [More details](https://stateless.udx.io/docs/constants/#wp_stateless_sync_log). +- NEW - New configuration constant `WP_STATELESS_SYNC_HEALTHCHECK_INTERVAL`. Defines an interval in minutes for a cron task that periodically checks the health of a particular background sync process. [More details](https://stateless.udx.io/docs/constants/#wp_stateless_sync_healthcheck_interval). - FIX - Fixed an issue when original files were not deleted from the server in the Ephemeral mode. GitHub issue [#484](https://github.com/udx/wp-stateless/issues/484). - FIX - Fixed an incorrect behavior of image `srcset` attribute in the Backup mode. GitHub issue [#558](https://github.com/udx/wp-stateless/issues/558). - COMPATIBILITY - Litespeed Cache - Fixed an incorrect upload folder determination. GitHub issue [#527](https://github.com/udx/wp-stateless/issues/527). diff --git a/composer.json b/composer.json index ce342fe63..06685b617 100644 --- a/composer.json +++ b/composer.json @@ -23,16 +23,16 @@ "require": { "php": ">=5.6.20", "composer/installers": "~1.0", - "udx/lib-settings": "~0.3", - "udx/lib-wp-bootstrap": "~1.3", - "udx/lib-ud-api-client": "~1.2", "ccampbell/chromephp": "^4.1", "firebase/php-jwt": "^6.1.2", - "wpmetabox/meta-box": "5.6.3" + "wpmetabox/meta-box": "^5.6.3", + "udx/lib-ud-api-client": "^1.2", + "udx/lib-wp-bootstrap": "^1.3" }, "autoload": { "classmap": [ - "lib/classes" + "lib/classes", + "lib/includes" ] }, "archive": { @@ -87,10 +87,18 @@ }, "product": false } + }, + "installer-paths": { + "vendor/wpmetabox/meta-box": ["wpmetabox/meta-box"] } }, "require-dev": { "coenjacobs/mozart": "0.7.1", "deliciousbrains/wp-background-processing": "^1.0" + }, + "config": { + "allow-plugins": { + "composer/installers": true + } } } diff --git a/composer.lock b/composer.lock index c94e9e3a9..324e7223f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e12415dd225dd16878a4f85007e8db5e", + "content-hash": "ee72847ceb6d6c1c588115004311ecb7", "packages": [ { "name": "ccampbell/chromephp", @@ -47,6 +47,10 @@ "log", "logging" ], + "support": { + "issues": "https://github.com/ccampbell/chromephp/issues", + "source": "https://github.com/ccampbell/chromephp/tree/4.1.0" + }, "time": "2013-06-26T03:44:33+00:00" }, { @@ -180,6 +184,10 @@ "zend", "zikula" ], + "support": { + "issues": "https://github.com/composer/installers/issues", + "source": "https://github.com/composer/installers/tree/v1.12.0" + }, "funding": [ { "url": "https://packagist.com", @@ -198,16 +206,16 @@ }, { "name": "firebase/php-jwt", - "version": "v6.6.0", + "version": "v6.9.0", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "5a9cf79b4a2eb347230384648cc7b0d68cd97faa" + "reference": "f03270e63eaccf3019ef0f32849c497385774e11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/5a9cf79b4a2eb347230384648cc7b0d68cd97faa", - "reference": "5a9cf79b4a2eb347230384648cc7b0d68cd97faa", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/f03270e63eaccf3019ef0f32849c497385774e11", + "reference": "f03270e63eaccf3019ef0f32849c497385774e11", "shasum": "" }, "require": { @@ -253,87 +261,23 @@ "jwt", "php" ], - "time": "2023-06-13T17:11:06+00:00" - }, - { - "name": "udx/lib-settings", - "version": "0.3.0", - "source": { - "type": "git", - "url": "git@github.com:udx/lib-settings", - "reference": "0.3.0" - }, - "dist": { - "type": "zip", - "url": "https://github.com/udx/lib-settings/archive/0.3.0.zip", - "reference": "0.3.0" - }, - "require": { - "udx/lib-utility": "~0.3" - }, - "require-dev": { - "justinrainbow/json-schema": "1.1.*" + "support": { + "issues": "https://github.com/firebase/php-jwt/issues", + "source": "https://github.com/firebase/php-jwt/tree/v6.9.0" }, - "type": "library", - "extra": { - "component": { - "scripts": [ - "static/scripts/settings.js" - ], - "templates": [ - "static/views/new-installation.xhtml" - ], - "files": [ - "static/schemas/settings.json" - ] - }, - "installer-name": "lib-settings" - }, - "autoload": { - "classmap": [ - "lib" - ] - }, - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Andy Potanin", - "email": "andy.potanin@usabilitydynamics.com", - "homepage": "https://www.usabilitydynamics.com", - "role": "Developer" - }, - { - "name": "Maxim Peshkov", - "email": "maxim.peshkov@usabilitydynamics.com", - "homepage": "https://www.usabilitydynamics.com", - "role": "Developer" - }, - { - "name": "Anton Korotkov", - "email": "anton.korotkov@usabilitydynamics.com", - "homepage": "https://www.usabilitydynamics.com", - "role": "Developer" - } - ], - "homepage": "https://github.com/udx/lib-settings", - "keywords": [ - "settings" - ] + "time": "2023-10-05T00:24:42+00:00" }, { "name": "udx/lib-ud-api-client", - "version": "1.2.1", + "version": "1.2.4", "source": { "type": "git", "url": "git@github.com:udx/lib-ud-api-client", - "reference": "1.2.1" + "reference": "1.2.4" }, "dist": { "type": "zip", - "url": "https://github.com/udx/lib-ud-api-client/archive/1.2.1.zip", - "reference": "1.2.1" + "url": "https://github.com/udx/lib-ud-api-client/archive/1.2.4.zip" }, "require": { "php": ">=5.3" @@ -366,82 +310,20 @@ "wordpress" ] }, - { - "name": "udx/lib-utility", - "version": "0.4.0", - "source": { - "type": "git", - "url": "git@github.com:udx/lib-utility", - "reference": "0.4.0" - }, - "dist": { - "type": "zip", - "url": "https://github.com/udx/lib-utility/archive/0.4.0.zip", - "reference": "0.4.0" - }, - "require-dev": { - "phpunit/phpunit": "4.1.*" - }, - "type": "library", - "extra": { - "installer-name": "lib-utility", - "component": { - "name": "utility", - "scripts": [ - "scripts/*.js" - ] - } - }, - "autoload": { - "classmap": [ - "lib" - ] - }, - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Andy Potanin", - "email": "andy.potanin@usabilitydynamics.com", - "homepage": "https://www.usabilitydynamics.com", - "role": "Developer" - }, - { - "name": "Maxim Peshkov", - "email": "maxim.peshkov@usabilitydynamics.com", - "homepage": "https://www.usabilitydynamics.com", - "role": "Developer" - }, - { - "name": "Anton Korotkov", - "email": "anton.korotkov@usabilitydynamics.com", - "homepage": "https://www.usabilitydynamics.com", - "role": "Developer" - } - ], - "keywords": [ - "job", - "process", - "utility" - ] - }, { "name": "udx/lib-wp-bootstrap", - "version": "1.3.0", + "version": "1.3.3", "source": { "type": "git", "url": "git@github.com:udx/lib-wp-bootstrap", - "reference": "1.3.0" + "reference": "1.3.3" }, "dist": { "type": "zip", - "url": "https://github.com/udx/lib-wp-bootstrap/archive/1.3.0.zip", - "reference": "1.3.0" + "url": "https://github.com/udx/lib-wp-bootstrap/archive/1.3.3.zip" }, "require": { - "php": ">=5.3", - "udx/lib-utility": "~0.3" + "php": ">=5.3" }, "type": "library", "extra": { @@ -463,19 +345,24 @@ }, { "name": "wpmetabox/meta-box", - "version": "5.6.3", + "version": "5.8.2", "source": { "type": "git", "url": "https://github.com/wpmetabox/meta-box.git", - "reference": "c2c4a30ed70163dfdfe93f2865e88a7a45c46856" + "reference": "de583a74171bdee1b5213232a5bf50f82c6fee14" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wpmetabox/meta-box/zipball/c2c4a30ed70163dfdfe93f2865e88a7a45c46856", - "reference": "c2c4a30ed70163dfdfe93f2865e88a7a45c46856", + "url": "https://api.github.com/repos/wpmetabox/meta-box/zipball/de583a74171bdee1b5213232a5bf50f82c6fee14", + "reference": "de583a74171bdee1b5213232a5bf50f82c6fee14", "shasum": "" }, "type": "wordpress-plugin", + "autoload": { + "psr-4": { + "MetaBox\\": "src/" + } + }, "notification-url": "https://packagist.org/downloads/", "license": [ "GPL-2.0" @@ -499,7 +386,11 @@ "wordpress-plugin", "wp-admin" ], - "time": "2022-04-18T03:20:58+00:00" + "support": { + "issues": "https://github.com/wpmetabox/meta-box/issues", + "source": "https://github.com/wpmetabox/meta-box/tree/5.8.2" + }, + "time": "2023-10-13T13:53:33+00:00" } ], "packages-dev": [ @@ -549,6 +440,10 @@ } ], "description": "Composes all dependencies as a package inside a WordPress plugin", + "support": { + "issues": "https://github.com/coenjacobs/mozart/issues", + "source": "https://github.com/coenjacobs/mozart/tree/0.7.1" + }, "funding": [ { "url": "https://github.com/coenjacobs", @@ -559,16 +454,16 @@ }, { "name": "deliciousbrains/wp-background-processing", - "version": "1.1.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/deliciousbrains/wp-background-processing.git", - "reference": "d5ef95cecba7f792ddca3e3bd70ebfb90dc4996d" + "reference": "ebbed762c42e70e76573ffbd36e591378ba5f2ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/deliciousbrains/wp-background-processing/zipball/d5ef95cecba7f792ddca3e3bd70ebfb90dc4996d", - "reference": "d5ef95cecba7f792ddca3e3bd70ebfb90dc4996d", + "url": "https://api.github.com/repos/deliciousbrains/wp-background-processing/zipball/ebbed762c42e70e76573ffbd36e591378ba5f2ee", + "reference": "ebbed762c42e70e76573ffbd36e591378ba5f2ee", "shasum": "" }, "require": { @@ -601,7 +496,11 @@ } ], "description": "WP Background Processing can be used to fire off non-blocking asynchronous requests or as a background processing tool, allowing you to queue tasks.", - "time": "2023-04-18T12:32:25+00:00" + "support": { + "issues": "https://github.com/deliciousbrains/wp-background-processing/issues", + "source": "https://github.com/deliciousbrains/wp-background-processing/tree/1.1.1" + }, + "time": "2023-07-18T10:22:06+00:00" }, { "name": "league/flysystem", @@ -685,6 +584,10 @@ "sftp", "storage" ], + "support": { + "issues": "https://github.com/thephpleague/flysystem/issues", + "source": "https://github.com/thephpleague/flysystem/tree/1.1.10" + }, "funding": [ { "url": "https://offset.earth/frankdejonge", @@ -695,26 +598,26 @@ }, { "name": "league/mime-type-detection", - "version": "1.11.0", + "version": "1.14.0", "source": { "type": "git", "url": "https://github.com/thephpleague/mime-type-detection.git", - "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd" + "reference": "b6a5854368533df0295c5761a0253656a2e52d9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ff6248ea87a9f116e78edd6002e39e5128a0d4dd", - "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/b6a5854368533df0295c5761a0253656a2e52d9e", + "reference": "b6a5854368533df0295c5761a0253656a2e52d9e", "shasum": "" }, "require": { "ext-fileinfo": "*", - "php": "^7.2 || ^8.0" + "php": "^7.4 || ^8.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.2", "phpstan/phpstan": "^0.12.68", - "phpunit/phpunit": "^8.5.8 || ^9.3" + "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0" }, "type": "library", "autoload": { @@ -733,6 +636,10 @@ } ], "description": "Mime-type detection for Flysystem", + "support": { + "issues": "https://github.com/thephpleague/mime-type-detection/issues", + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.14.0" + }, "funding": [ { "url": "https://github.com/frankdejonge", @@ -743,7 +650,7 @@ "type": "tidelift" } ], - "time": "2022-04-17T13:12:02+00:00" + "time": "2023-10-17T14:13:20+00:00" }, { "name": "psr/container", @@ -792,20 +699,24 @@ "container-interop", "psr" ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, "time": "2021-11-05T16:47:00+00:00" }, { "name": "symfony/console", - "version": "v5.4.24", + "version": "v5.4.31", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "560fc3ed7a43e6d30ea94a07d77f9a60b8ed0fb8" + "reference": "11ac5f154e0e5c4c77af83ad11ead9165280b92a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/560fc3ed7a43e6d30ea94a07d77f9a60b8ed0fb8", - "reference": "560fc3ed7a43e6d30ea94a07d77f9a60b8ed0fb8", + "url": "https://api.github.com/repos/symfony/console/zipball/11ac5f154e0e5c4c77af83ad11ead9165280b92a", + "reference": "11ac5f154e0e5c4c77af83ad11ead9165280b92a", "shasum": "" }, "require": { @@ -874,6 +785,9 @@ "console", "terminal" ], + "support": { + "source": "https://github.com/symfony/console/tree/v5.4.31" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -888,29 +802,29 @@ "type": "tidelift" } ], - "time": "2023-05-26T05:13:16+00:00" + "time": "2023-10-31T07:58:33+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.3.0", + "version": "v3.0.2", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.0.2" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", @@ -938,6 +852,9 @@ ], "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.2" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -952,20 +869,20 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2022-01-02T09:55:41+00:00" }, { "name": "symfony/finder", - "version": "v5.4.21", + "version": "v5.4.27", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "078e9a5e1871fcfe6a5ce421b539344c21afef19" + "reference": "ff4bce3c33451e7ec778070e45bd23f74214cd5d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/078e9a5e1871fcfe6a5ce421b539344c21afef19", - "reference": "078e9a5e1871fcfe6a5ce421b539344c21afef19", + "url": "https://api.github.com/repos/symfony/finder/zipball/ff4bce3c33451e7ec778070e45bd23f74214cd5d", + "reference": "ff4bce3c33451e7ec778070e45bd23f74214cd5d", "shasum": "" }, "require": { @@ -998,6 +915,9 @@ ], "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v5.4.27" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1012,20 +932,20 @@ "type": "tidelift" } ], - "time": "2023-02-16T09:33:00+00:00" + "time": "2023-07-31T08:02:31+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", "shasum": "" }, "require": { @@ -1040,7 +960,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1077,6 +997,9 @@ "polyfill", "portable" ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1091,20 +1014,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354" + "reference": "875e90aeea2777b6f135677f618529449334a612" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612", + "reference": "875e90aeea2777b6f135677f618529449334a612", "shasum": "" }, "require": { @@ -1116,7 +1039,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1155,6 +1078,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1169,20 +1095,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" }, "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/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", "shasum": "" }, "require": { @@ -1194,7 +1120,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1236,6 +1162,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1250,20 +1179,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + "reference": "42292d99c55abe617799667f454222c54c60e229" }, "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/42292d99c55abe617799667f454222c54c60e229", + "reference": "42292d99c55abe617799667f454222c54c60e229", "shasum": "" }, "require": { @@ -1278,7 +1207,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1316,6 +1245,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1330,20 +1262,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-07-28T09:04:16+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9" + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/9e8ecb5f92152187c4799efd3c96b78ccab18ff9", - "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fe2f306d1d9d346a7fee353d0d5012e401e984b5", + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5", "shasum": "" }, "require": { @@ -1352,7 +1284,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1392,6 +1324,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.28.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1406,20 +1341,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", "shasum": "" }, "require": { @@ -1428,7 +1363,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1472,6 +1407,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1486,33 +1424,36 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.3.0", + "version": "v3.0.2", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4" + "reference": "d78d39c1599bd1188b8e26bb341da52c3c6d8a66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", - "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d78d39c1599bd1188b8e26bb341da52c3c6d8a66", + "reference": "d78d39c1599bd1188b8e26bb341da52c3c6d8a66", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.0.2", "psr/container": "^2.0" }, "conflict": { "ext-psr": "<1.1|>=2" }, + "suggest": { + "symfony/service-implementation": "" + }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", @@ -1522,10 +1463,7 @@ "autoload": { "psr-4": { "Symfony\\Contracts\\Service\\": "" - }, - "exclude-from-classmap": [ - "/Test/" - ] + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1551,6 +1489,9 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.0.2" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1565,37 +1506,36 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2022-05-30T19:17:58+00:00" }, { "name": "symfony/string", - "version": "v6.3.0", + "version": "v6.0.19", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "f2e190ee75ff0f5eced645ec0be5c66fac81f51f" + "reference": "d9e72497367c23e08bf94176d2be45b00a9d232a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/f2e190ee75ff0f5eced645ec0be5c66fac81f51f", - "reference": "f2e190ee75ff0f5eced645ec0be5c66fac81f51f", + "url": "https://api.github.com/repos/symfony/string/zipball/d9e72497367c23e08bf94176d2be45b00a9d232a", + "reference": "d9e72497367c23e08bf94176d2be45b00a9d232a", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.0.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/translation-contracts": "<2.5" + "symfony/translation-contracts": "<2.0" }, "require-dev": { "symfony/error-handler": "^5.4|^6.0", "symfony/http-client": "^5.4|^6.0", - "symfony/intl": "^6.2", - "symfony/translation-contracts": "^2.5|^3.0", + "symfony/translation-contracts": "^2.0|^3.0", "symfony/var-exporter": "^5.4|^6.0" }, "type": "library", @@ -1634,6 +1574,9 @@ "utf-8", "utf8" ], + "support": { + "source": "https://github.com/symfony/string/tree/v6.0.19" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1648,7 +1591,7 @@ "type": "tidelift" } ], - "time": "2023-03-21T21:06:29+00:00" + "time": "2023-01-01T08:36:10+00:00" } ], "aliases": [], @@ -1660,5 +1603,5 @@ "php": ">=5.6.20" }, "platform-dev": [], - "plugin-api-version": "1.1.0" + "plugin-api-version": "2.6.0" } diff --git a/l10n.php b/l10n.php index be71628ba..eafa634a4 100644 --- a/l10n.php +++ b/l10n.php @@ -84,6 +84,8 @@ 'get_non_images_media_id_request_failed' => __('Get non Images Media ID: Request failed', ud_get_stateless_media()->domain ), 'regenerate_single_image_request_failed' => __('Regenerate single image: Request failed', ud_get_stateless_media()->domain ), - + + 'confirm' => __('Confirm', ud_get_stateless_media()->domain ), + 'cancel' => __('Cancel', ud_get_stateless_media()->domain ), ); diff --git a/lib/Google/CHANGELOG.md b/lib/Google/CHANGELOG.md index 79305bb5a..b6d29393c 100644 --- a/lib/Google/CHANGELOG.md +++ b/lib/Google/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.15.1](https://github.com/googleapis/google-api-php-client/compare/v2.15.0...v2.15.1) (2023-09-12) + + +### Bug Fixes + +* Upgrade min phpseclib version ([#2499](https://github.com/googleapis/google-api-php-client/issues/2499)) ([8e7fae2](https://github.com/googleapis/google-api-php-client/commit/8e7fae2b79cfc1b72026347abf6314d91442a018)) + ## [2.15.0](https://github.com/googleapis/google-api-php-client/compare/v2.14.0...v2.15.0) (2023-05-18) diff --git a/lib/Google/CODE_OF_CONDUCT.md b/lib/Google/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..46b2a08ea --- /dev/null +++ b/lib/Google/CODE_OF_CONDUCT.md @@ -0,0 +1,43 @@ +# Contributor Code of Conduct + +As contributors and maintainers of this project, +and in the interest of fostering an open and welcoming community, +we pledge to respect all people who contribute through reporting issues, +posting feature requests, updating documentation, +submitting pull requests or patches, and other activities. + +We are committed to making participation in this project +a harassment-free experience for everyone, +regardless of level of experience, gender, gender identity and expression, +sexual orientation, disability, personal appearance, +body size, race, ethnicity, age, religion, or nationality. + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery +* Personal attacks +* Trolling or insulting/derogatory comments +* Public or private harassment +* Publishing other's private information, +such as physical or electronic +addresses, without explicit permission +* Other unethical or unprofessional conduct. + +Project maintainers have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct. +By adopting this Code of Conduct, +project maintainers commit themselves to fairly and consistently +applying these principles to every aspect of managing this project. +Project maintainers who do not follow or enforce the Code of Conduct +may be permanently removed from the project team. + +This code of conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior +may be reported by opening an issue +or contacting one or more of the project maintainers. + +This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, +available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) diff --git a/lib/Google/README.md b/lib/Google/README.md index 1beb6c88d..b82f44f14 100644 --- a/lib/Google/README.md +++ b/lib/Google/README.md @@ -44,7 +44,7 @@ composer installed. Once composer is installed, execute the following command in your project root to install this library: ```sh -composer require google/apiclient:^2.12.1 +composer require google/apiclient:^2.15.0 ``` Finally, be sure to include the autoloader: @@ -65,7 +65,7 @@ you want to keep in `composer.json`: ```json { "require": { - "google/apiclient": "^2.12.1" + "google/apiclient": "^2.15.0" }, "scripts": { "pre-autoload-dump": "Google\\Task\\Composer::cleanup" @@ -245,9 +245,10 @@ The classes used to call the API in [google-api-php-client-services](https://git A JSON request to the [Datastore API](https://developers.google.com/apis-explorer/#p/datastore/v1beta3/datastore.projects.runQuery) would look like this: -```json +``` POST https://datastore.googleapis.com/v1beta3/projects/YOUR_PROJECT_ID:runQuery?key=YOUR_API_KEY - +``` +```json { "query": { "kind": [{ diff --git a/lib/Google/UPGRADING.md b/lib/Google/UPGRADING.md new file mode 100644 index 000000000..ef939e943 --- /dev/null +++ b/lib/Google/UPGRADING.md @@ -0,0 +1,377 @@ +Google API Client Upgrade Guide +=============================== + +2.x to 2.10.0 +------------- + +### Namespaces + +The Google API Client for PHP now uses namespaces for all classes. Code using +the legacy classnames will continue to work, but it is advised to upgrade to the +underspaced names, as the legacy classnames will be deprecated some time in the +future. + +**Before** + +```php +$client = new Google_Client(); +$service = new Google_Service_Books($client); +``` + +**After** +```php +$client = new Google\Client(); +$service = new Google\Service\Books($client); +``` + +### Service class constructors + +Service class constructors now accept an optional `Google\Client|array` parameter +as their first argument, rather than requiring an instance of `Google\Client`. + +**Before** + +```php +$client = new Google_Client(); +$client->setApplicationName("Client_Library_Examples"); +$client->setDeveloperKey("YOUR_APP_KEY"); + +$service = new Google_Service_Books($client); +``` + +**After** + +```php +$service = new Google\Service\Books([ + 'application_name' => "Client_Library_Examples", + 'developer_key' => "YOUR_APP_KEY", +]); +``` + +1.0 to 2.0 +---------- + +The Google API Client for PHP has undergone major internal changes in `2.0`. Please read through +the list below in order to upgrade to the latest version: + +## Installation now uses `Composer` + +**Before** + +The project was cloned in your project and you would run the autoloader from wherever: + +```php +// the autoload file was included +require_once 'google-api-php-client/src/Google/autoload.php'; // or wherever autoload.php is located +// OR classes were added one-by-one +require_once 'Google/Client.php'; +require_once 'Google/Service/YouTube.php'; +``` + +**After** + +This library now uses [composer](https://getcomposer.org) (We suggest installing +composer [globally](http://symfony.com/doc/current/cookbook/composer.html)). Add this library by +running the following in the root of your project: + +``` +$ composer require google/apiclient:~2.0 +``` + +This will install this library and generate an autoload file in `vendor/autoload.php` in the root +of your project. You can now include this library with the following code: + +```php +require_once 'vendor/autoload.php'; +``` + +## Access Tokens are passed around as arrays instead of JSON strings + +**Before** + +```php +$accessToken = $client->getAccessToken(); +print_r($accessToken); +// would output: +// string(153) "{"access_token":"ya29.FAKsaByOPoddfzvKRo_LBpWWCpVTiAm4BjsvBwxtN7IgSNoUfcErBk_VPl4iAiE1ntb_","token_type":"Bearer","expires_in":3593,"created":1445548590}" +file_put_contents($credentialsPath, $accessToken); +``` + +**After** + +```php +$accessToken = $client->getAccessToken(); +print_r($accessToken); +// will output: +// array(4) { +// ["access_token"]=> +// string(73) "ya29.FAKsaByOPoddfzvKRo_LBpWWCpVTiAm4BjsvBwxtN7IgSNoUfcErBk_VPl4iAiE1ntb_" +// ["token_type"]=> +// string(6) "Bearer" +// ["expires_in"]=> +// int(3593) +// ["created"]=> +// int(1445548590) +// } +file_put_contents($credentialsPath, json_encode($accessToken)); +``` + +## ID Token data is returned as an array + +**Before** + +```php +$ticket = $client->verifyIdToken($idToken); +$data = $ticket->getAttributes(); +$userId = $data['payload']['sub']; +``` + +**After** + +```php +$userData = $client->verifyIdToken($idToken); +$userId = $userData['sub']; +``` + +## `Google_Auth_AssertionCredentials` has been removed + +For service accounts, we now use `setAuthConfig` or `useApplicationDefaultCredentials` + +**Before** + +```php +$client_email = '1234567890-a1b2c3d4e5f6g7h8i@developer.gserviceaccount.com'; +$private_key = file_get_contents('MyProject.p12'); +$scopes = array('https://www.googleapis.com/auth/sqlservice.admin'); +$credentials = new Google_Auth_AssertionCredentials( + $client_email, + $scopes, + $private_key +); +``` + +**After** + +```php +$client->setAuthConfig('/path/to/service-account.json'); + +// OR use environment variables (recommended) + +putenv('GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json'); +$client->useApplicationDefaultCredentials(); +``` + +> Note: P12s are deprecated in favor of service account JSON, which can be generated in the +> Credentials section of Google Developer Console. + +In order to impersonate a user, call `setSubject` when your service account +credentials are being used. + +**Before** + +```php +$user_to_impersonate = 'user@example.org'; +$credentials = new Google_Auth_AssertionCredentials( + $client_email, + $scopes, + $private_key, + 'notasecret', // Default P12 password + 'http://oauth.net/grant_type/jwt/1.0/bearer', // Default grant type + $user_to_impersonate, +); +``` + +**After** + +```php +$user_to_impersonate = 'user@example.org'; +$client->setSubject($user_to_impersonate); +``` + +Additionally, `Google_Client::loadServiceAccountJson` has been removed in favor +of `Google_Client::setAuthConfig`: + +**Before** + +```php +$scopes = [ Google_Service_Books::BOOKS ]; +$client->loadServiceAccountJson('/path/to/service-account.json', $scopes); +``` + +**After** + +```php +$scopes = [ Google_Service_Books::BOOKS ]; +$client->setAuthConfig('/path/to/service-account.json'); +$client->setScopes($scopes); +``` + +## `Google_Auth_AppIdentity` has been removed + +For App Engine authentication, we now use the underlying [`google/auth`][Google Auth] and +call `useApplicationDefaultCredentials`: + +**Before** + +```php +$client->setAuth(new Google_Auth_AppIdentity($client)); +$client->getAuth() + ->authenticateForScope('https://www.googleapis.com/auth/sqlservice.admin') +``` + +**After** + +```php +$client->useApplicationDefaultCredentials(); +$client->addScope('https://www.googleapis.com/auth/sqlservice.admin'); +``` + +This will detect when the App Engine environment is present, and use the appropriate credentials. + +## `Google_Auth_Abstract` classes have been removed + +[`google/auth`][Google Auth] is now used for authentication. As a result, all +`Google_Auth`-related functionality has been removed. The methods that were a part of +`Google_Auth_Abstract` have been moved into the `Google_Client` object. + +**Before** + +```php +$request = new Google_Http_Request(); +$client->getAuth()->sign($request); +``` + +**After** + +```php +// create an authorized HTTP client +$httpClient = $client->authorize(); + +// OR add authorization to an existing client +$httpClient = new GuzzleHttp\Client(); +$httpClient = $client->authorize($httpClient); +``` + +**Before** + +```php +$request = new Google_Http_Request(); +$response = $client->getAuth()->authenticatedRequest($request); +``` + +**After** + +```php +$httpClient = $client->authorize(); +$request = new GuzzleHttp\Psr7\Request('POST', $url); +$response = $httpClient->send($request); +``` + +> NOTE: `$request` can be any class implementing +> `Psr\Http\Message\RequestInterface` + +In addition, other methods that were callable on `Google_Auth_OAuth2` are now called +on the `Google_Client` object: + +**Before** + +```php +$client->getAuth()->refreshToken($token); +$client->getAuth()->refreshTokenWithAssertion(); +$client->getAuth()->revokeToken($token); +$client->getAuth()->isAccessTokenExpired(); +``` + +**After** + +```php +$client->refreshToken($token); +$client->refreshTokenWithAssertion(); +$client->revokeToken($token); +$client->isAccessTokenExpired(); +``` + +## PHP 5.6 is now the minimum supported PHP version + +This was previously `PHP 5.2`. If you still need to use PHP 5.2, please continue to use +the [v1-master](https://github.com/google/google-api-php-client/tree/v1-master) branch. + +## Guzzle and PSR-7 are used for HTTP Requests + +The HTTP library Guzzle is used for all HTTP Requests. By default, [`Guzzle 6`][Guzzle 6] +is used, but this library is also compatible with [`Guzzle 5`][Guzzle 5]. As a result, +all `Google_IO`-related functionality and `Google_Http`-related functionality has been +changed or removed. + +1. Removed `Google_Http_Request` +1. Removed `Google_IO_Abstract`, `Google_IO_Exception`, `Google_IO_Curl`, and `Google_IO_Stream` +1. Removed methods `Google_Client::getIo` and `Google_Client::setIo` +1. Refactored `Google_Http_Batch` and `Google_Http_MediaFileUpload` for Guzzle +1. Added `Google_Client::getHttpClient` and `Google_Client::setHttpClient` for getting and +setting the Guzzle `GuzzleHttp\ClientInterface` object. + +> NOTE: `PSR-7`-compatible libraries can now be used with this library. + +## Other Changes + + - [`PSR 3`][PSR 3] `LoggerInterface` is now supported, and [Monolog][Monolog] is used for all + logging. As a result, all `Google_Logger`-related functionality has been removed: + 1. Removed `Google_Logger_Abstract`, `Google_Logger_Exception`, `Google_Logger_File`, + `Google_Logger_Null`, and `Google_Logger_Psr` + 1. `Google_Client::setLogger` now requires `Psr\Log\LoggerInterface` + - [`firebase/jwt`][Firebase JWT] is now used for all JWT signing and verifying. As a result, the + following classes have been changed or removed: + 1. Removed `Google_Signer_P12` + 1. Removed `Google_Verifier_Pem` + 1. Removed `Google_Auth_LoginTicket` (see below) + - The following classes and methods have been removed in favor of [`google/auth`][Google Auth]: + 1. Removed methods `Google_Client::getAuth` and `Google_Client::setAuth` + 1. Removed `Google_Auth_Abstract` + - `Google_Auth_Abstract::sign` and `Google_Auth_Abstract::authenticatedRequest` have been + replaced by `Google_Client::authorize`. See the above examples for more details. + 1. Removed `Google_Auth_AppIdentity`. This is now supported in [`google/auth`][Google Auth AppIdentity] + and is used automatically when `Google_Client::useApplicationDefaultCredentials` is called. + 1. Removed `Google_Auth_AssertionCredentials`. Use `Google_Client::setAuthConfig` instead. + 1. Removed `Google_Auth_ComputeEngine`. This is now supported in + [`google/auth`][Google Auth GCE], and is used automatically when + `Google_Client::useApplicationDefaultCredentials` is called. + 1. Removed `Google_Auth_Exception` + 1. Removed `Google_Auth_LoginTicket`. Calls to `Google_Client::verifyIdToken` now returns + the payload of the ID Token as an array if the verification is successful. + 1. Removed `Google_Auth_OAuth2`. This functionality is now supported in [`google/auth`][Google Auth OAuth2] and wrapped in `Google_Client`. These changes will only affect applications calling `Google_Client::getAuth`, + as the methods on `Google_Client` have not changed. + 1. Removed `Google_Auth_Simple`. This is now supported in [`google/auth`][Google Auth Simple] + and is used automatically when `Google_Client::setDeveloperKey` is called. + - `Google_Client::sign` has been replaced by `Google_Client::authorize`. This function + now takes a `GuzzleHttp\ClientInterface` object and uses the following decision tree for + authentication: + 1. Uses Application Default Credentials when + `Google_Client::useApplicationDefaultCredentials` is called + - Looks for `GOOGLE_APPLICATION_CREDENTIALS` environment variable if set + - Looks in `~/.config/gcloud/application_default_credentials.json` + - Otherwise, uses `GCECredentials` + 1. Uses API Key if set (see `Client::setDeveloperKey`) + 1. Uses Access Token if set (call `Client::setAccessToken`) + 1. Automatically refreshes access tokens if one is set and the access token is expired + - Removed `Google_Config` + - Removed `Google_Utils` + - [`PSR-6`][PSR 6] cache is used for all caching. As a result: + 1. Removed `Google_Cache_Abstract` + 1. Classes `Google_Cache_Apc`, `Google_Cache_File`, `Google_Cache_Memcache`, and + `Google_Cache_Null` now implement `Google\Auth\CacheInterface`. + 1. Google Auth provides simple [caching utilities][Google Auth Cache] which + are used by default unless you provide alternatives. + - Removed `$boundary` constructor argument for `Google_Http_MediaFileUpload` + +[PSR 3]: https://www.php-fig.org/psr/psr-3/ +[PSR 6]: https://www.php-fig.org/psr/psr-6/ +[Guzzle 5]: https://github.com/guzzle/guzzle +[Guzzle 6]: http://docs.guzzlephp.org/en/latest/psr7.html +[Monolog]: https://github.com/Seldaek/monolog +[Google Auth]: https://github.com/google/google-auth-library-php +[Google Auth Cache]: https://github.com/googleapis/google-auth-library-php/tree/master/src/Cache +[Google Auth GCE]: https://github.com/google/google-auth-library-php/blob/master/src/GCECredentials.php +[Google Auth OAuth2]: https://github.com/google/google-auth-library-php/blob/master/src/OAuth2.php +[Google Auth Simple]: https://github.com/google/google-auth-library-php/blob/master/src/Simple.php +[Google Auth AppIdentity]: https://github.com/google/google-auth-library-php/blob/master/src/AppIdentityCredentials.php +[Firebase JWT]: https://github.com/firebase/php-jwt diff --git a/lib/Google/composer.json b/lib/Google/composer.json index 461fdaae7..c646bcd68 100644 --- a/lib/Google/composer.json +++ b/lib/Google/composer.json @@ -8,23 +8,24 @@ "require": { "php": "^7.4|^8.0", "google/auth": "^1.28", - "google/cloud-core": "^1.51.2", - "google/cloud-storage": "^1.31.2", "firebase/php-jwt": "~6.0", "monolog/monolog": "^2.9||^3.0", - "phpseclib/phpseclib": "^3.0.2", + "phpseclib/phpseclib": "^3.0.19", "guzzlehttp/guzzle": "~6.5||~7.0", - "guzzlehttp/psr7": "^1.8.4||^2.2.1" + "guzzlehttp/psr7": "^1.8.4||^2.2.1", + "google/cloud-storage": "^1.34", + "google/cloud-core": "^1.52", + "google/apiclient-services": "^0.323.0" }, "require-dev": { "squizlabs/php_codesniffer": "^3.0", "symfony/dom-crawler": "~2.1", "symfony/css-selector": "~2.1", - "cache/filesystem-adapter": "^1.1", "phpcompatibility/php-compatibility": "^9.2", "composer/composer": "^1.10.22", "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.5" + "phpunit/phpunit": "^9.5", + "cache/filesystem-adapter": "^1.2" }, "suggest": { "cache/filesystem-adapter": "For caching certs and tokens (using Google\\Client::setCache)" @@ -40,7 +41,13 @@ "src/aliases.php" ] }, + "scripts": { + "pre-autoload-dump": "Google\\Task\\Composer::cleanup" + }, "extra": { + "google/apiclient-services": [ + "Storage" + ], "branch-alias": { "dev-main": "2.x-dev" } diff --git a/lib/Google/composer.lock b/lib/Google/composer.lock index c80636154..351a8bea8 100644 --- a/lib/Google/composer.lock +++ b/lib/Google/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d23c27e8eca497813f44feccf80aae06", + "content-hash": "a24978434a3e0a329346faa11f43a9d9", "packages": [ { "name": "brick/math", @@ -49,6 +49,10 @@ "brick", "math" ], + "support": { + "issues": "https://github.com/brick/math/issues", + "source": "https://github.com/brick/math/tree/0.11.0" + }, "funding": [ { "url": "https://github.com/BenMorel", @@ -59,16 +63,16 @@ }, { "name": "firebase/php-jwt", - "version": "v6.5.0", + "version": "v6.10.0", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "e94e7353302b0c11ec3cfff7180cd0b1743975d2" + "reference": "a49db6f0a5033aef5143295342f1c95521b075ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/e94e7353302b0c11ec3cfff7180cd0b1743975d2", - "reference": "e94e7353302b0c11ec3cfff7180cd0b1743975d2", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/a49db6f0a5033aef5143295342f1c95521b075ff", + "reference": "a49db6f0a5033aef5143295342f1c95521b075ff", "shasum": "" }, "require": { @@ -114,20 +118,68 @@ "jwt", "php" ], - "time": "2023-05-12T15:47:07+00:00" + "support": { + "issues": "https://github.com/firebase/php-jwt/issues", + "source": "https://github.com/firebase/php-jwt/tree/v6.10.0" + }, + "time": "2023-12-01T16:26:39+00:00" + }, + { + "name": "google/apiclient-services", + "version": "v0.323.0", + "source": { + "type": "git", + "url": "https://github.com/googleapis/google-api-php-client-services.git", + "reference": "d5497d30ddfafe7592102ca48bedaf222a4ca7a6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/d5497d30ddfafe7592102ca48bedaf222a4ca7a6", + "reference": "d5497d30ddfafe7592102ca48bedaf222a4ca7a6", + "shasum": "" + }, + "require": { + "php": "^7.4||^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7||^8.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "autoload.php" + ], + "psr-4": { + "Google\\Service\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "Client library for Google APIs", + "homepage": "http://developers.google.com/api-client-library/php", + "keywords": [ + "google" + ], + "support": { + "issues": "https://github.com/googleapis/google-api-php-client-services/issues", + "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.323.0" + }, + "time": "2023-11-06T01:08:38+00:00" }, { "name": "google/auth", - "version": "v1.28.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-auth-library-php.git", - "reference": "07f7f6305f1b7df32b2acf6e101c1225c839c7ac" + "reference": "682dc6c30bb509953c9e43bb0960d901582da00b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/07f7f6305f1b7df32b2acf6e101c1225c839c7ac", - "reference": "07f7f6305f1b7df32b2acf6e101c1225c839c7ac", + "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/682dc6c30bb509953c9e43bb0960d901582da00b", + "reference": "682dc6c30bb509953c9e43bb0960d901582da00b", "shasum": "" }, "require": { @@ -139,8 +191,8 @@ "psr/http-message": "^1.1||^2.0" }, "require-dev": { - "guzzlehttp/promises": "^1.3", - "kelvinmo/simplejwt": "0.7.0", + "guzzlehttp/promises": "^2.0", + "kelvinmo/simplejwt": "0.7.1", "phpseclib/phpseclib": "^3.0", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.0.0", @@ -167,36 +219,41 @@ "google", "oauth2" ], - "time": "2023-05-11T21:58:18+00:00" + "support": { + "docs": "https://googleapis.github.io/google-auth-library-php/main/", + "issues": "https://github.com/googleapis/google-auth-library-php/issues", + "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.33.0" + }, + "time": "2023-11-30T15:49:27+00:00" }, { "name": "google/cloud-core", - "version": "v1.51.2", + "version": "v1.52.10", "source": { "type": "git", "url": "https://github.com/googleapis/google-cloud-php-core.git", - "reference": "85dc48d62143f4bbfaa34c24da95003371de7b79" + "reference": "5e34556498ecadee2161402fd1024bec7ce33186" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-cloud-php-core/zipball/85dc48d62143f4bbfaa34c24da95003371de7b79", - "reference": "85dc48d62143f4bbfaa34c24da95003371de7b79", + "url": "https://api.github.com/repos/googleapis/google-cloud-php-core/zipball/5e34556498ecadee2161402fd1024bec7ce33186", + "reference": "5e34556498ecadee2161402fd1024bec7ce33186", "shasum": "" }, "require": { "google/auth": "^1.18", - "guzzlehttp/guzzle": "^5.3|^6.5.7|^7.4.4", - "guzzlehttp/promises": "^1.3", + "guzzlehttp/guzzle": "^6.5.8|^7.4.4", + "guzzlehttp/promises": "^1.4||^2.0", "guzzlehttp/psr7": "^1.7|^2.0", "monolog/monolog": "^1.1|^2.0|^3.0", "php": ">=7.4", - "psr/http-message": "^1.0", + "psr/http-message": "^1.0|^2.0", "rize/uri-template": "~0.3" }, "require-dev": { "erusev/parsedown": "^1.6", "google/cloud-common-protos": "^0.4", - "google/gax": "^1.9", + "google/gax": "^1.24.0", "opis/closure": "^3", "phpdocumentor/reflection": "^5.0", "phpspec/prophecy-phpunit": "^2.0", @@ -229,25 +286,27 @@ "Apache-2.0" ], "description": "Google Cloud PHP shared dependency, providing functionality useful to all components.", - "time": "2023-05-05T23:01:42+00:00" + "support": { + "source": "https://github.com/googleapis/google-cloud-php-core/tree/v1.52.10" + }, + "time": "2023-12-08T22:36:35+00:00" }, { "name": "google/cloud-storage", - "version": "v1.31.2", + "version": "v1.36.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-cloud-php-storage.git", - "reference": "7fe96d56856cda550b21779bb95a066b264852da" + "reference": "94215228fd03e548590134d1e521a34ec727460c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-cloud-php-storage/zipball/7fe96d56856cda550b21779bb95a066b264852da", - "reference": "7fe96d56856cda550b21779bb95a066b264852da", + "url": "https://api.github.com/repos/googleapis/google-cloud-php-storage/zipball/94215228fd03e548590134d1e521a34ec727460c", + "reference": "94215228fd03e548590134d1e521a34ec727460c", "shasum": "" }, "require": { - "google/cloud-core": "^1.51.1", - "google/crc32": "^0.2.0", + "google/cloud-core": "^1.52.7", "php": ">=7.4", "ramsey/uuid": "^4.2.3" }, @@ -283,67 +342,29 @@ "Apache-2.0" ], "description": "Cloud Storage Client for PHP", - "time": "2023-05-05T23:01:42+00:00" - }, - { - "name": "google/crc32", - "version": "v0.2.0", - "source": { - "type": "git", - "url": "https://github.com/google/php-crc32.git", - "reference": "948f7945d803dcc1a375152c72f63144c2dadf23" + "support": { + "source": "https://github.com/googleapis/google-cloud-php-storage/tree/v1.36.0" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/google/php-crc32/zipball/948f7945d803dcc1a375152c72f63144c2dadf23", - "reference": "948f7945d803dcc1a375152c72f63144c2dadf23", - "shasum": "" - }, - "require": { - "php": ">=7.4" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "v3.15", - "phpunit/phpunit": "^9" - }, - "type": "library", - "autoload": { - "psr-4": { - "Google\\CRC32\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Andrew Brampton", - "email": "bramp@google.com" - } - ], - "description": "Various CRC32 implementations", - "homepage": "https://github.com/google/php-crc32", - "time": "2023-04-16T22:44:57+00:00" + "time": "2023-12-08T22:36:35+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "7.7.0", + "version": "7.8.1", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "fb7566caccf22d74d1ab270de3551f72a58399f5" + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/fb7566caccf22d74d1ab270de3551f72a58399f5", - "reference": "fb7566caccf22d74d1ab270de3551f72a58399f5", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104", + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.5.3 || ^2.0", - "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", + "guzzlehttp/promises": "^1.5.3 || ^2.0.1", + "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" @@ -352,11 +373,11 @@ "psr/http-client-implementation": "1.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.1", + "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", "php-http/message-factory": "^1.1", - "phpunit/phpunit": "^8.5.29 || ^9.5.23", + "phpunit/phpunit": "^8.5.36 || ^9.6.15", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { @@ -432,6 +453,10 @@ "rest", "web service" ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.8.1" + }, "funding": [ { "url": "https://github.com/GrahamCampbell", @@ -446,33 +471,37 @@ "type": "tidelift" } ], - "time": "2023-05-21T14:04:53+00:00" + "time": "2023-12-03T20:35:24+00:00" }, { "name": "guzzlehttp/promises", - "version": "1.5.3", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e" + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/67ab6e18aaa14d753cc148911d273f6e6cb6721e", - "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e", + "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223", + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223", "shasum": "" }, "require": { - "php": ">=5.5" + "php": "^7.2.5 || ^8.0" }, "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.1" + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" }, "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, "autoload": { - "files": [ - "src/functions_include.php" - ], "psr-4": { "GuzzleHttp\\Promise\\": "src/" } @@ -507,6 +536,10 @@ "keywords": [ "promise" ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.0.2" + }, "funding": [ { "url": "https://github.com/GrahamCampbell", @@ -521,20 +554,20 @@ "type": "tidelift" } ], - "time": "2023-05-21T12:31:43+00:00" + "time": "2023-12-03T20:19:20+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.5.0", + "version": "2.6.2", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "b635f279edd83fc275f822a1188157ffea568ff6" + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/b635f279edd83fc275f822a1188157ffea568ff6", - "reference": "b635f279edd83fc275f822a1188157ffea568ff6", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221", "shasum": "" }, "require": { @@ -548,9 +581,9 @@ "psr/http-message-implementation": "1.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.1", + "bamarni/composer-bin-plugin": "^1.8.2", "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.29 || ^9.5.23" + "phpunit/phpunit": "^8.5.36 || ^9.6.15" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" @@ -619,6 +652,10 @@ "uri", "url" ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.6.2" + }, "funding": [ { "url": "https://github.com/GrahamCampbell", @@ -633,20 +670,20 @@ "type": "tidelift" } ], - "time": "2023-04-17T16:11:26+00:00" + "time": "2023-12-03T20:05:35+00:00" }, { "name": "monolog/monolog", - "version": "2.9.1", + "version": "2.9.2", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "f259e2b15fb95494c83f52d3caad003bbf5ffaa1" + "reference": "437cb3628f4cf6042cc10ae97fc2b8472e48ca1f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f259e2b15fb95494c83f52d3caad003bbf5ffaa1", - "reference": "f259e2b15fb95494c83f52d3caad003bbf5ffaa1", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/437cb3628f4cf6042cc10ae97fc2b8472e48ca1f", + "reference": "437cb3628f4cf6042cc10ae97fc2b8472e48ca1f", "shasum": "" }, "require": { @@ -721,6 +758,10 @@ "logging", "psr-3" ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/2.9.2" + }, "funding": [ { "url": "https://github.com/Seldaek", @@ -731,7 +772,7 @@ "type": "tidelift" } ], - "time": "2023-02-06T13:44:46+00:00" + "time": "2023-10-27T15:25:26+00:00" }, { "name": "paragonie/constant_time_encoding", @@ -793,6 +834,11 @@ "hex2bin", "rfc4648" ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, "time": "2022-06-14T06:56:20+00:00" }, { @@ -838,20 +884,25 @@ "pseudorandom", "random" ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, "time": "2020-10-15T08:29:30+00:00" }, { "name": "phpseclib/phpseclib", - "version": "3.0.19", + "version": "3.0.37", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "cc181005cf548bfd8a4896383bb825d859259f95" + "reference": "cfa2013d0f68c062055180dd4328cc8b9d1f30b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/cc181005cf548bfd8a4896383bb825d859259f95", - "reference": "cc181005cf548bfd8a4896383bb825d859259f95", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/cfa2013d0f68c062055180dd4328cc8b9d1f30b8", + "reference": "cfa2013d0f68c062055180dd4328cc8b9d1f30b8", "shasum": "" }, "require": { @@ -930,6 +981,10 @@ "x.509", "x509" ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.37" + }, "funding": [ { "url": "https://github.com/terrafrost", @@ -944,7 +999,7 @@ "type": "tidelift" } ], - "time": "2023-03-05T17:13:09+00:00" + "time": "2024-03-03T02:14:58+00:00" }, { "name": "psr/cache", @@ -990,20 +1045,23 @@ "psr", "psr-6" ], + "support": { + "source": "https://github.com/php-fig/cache/tree/2.0.0" + }, "time": "2021-02-03T23:23:37+00:00" }, { "name": "psr/http-client", - "version": "1.0.2", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/php-fig/http-client.git", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31" + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", "shasum": "" }, "require": { @@ -1039,7 +1097,10 @@ "psr", "psr-18" ], - "time": "2023-04-10T20:12:12+00:00" + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" }, { "name": "psr/http-factory", @@ -1091,20 +1152,23 @@ "request", "response" ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/1.0.2" + }, "time": "2023-04-10T20:10:41+00:00" }, { "name": "psr/http-message", - "version": "1.1", + "version": "2.0", "source": { "type": "git", "url": "https://github.com/php-fig/http-message.git", - "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", - "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", "shasum": "" }, "require": { @@ -1113,7 +1177,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -1128,7 +1192,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for HTTP messages", @@ -1141,7 +1205,10 @@ "request", "response" ], - "time": "2023-04-04T09:50:52+00:00" + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" }, { "name": "psr/log", @@ -1188,6 +1255,9 @@ "psr", "psr-3" ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, "time": "2021-05-03T11:20:27+00:00" }, { @@ -1228,24 +1298,29 @@ } ], "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, "time": "2019-03-08T08:55:37+00:00" }, { "name": "ramsey/collection", - "version": "2.0.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/ramsey/collection.git", - "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5" + "reference": "ad7475d1c9e70b190ecffc58f2d989416af339b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", - "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", + "url": "https://api.github.com/repos/ramsey/collection/zipball/ad7475d1c9e70b190ecffc58f2d989416af339b4", + "reference": "ad7475d1c9e70b190ecffc58f2d989416af339b4", "shasum": "" }, "require": { - "php": "^8.1" + "php": "^7.4 || ^8.0", + "symfony/polyfill-php81": "^1.23" }, "require-dev": { "captainhook/plugin-composer": "^5.3", @@ -1303,6 +1378,10 @@ "queue", "set" ], + "support": { + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/1.3.0" + }, "funding": [ { "url": "https://github.com/ramsey", @@ -1313,20 +1392,20 @@ "type": "tidelift" } ], - "time": "2022-12-31T21:50:55+00:00" + "time": "2022-12-27T19:12:24+00:00" }, { "name": "ramsey/uuid", - "version": "4.7.4", + "version": "4.7.5", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "60a4c63ab724854332900504274f6150ff26d286" + "reference": "5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/60a4c63ab724854332900504274f6150ff26d286", - "reference": "60a4c63ab724854332900504274f6150ff26d286", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e", + "reference": "5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e", "shasum": "" }, "require": { @@ -1391,6 +1470,10 @@ "identifier", "uuid" ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "source": "https://github.com/ramsey/uuid/tree/4.7.5" + }, "funding": [ { "url": "https://github.com/ramsey", @@ -1401,7 +1484,7 @@ "type": "tidelift" } ], - "time": "2023-04-15T23:01:58+00:00" + "time": "2023-11-08T05:53:05+00:00" }, { "name": "rize/uri-template", @@ -1445,6 +1528,10 @@ "template", "uri" ], + "support": { + "issues": "https://github.com/rize/UriTemplate/issues", + "source": "https://github.com/rize/UriTemplate/tree/0.3.5" + }, "funding": [ { "url": "https://www.paypal.me/rezigned", @@ -1463,25 +1550,25 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v3.2.1", + "version": "v3.0.2", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e" + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e", - "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.0.2" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.3-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", @@ -1509,6 +1596,9 @@ ], "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.2" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1523,7 +1613,86 @@ "type": "tidelift" } ], - "time": "2023-03-01T10:25:55+00:00" + "time": "2022-01-02T09:55:41+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/7581cd600fa9fd681b797d00b02f068e2f13263b", + "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "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 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.28.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": "2023-01-26T09:26:14+00:00" } ], "packages-dev": [ @@ -1586,6 +1755,9 @@ "psr-6", "tag" ], + "support": { + "source": "https://github.com/php-cache/adapter-common/tree/1.3.0" + }, "time": "2022-01-15T15:47:19+00:00" }, { @@ -1655,6 +1827,9 @@ "psr-6", "tag" ], + "support": { + "source": "https://github.com/php-cache/filesystem-adapter/tree/1.2.0" + }, "time": "2022-01-15T15:47:19+00:00" }, { @@ -1710,20 +1885,24 @@ "psr6", "tag" ], + "support": { + "issues": "https://github.com/php-cache/tag-interop/issues", + "source": "https://github.com/php-cache/tag-interop/tree/1.1.0" + }, "time": "2021-12-31T10:03:23+00:00" }, { "name": "composer/ca-bundle", - "version": "1.3.5", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "74780ccf8c19d6acb8d65c5f39cd72110e132bbd" + "reference": "b66d11b7479109ab547f9405b97205640b17d385" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/74780ccf8c19d6acb8d65c5f39cd72110e132bbd", - "reference": "74780ccf8c19d6acb8d65c5f39cd72110e132bbd", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/b66d11b7479109ab547f9405b97205640b17d385", + "reference": "b66d11b7479109ab547f9405b97205640b17d385", "shasum": "" }, "require": { @@ -1735,7 +1914,7 @@ "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" + "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0" }, "type": "library", "extra": { @@ -1767,6 +1946,11 @@ "ssl", "tls" ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/ca-bundle/issues", + "source": "https://github.com/composer/ca-bundle/tree/1.4.0" + }, "funding": [ { "url": "https://packagist.com", @@ -1781,20 +1965,20 @@ "type": "tidelift" } ], - "time": "2023-01-11T08:27:00+00:00" + "time": "2023-12-18T12:05:55+00:00" }, { "name": "composer/composer", - "version": "1.10.26", + "version": "1.10.27", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "3e196135eacf9e519a6b00986bc6fe6aff977997" + "reference": "f8f49191eec76f039b466aa1f161406fe43aff50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/3e196135eacf9e519a6b00986bc6fe6aff977997", - "reference": "3e196135eacf9e519a6b00986bc6fe6aff977997", + "url": "https://api.github.com/repos/composer/composer/zipball/f8f49191eec76f039b466aa1f161406fe43aff50", + "reference": "f8f49191eec76f039b466aa1f161406fe43aff50", "shasum": "" }, "require": { @@ -1861,6 +2045,11 @@ "dependency", "package" ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/composer/issues", + "source": "https://github.com/composer/composer/tree/1.10.27" + }, "funding": [ { "url": "https://packagist.com", @@ -1875,7 +2064,7 @@ "type": "tidelift" } ], - "time": "2022-04-13T14:39:56+00:00" + "time": "2023-09-29T08:50:23+00:00" }, { "name": "composer/semver", @@ -1936,6 +2125,11 @@ "validation", "versioning" ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/1.7.2" + }, "funding": [ { "url": "https://packagist.com", @@ -1954,16 +2148,16 @@ }, { "name": "composer/spdx-licenses", - "version": "1.5.7", + "version": "1.5.8", "source": { "type": "git", "url": "https://github.com/composer/spdx-licenses.git", - "reference": "c848241796da2abf65837d51dce1fae55a960149" + "reference": "560bdcf8deb88ae5d611c80a2de8ea9d0358cc0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/c848241796da2abf65837d51dce1fae55a960149", - "reference": "c848241796da2abf65837d51dce1fae55a960149", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/560bdcf8deb88ae5d611c80a2de8ea9d0358cc0a", + "reference": "560bdcf8deb88ae5d611c80a2de8ea9d0358cc0a", "shasum": "" }, "require": { @@ -2011,6 +2205,11 @@ "spdx", "validator" ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/spdx-licenses/issues", + "source": "https://github.com/composer/spdx-licenses/tree/1.5.8" + }, "funding": [ { "url": "https://packagist.com", @@ -2025,7 +2224,7 @@ "type": "tidelift" } ], - "time": "2022-05-23T07:37:50+00:00" + "time": "2023-11-20T07:44:33+00:00" }, { "name": "composer/xdebug-handler", @@ -2070,6 +2269,11 @@ "Xdebug", "performance" ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/1.4.6" + }, "funding": [ { "url": "https://packagist.com", @@ -2088,25 +2292,29 @@ }, { "name": "doctrine/deprecations", - "version": "v1.0.0", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de" + "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", - "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/4f2d4f2836e7ec4e7a8625e75c6aa916004db931", + "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931", "shasum": "" }, "require": { - "php": "^7.1|^8.0" + "php": "^7.1 || ^8.0" }, "require-dev": { "doctrine/coding-standard": "^9", - "phpunit/phpunit": "^7.5|^8.5|^9.5", - "psr/log": "^1|^2|^3" + "phpstan/phpstan": "1.4.10 || 1.10.15", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "0.18.4", + "psr/log": "^1 || ^2 || ^3", + "vimeo/psalm": "4.30.0 || 5.12.0" }, "suggest": { "psr/log": "Allows logging deprecations via PSR-3 logger implementation" @@ -2123,34 +2331,38 @@ ], "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", "homepage": "https://www.doctrine-project.org/", - "time": "2022-05-02T15:47:09+00:00" + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.2" + }, + "time": "2023-09-27T20:04:15+00:00" }, { "name": "doctrine/instantiator", - "version": "2.0.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", - "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", "shasum": "" }, "require": { - "php": "^8.1" + "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^11", + "doctrine/coding-standard": "^9 || ^11", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^1.2", - "phpstan/phpstan": "^1.9.4", - "phpstan/phpstan-phpunit": "^1.3", - "phpunit/phpunit": "^9.5.27", - "vimeo/psalm": "^5.4" + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.30 || ^5.4" }, "type": "library", "autoload": { @@ -2175,6 +2387,10 @@ "constructor", "instantiate" ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.5.0" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -2189,20 +2405,20 @@ "type": "tidelift" } ], - "time": "2022-12-30T00:23:10+00:00" + "time": "2022-12-30T00:15:36+00:00" }, { "name": "justinrainbow/json-schema", - "version": "5.2.12", + "version": "v5.2.13", "source": { "type": "git", "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60" + "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/ad87d5a5ca981228e0e205c2bc7dfb8e24559b60", - "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/fbbe7e5d79f618997bc3332a6f49246036c45793", + "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793", "shasum": "" }, "require": { @@ -2255,7 +2471,11 @@ "json", "schema" ], - "time": "2022-04-13T08:02:27+00:00" + "support": { + "issues": "https://github.com/justinrainbow/json-schema/issues", + "source": "https://github.com/justinrainbow/json-schema/tree/v5.2.13" + }, + "time": "2023-09-26T02:20:38+00:00" }, { "name": "league/flysystem", @@ -2339,6 +2559,10 @@ "sftp", "storage" ], + "support": { + "issues": "https://github.com/thephpleague/flysystem/issues", + "source": "https://github.com/thephpleague/flysystem/tree/1.1.10" + }, "funding": [ { "url": "https://offset.earth/frankdejonge", @@ -2349,26 +2573,26 @@ }, { "name": "league/mime-type-detection", - "version": "1.11.0", + "version": "1.14.0", "source": { "type": "git", "url": "https://github.com/thephpleague/mime-type-detection.git", - "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd" + "reference": "b6a5854368533df0295c5761a0253656a2e52d9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ff6248ea87a9f116e78edd6002e39e5128a0d4dd", - "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/b6a5854368533df0295c5761a0253656a2e52d9e", + "reference": "b6a5854368533df0295c5761a0253656a2e52d9e", "shasum": "" }, "require": { "ext-fileinfo": "*", - "php": "^7.2 || ^8.0" + "php": "^7.4 || ^8.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.2", "phpstan/phpstan": "^0.12.68", - "phpunit/phpunit": "^8.5.8 || ^9.3" + "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0" }, "type": "library", "autoload": { @@ -2387,6 +2611,10 @@ } ], "description": "Mime-type detection for Flysystem", + "support": { + "issues": "https://github.com/thephpleague/mime-type-detection/issues", + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.14.0" + }, "funding": [ { "url": "https://github.com/frankdejonge", @@ -2397,7 +2625,7 @@ "type": "tidelift" } ], - "time": "2022-04-17T13:12:02+00:00" + "time": "2023-10-17T14:13:20+00:00" }, { "name": "myclabs/deep-copy", @@ -2446,6 +2674,10 @@ "object", "object graph" ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + }, "funding": [ { "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", @@ -2456,16 +2688,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.15.5", + "version": "v4.18.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "11e2663a5bc9db5d714eedb4277ee300403b4a9e" + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/11e2663a5bc9db5d714eedb4277ee300403b4a9e", - "reference": "11e2663a5bc9db5d714eedb4277ee300403b4a9e", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999", "shasum": "" }, "require": { @@ -2504,7 +2736,11 @@ "parser", "php" ], - "time": "2023-05-19T20:20:00+00:00" + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0" + }, + "time": "2023-12-10T21:03:43+00:00" }, { "name": "phar-io/manifest", @@ -2560,6 +2796,10 @@ } ], "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" + }, "time": "2021-07-20T11:28:43+00:00" }, { @@ -2607,6 +2847,10 @@ } ], "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, "time": "2022-02-21T01:04:05+00:00" }, { @@ -2665,6 +2909,10 @@ "phpcs", "standards" ], + "support": { + "issues": "https://github.com/PHPCompatibility/PHPCompatibility/issues", + "source": "https://github.com/PHPCompatibility/PHPCompatibility" + }, "time": "2019-12-27T09:44:58+00:00" }, { @@ -2714,6 +2962,10 @@ "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" }, { @@ -2767,20 +3019,24 @@ } ], "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.7.1", + "version": "1.7.3", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "dfc078e8af9c99210337325ff5aa152872c98714" + "reference": "3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/dfc078e8af9c99210337325ff5aa152872c98714", - "reference": "dfc078e8af9c99210337325ff5aa152872c98714", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419", + "reference": "3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419", "shasum": "" }, "require": { @@ -2821,33 +3077,37 @@ } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2023-03-27T19:02:04+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.7.3" + }, + "time": "2023-08-12T11:01:26+00:00" }, { "name": "phpspec/prophecy", - "version": "v1.17.0", + "version": "v1.18.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "15873c65b207b07765dbc3c95d20fdf4a320cbe2" + "reference": "d4f454f7e1193933f04e6500de3e79191648ed0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/15873c65b207b07765dbc3c95d20fdf4a320cbe2", - "reference": "15873c65b207b07765dbc3c95d20fdf4a320cbe2", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d4f454f7e1193933f04e6500de3e79191648ed0c", + "reference": "d4f454f7e1193933f04e6500de3e79191648ed0c", "shasum": "" }, "require": { "doctrine/instantiator": "^1.2 || ^2.0", - "php": "^7.2 || 8.0.* || 8.1.* || 8.2.*", + "php": "^7.2 || 8.0.* || 8.1.* || 8.2.* || 8.3.*", "phpdocumentor/reflection-docblock": "^5.2", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" + "sebastian/comparator": "^3.0 || ^4.0 || ^5.0", + "sebastian/recursion-context": "^3.0 || ^4.0 || ^5.0" }, "require-dev": { "phpspec/phpspec": "^6.0 || ^7.0", "phpstan/phpstan": "^1.9", - "phpunit/phpunit": "^8.0 || ^9.0" + "phpunit/phpunit": "^8.0 || ^9.0 || ^10.0" }, "type": "library", "extra": { @@ -2880,31 +3140,36 @@ "keywords": [ "Double", "Dummy", + "dev", "fake", "mock", "spy", "stub" ], - "time": "2023-02-02T15:41:36+00:00" + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/v1.18.0" + }, + "time": "2023-12-07T16:22:33+00:00" }, { "name": "phpspec/prophecy-phpunit", - "version": "v2.0.2", + "version": "v2.1.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy-phpunit.git", - "reference": "9f26c224a2fa335f33e6666cc078fbf388255e87" + "reference": "29f8114c2c319a4308e6b070902211e062efa392" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy-phpunit/zipball/9f26c224a2fa335f33e6666cc078fbf388255e87", - "reference": "9f26c224a2fa335f33e6666cc078fbf388255e87", + "url": "https://api.github.com/repos/phpspec/prophecy-phpunit/zipball/29f8114c2c319a4308e6b070902211e062efa392", + "reference": "29f8114c2c319a4308e6b070902211e062efa392", "shasum": "" }, "require": { "php": "^7.3 || ^8", - "phpspec/prophecy": "^1.3", - "phpunit/phpunit": "^9.1" + "phpspec/prophecy": "^1.18", + "phpunit/phpunit": "^9.1 || ^10.1" }, "type": "library", "extra": { @@ -2933,26 +3198,31 @@ "phpunit", "prophecy" ], - "time": "2023-04-18T11:58:05+00:00" + "support": { + "issues": "https://github.com/phpspec/prophecy-phpunit/issues", + "source": "https://github.com/phpspec/prophecy-phpunit/tree/v2.1.0" + }, + "time": "2023-12-08T12:48:02+00:00" }, { "name": "phpstan/phpdoc-parser", - "version": "1.21.0", + "version": "1.24.5", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "6df62b08faef4f899772bc7c3bbabb93d2b7a21c" + "reference": "fedf211ff14ec8381c9bf5714e33a7a552dd1acc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/6df62b08faef4f899772bc7c3bbabb93d2b7a21c", - "reference": "6df62b08faef4f899772bc7c3bbabb93d2b7a21c", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fedf211ff14ec8381c9bf5714e33a7a552dd1acc", + "reference": "fedf211ff14ec8381c9bf5714e33a7a552dd1acc", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "require-dev": { + "doctrine/annotations": "^2.0", "nikic/php-parser": "^4.15", "php-parallel-lint/php-parallel-lint": "^1.2", "phpstan/extension-installer": "^1.0", @@ -2975,27 +3245,31 @@ "MIT" ], "description": "PHPDoc parser with support for nullable, intersection and generic types", - "time": "2023-05-17T13:13:44+00:00" + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.5" + }, + "time": "2023-12-16T09:33:33+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.26", + "version": "9.2.30", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1" + "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", - "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca2bd87d2f9215904682a9cb9bb37dda98e76089", + "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.15", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -3042,13 +3316,18 @@ "testing", "xunit" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.30" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], - "time": "2023-03-06T12:58:08+00:00" + "time": "2023-12-22T06:47:57+00:00" }, { "name": "phpunit/php-file-iterator", @@ -3098,6 +3377,10 @@ "filesystem", "iterator" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3157,6 +3440,10 @@ "keywords": [ "process" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3212,6 +3499,10 @@ "keywords": [ "template" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3267,6 +3558,10 @@ "keywords": [ "timer" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3277,16 +3572,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.8", + "version": "9.6.15", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "17d621b3aff84d0c8b62539e269e87d8d5baa76e" + "reference": "05017b80304e0eb3f31d90194a563fd53a6021f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/17d621b3aff84d0c8b62539e269e87d8d5baa76e", - "reference": "17d621b3aff84d0c8b62539e269e87d8d5baa76e", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/05017b80304e0eb3f31d90194a563fd53a6021f1", + "reference": "05017b80304e0eb3f31d90194a563fd53a6021f1", "shasum": "" }, "require": { @@ -3301,7 +3596,7 @@ "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", "php": ">=7.3", - "phpunit/php-code-coverage": "^9.2.13", + "phpunit/php-code-coverage": "^9.2.28", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", "phpunit/php-text-template": "^2.0.3", @@ -3357,6 +3652,11 @@ "testing", "xunit" ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.15" + }, "funding": [ { "url": "https://phpunit.de/sponsors.html", @@ -3371,7 +3671,7 @@ "type": "tidelift" } ], - "time": "2023-05-11T05:14:45+00:00" + "time": "2023-12-01T16:55:19+00:00" }, { "name": "psr/container", @@ -3420,6 +3720,10 @@ "container-interop", "psr" ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, "time": "2021-11-05T16:47:00+00:00" }, { @@ -3468,6 +3772,9 @@ "psr-16", "simple-cache" ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/master" + }, "time": "2017-10-23T01:57:42+00:00" }, { @@ -3514,6 +3821,10 @@ ], "description": "Library for parsing CLI options", "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" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3566,6 +3877,10 @@ ], "description": "Collection of value objects that represent the PHP code units", "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" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3617,6 +3932,10 @@ ], "description": "Looks up which function or method a line of code belongs to", "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" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3687,6 +4006,10 @@ "compare", "equality" ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3697,20 +4020,20 @@ }, { "name": "sebastian/complexity", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", "shasum": "" }, "require": { - "nikic/php-parser": "^4.7", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3" }, "require-dev": { @@ -3740,13 +4063,17 @@ ], "description": "Library for calculating the complexity of PHP code units", "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], - "time": "2020-10-26T15:52:27+00:00" + "time": "2023-12-22T06:19:30+00:00" }, { "name": "sebastian/diff", @@ -3802,6 +4129,10 @@ "unidiff", "unified diff" ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3861,6 +4192,10 @@ "environment", "hhvm" ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3934,6 +4269,10 @@ "export", "exporter" ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3944,16 +4283,16 @@ }, { "name": "sebastian/global-state", - "version": "5.0.5", + "version": "5.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" + "reference": "bde739e7565280bda77be70044ac1047bc007e34" }, "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/bde739e7565280bda77be70044ac1047bc007e34", + "reference": "bde739e7565280bda77be70044ac1047bc007e34", "shasum": "" }, "require": { @@ -3994,30 +4333,34 @@ "keywords": [ "global state" ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.6" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], - "time": "2022-02-14T08:28:10+00:00" + "time": "2023-08-02T09:26:13+00:00" }, { "name": "sebastian/lines-of-code", - "version": "1.0.3", + "version": "1.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" }, "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/e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", "shasum": "" }, "require": { - "nikic/php-parser": "^4.6", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3" }, "require-dev": { @@ -4047,13 +4390,17 @@ ], "description": "Library for counting the lines of code in PHP source code", "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.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], - "time": "2020-11-28T06:42:11+00:00" + "time": "2023-12-22T06:20:34+00:00" }, { "name": "sebastian/object-enumerator", @@ -4100,6 +4447,10 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "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" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4151,6 +4502,10 @@ ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "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" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4210,6 +4565,10 @@ ], "description": "Provides functionality to recursively process PHP variables", "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.5" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4261,6 +4620,10 @@ ], "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", @@ -4313,6 +4676,10 @@ ], "description": "Collection of value objects that represent the types of the PHP type system", "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4362,6 +4729,10 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4372,16 +4743,16 @@ }, { "name": "seld/jsonlint", - "version": "1.10.0", + "version": "1.10.1", "source": { "type": "git", "url": "https://github.com/Seldaek/jsonlint.git", - "reference": "594fd6462aad8ecee0b45ca5045acea4776667f1" + "reference": "76d449a358ece77d6f1d6331c68453e657172202" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/594fd6462aad8ecee0b45ca5045acea4776667f1", - "reference": "594fd6462aad8ecee0b45ca5045acea4776667f1", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/76d449a358ece77d6f1d6331c68453e657172202", + "reference": "76d449a358ece77d6f1d6331c68453e657172202", "shasum": "" }, "require": { @@ -4408,7 +4779,7 @@ { "name": "Jordi Boggiano", "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" + "homepage": "https://seld.be" } ], "description": "JSON Linter", @@ -4418,6 +4789,10 @@ "parser", "validator" ], + "support": { + "issues": "https://github.com/Seldaek/jsonlint/issues", + "source": "https://github.com/Seldaek/jsonlint/tree/1.10.1" + }, "funding": [ { "url": "https://github.com/Seldaek", @@ -4428,7 +4803,7 @@ "type": "tidelift" } ], - "time": "2023-05-11T13:16:46+00:00" + "time": "2023-12-18T13:03:25+00:00" }, { "name": "seld/phar-utils", @@ -4472,20 +4847,24 @@ "keywords": [ "phar" ], + "support": { + "issues": "https://github.com/Seldaek/phar-utils/issues", + "source": "https://github.com/Seldaek/phar-utils/tree/1.2.1" + }, "time": "2022-08-31T10:31:18+00:00" }, { "name": "squizlabs/php_codesniffer", - "version": "3.7.2", + "version": "3.8.0", "source": { "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879" + "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", + "reference": "5805f7a4e4958dbb5e944ef1e6edae0a303765e7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879", - "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/5805f7a4e4958dbb5e944ef1e6edae0a303765e7", + "reference": "5805f7a4e4958dbb5e944ef1e6edae0a303765e7", "shasum": "" }, "require": { @@ -4495,7 +4874,7 @@ "php": ">=5.4.0" }, "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" }, "bin": [ "bin/phpcs", @@ -4514,30 +4893,58 @@ "authors": [ { "name": "Greg Sherwood", - "role": "lead" + "role": "Former lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "Current lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" } ], "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", "keywords": [ "phpcs", "standards", "static analysis" ], - "time": "2023-02-22T23:07:41+00:00" + "support": { + "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", + "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", + "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" + }, + "funding": [ + { + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + } + ], + "time": "2023-12-08T12:32:31+00:00" }, { "name": "symfony/console", - "version": "v5.4.23", + "version": "v5.4.32", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "90f21e27d0d88ce38720556dd164d4a1e4c3934c" + "reference": "c70df1ffaf23a8d340bded3cfab1b86752ad6ed7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/90f21e27d0d88ce38720556dd164d4a1e4c3934c", - "reference": "90f21e27d0d88ce38720556dd164d4a1e4c3934c", + "url": "https://api.github.com/repos/symfony/console/zipball/c70df1ffaf23a8d340bded3cfab1b86752ad6ed7", + "reference": "c70df1ffaf23a8d340bded3cfab1b86752ad6ed7", "shasum": "" }, "require": { @@ -4606,6 +5013,9 @@ "console", "terminal" ], + "support": { + "source": "https://github.com/symfony/console/tree/v5.4.32" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4620,7 +5030,7 @@ "type": "tidelift" } ], - "time": "2023-04-24T18:47:29+00:00" + "time": "2023-11-18T18:23:04+00:00" }, { "name": "symfony/css-selector", @@ -4673,6 +5083,9 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/css-selector/tree/v2.8.52" + }, "time": "2018-11-11T11:18:13+00:00" }, { @@ -4730,20 +5143,23 @@ ], "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dom-crawler/tree/v2.8.50" + }, "time": "2018-11-24T22:30:19+00:00" }, { "name": "symfony/filesystem", - "version": "v5.4.23", + "version": "v5.4.25", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "b2f79d86cd9e7de0fff6d03baa80eaed7a5f38b5" + "reference": "0ce3a62c9579a53358d3a7eb6b3dfb79789a6364" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/b2f79d86cd9e7de0fff6d03baa80eaed7a5f38b5", - "reference": "b2f79d86cd9e7de0fff6d03baa80eaed7a5f38b5", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/0ce3a62c9579a53358d3a7eb6b3dfb79789a6364", + "reference": "0ce3a62c9579a53358d3a7eb6b3dfb79789a6364", "shasum": "" }, "require": { @@ -4777,6 +5193,9 @@ ], "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v5.4.25" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4791,20 +5210,20 @@ "type": "tidelift" } ], - "time": "2023-03-02T11:38:35+00:00" + "time": "2023-05-31T13:04:02+00:00" }, { "name": "symfony/finder", - "version": "v5.4.21", + "version": "v5.4.27", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "078e9a5e1871fcfe6a5ce421b539344c21afef19" + "reference": "ff4bce3c33451e7ec778070e45bd23f74214cd5d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/078e9a5e1871fcfe6a5ce421b539344c21afef19", - "reference": "078e9a5e1871fcfe6a5ce421b539344c21afef19", + "url": "https://api.github.com/repos/symfony/finder/zipball/ff4bce3c33451e7ec778070e45bd23f74214cd5d", + "reference": "ff4bce3c33451e7ec778070e45bd23f74214cd5d", "shasum": "" }, "require": { @@ -4837,6 +5256,9 @@ ], "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v5.4.27" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4851,20 +5273,20 @@ "type": "tidelift" } ], - "time": "2023-02-16T09:33:00+00:00" + "time": "2023-07-31T08:02:31+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", "shasum": "" }, "require": { @@ -4879,7 +5301,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4916,6 +5338,9 @@ "polyfill", "portable" ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4930,20 +5355,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354" + "reference": "875e90aeea2777b6f135677f618529449334a612" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612", + "reference": "875e90aeea2777b6f135677f618529449334a612", "shasum": "" }, "require": { @@ -4955,7 +5380,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4994,6 +5419,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -5008,20 +5436,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" }, "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/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", "shasum": "" }, "require": { @@ -5033,7 +5461,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -5075,6 +5503,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -5089,20 +5520,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + "reference": "42292d99c55abe617799667f454222c54c60e229" }, "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/42292d99c55abe617799667f454222c54c60e229", + "reference": "42292d99c55abe617799667f454222c54c60e229", "shasum": "" }, "require": { @@ -5117,7 +5548,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -5155,6 +5586,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -5169,20 +5603,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-07-28T09:04:16+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9" + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/9e8ecb5f92152187c4799efd3c96b78ccab18ff9", - "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fe2f306d1d9d346a7fee353d0d5012e401e984b5", + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5", "shasum": "" }, "require": { @@ -5191,7 +5625,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -5231,6 +5665,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.28.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -5245,20 +5682,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", "shasum": "" }, "require": { @@ -5267,7 +5704,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -5311,6 +5748,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -5325,20 +5765,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/process", - "version": "v5.4.23", + "version": "v5.4.28", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "4b842fc4b61609e0a155a114082bd94e31e98287" + "reference": "45261e1fccad1b5447a8d7a8e67aa7b4a9798b7b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/4b842fc4b61609e0a155a114082bd94e31e98287", - "reference": "4b842fc4b61609e0a155a114082bd94e31e98287", + "url": "https://api.github.com/repos/symfony/process/zipball/45261e1fccad1b5447a8d7a8e67aa7b4a9798b7b", + "reference": "45261e1fccad1b5447a8d7a8e67aa7b4a9798b7b", "shasum": "" }, "require": { @@ -5370,6 +5810,9 @@ ], "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v5.4.28" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -5384,24 +5827,24 @@ "type": "tidelift" } ], - "time": "2023-04-18T13:50:24+00:00" + "time": "2023-08-07T10:36:04+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.2.1", + "version": "v3.0.2", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "a8c9cedf55f314f3a186041d19537303766df09a" + "reference": "d78d39c1599bd1188b8e26bb341da52c3c6d8a66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/a8c9cedf55f314f3a186041d19537303766df09a", - "reference": "a8c9cedf55f314f3a186041d19537303766df09a", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d78d39c1599bd1188b8e26bb341da52c3c6d8a66", + "reference": "d78d39c1599bd1188b8e26bb341da52c3c6d8a66", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.0.2", "psr/container": "^2.0" }, "conflict": { @@ -5413,7 +5856,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.3-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", @@ -5423,10 +5866,7 @@ "autoload": { "psr-4": { "Symfony\\Contracts\\Service\\": "" - }, - "exclude-from-classmap": [ - "/Test/" - ] + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -5452,6 +5892,9 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.0.2" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -5466,24 +5909,24 @@ "type": "tidelift" } ], - "time": "2023-03-01T10:32:47+00:00" + "time": "2022-05-30T19:17:58+00:00" }, { "name": "symfony/string", - "version": "v6.2.8", + "version": "v6.0.19", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef" + "reference": "d9e72497367c23e08bf94176d2be45b00a9d232a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/193e83bbd6617d6b2151c37fff10fa7168ebddef", - "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef", + "url": "https://api.github.com/repos/symfony/string/zipball/d9e72497367c23e08bf94176d2be45b00a9d232a", + "reference": "d9e72497367c23e08bf94176d2be45b00a9d232a", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.0.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", @@ -5495,7 +5938,6 @@ "require-dev": { "symfony/error-handler": "^5.4|^6.0", "symfony/http-client": "^5.4|^6.0", - "symfony/intl": "^6.2", "symfony/translation-contracts": "^2.0|^3.0", "symfony/var-exporter": "^5.4|^6.0" }, @@ -5535,6 +5977,9 @@ "utf-8", "utf8" ], + "support": { + "source": "https://github.com/symfony/string/tree/v6.0.19" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -5549,20 +5994,20 @@ "type": "tidelift" } ], - "time": "2023-03-20T16:06:02+00:00" + "time": "2023-01-01T08:36:10+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.1", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96", + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96", "shasum": "" }, "require": { @@ -5589,13 +6034,17 @@ } ], "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.2" + }, "funding": [ { "url": "https://github.com/theseer", "type": "github" } ], - "time": "2021-07-28T10:34:58+00:00" + "time": "2023-11-20T00:12:19+00:00" }, { "name": "webmozart/assert", @@ -5649,6 +6098,10 @@ "check", "validate" ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, "time": "2022-06-03T18:03:27+00:00" } ], @@ -5661,5 +6114,5 @@ "php": "^7.4|^8.0" }, "platform-dev": [], - "plugin-api-version": "1.1.0" + "plugin-api-version": "2.6.0" } diff --git a/lib/Google/phpstan.neon.dist b/lib/Google/phpstan.neon.dist new file mode 100644 index 000000000..dcef11342 --- /dev/null +++ b/lib/Google/phpstan.neon.dist @@ -0,0 +1,5 @@ +parameters: + treatPhpDocTypesAsCertain: false + level: 5 + paths: + - src diff --git a/lib/Google/vendor/autoload.php b/lib/Google/vendor/autoload.php index b499e6fe8..67e940915 100644 --- a/lib/Google/vendor/autoload.php +++ b/lib/Google/vendor/autoload.php @@ -2,6 +2,24 @@ // autoload.php @generated by Composer +if (PHP_VERSION_ID < 50600) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + $err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL; + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, $err); + } elseif (!headers_sent()) { + echo $err; + } + } + trigger_error( + $err, + E_USER_ERROR + ); +} + require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit8a18562d3013519ef85187fe20fc0499::getLoader(); +return ComposerAutoloaderInit2cd6126242849aa869f10969652c4467::getLoader(); diff --git a/lib/Google/vendor/bin/google-cloud-batch b/lib/Google/vendor/bin/google-cloud-batch deleted file mode 120000 index e4c01822d..000000000 --- a/lib/Google/vendor/bin/google-cloud-batch +++ /dev/null @@ -1 +0,0 @@ -../google/cloud-core/bin/google-cloud-batch \ No newline at end of file diff --git a/lib/Google/vendor/bin/google-cloud-batch b/lib/Google/vendor/bin/google-cloud-batch new file mode 100755 index 000000000..04b357fa1 --- /dev/null +++ b/lib/Google/vendor/bin/google-cloud-batch @@ -0,0 +1,119 @@ +#!/usr/bin/env php +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + return include("phpvfscomposer://" . __DIR__ . '/..'.'/google/cloud-core/bin/google-cloud-batch'); + } +} + +return include __DIR__ . '/..'.'/google/cloud-core/bin/google-cloud-batch'; diff --git a/lib/Google/vendor/composer/ClassLoader.php b/lib/Google/vendor/composer/ClassLoader.php index 03b9bb9c4..7824d8f7e 100644 --- a/lib/Google/vendor/composer/ClassLoader.php +++ b/lib/Google/vendor/composer/ClassLoader.php @@ -37,26 +37,81 @@ * * @author Fabien Potencier * @author Jordi Boggiano - * @see http://www.php-fig.org/psr/psr-0/ - * @see http://www.php-fig.org/psr/psr-4/ + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ */ class ClassLoader { + /** @var \Closure(string):void */ + private static $includeFile; + + /** @var string|null */ + private $vendorDir; + // PSR-4 + /** + * @var array> + */ private $prefixLengthsPsr4 = array(); + /** + * @var array> + */ private $prefixDirsPsr4 = array(); + /** + * @var list + */ private $fallbackDirsPsr4 = array(); // PSR-0 + /** + * 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 list + */ private $fallbackDirsPsr0 = array(); + /** @var bool */ private $useIncludePath = false; + + /** + * @var array + */ private $classMap = array(); + + /** @var bool */ private $classMapAuthoritative = false; + + /** + * @var array + */ private $missingClasses = array(); + + /** @var string|null */ private $apcuPrefix; + /** + * @var array + */ + private static $registeredLoaders = array(); + + /** + * @param string|null $vendorDir + */ + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + self::initializeIncludeClosure(); + } + + /** + * @return array> + */ public function getPrefixes() { if (!empty($this->prefixesPsr0)) { @@ -66,28 +121,42 @@ public function getPrefixes() return array(); } + /** + * @return array> + */ public function getPrefixesPsr4() { return $this->prefixDirsPsr4; } + /** + * @return list + */ public function getFallbackDirs() { return $this->fallbackDirsPsr0; } + /** + * @return list + */ public function getFallbackDirsPsr4() { return $this->fallbackDirsPsr4; } + /** + * @return array Array of classname => path + */ public function getClassMap() { return $this->classMap; } /** - * @param array $classMap Class to filename map + * @param array $classMap Class to filename map + * + * @return void */ public function addClassMap(array $classMap) { @@ -102,22 +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 array|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 ); } @@ -126,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 ); } } @@ -147,25 +219,28 @@ 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 array|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 + * + * @return void */ 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])) { @@ -175,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 ); } } @@ -195,8 +270,10 @@ 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 array|string $paths The PSR-0 base directories + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 base directories + * + * @return void */ public function set($prefix, $paths) { @@ -211,10 +288,12 @@ 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 array|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 + * + * @return void */ public function setPsr4($prefix, $paths) { @@ -234,6 +313,8 @@ public function setPsr4($prefix, $paths) * Turns on searching the include path for class files. * * @param bool $useIncludePath + * + * @return void */ public function setUseIncludePath($useIncludePath) { @@ -256,6 +337,8 @@ public function getUseIncludePath() * that have not been registered with the class map. * * @param bool $classMapAuthoritative + * + * @return void */ public function setClassMapAuthoritative($classMapAuthoritative) { @@ -276,6 +359,8 @@ public function isClassMapAuthoritative() * APCu prefix to use to cache found/not-found classes, if the extension is enabled. * * @param string|null $apcuPrefix + * + * @return void */ public function setApcuPrefix($apcuPrefix) { @@ -296,33 +381,55 @@ public function getApcuPrefix() * Registers this instance as an autoloader. * * @param bool $prepend Whether to prepend the autoloader or not + * + * @return void */ public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + return; + } + + if ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } } /** * Unregisters this instance as an autoloader. + * + * @return void */ public function unregister() { spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } } /** * Loads the given class or interface. * * @param string $class The name of the class - * @return bool|null True if loaded, null otherwise + * @return true|null True if loaded, null otherwise */ public function loadClass($class) { if ($file = $this->findFile($class)) { - includeFile($file); + $includeFile = self::$includeFile; + $includeFile($file); return true; } + + return null; } /** @@ -367,6 +474,21 @@ public function findFile($class) return $file; } + /** + * Returns the currently registered loaders keyed by their corresponding vendor directories. + * + * @return array + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + + /** + * @param string $class + * @param string $ext + * @return string|false + */ private function findFileWithExtension($class, $ext) { // PSR-4 lookup @@ -432,14 +554,26 @@ private function findFileWithExtension($class, $ext) return false; } -} -/** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - */ -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/lib/Google/vendor/composer/InstalledVersions.php b/lib/Google/vendor/composer/InstalledVersions.php new file mode 100644 index 000000000..51e734a77 --- /dev/null +++ b/lib/Google/vendor/composer/InstalledVersions.php @@ -0,0 +1,359 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer; + +use Composer\Autoload\ClassLoader; +use Composer\Semver\VersionParser; + +/** + * This class is copied in every Composer installed project and available to all + * + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + * + * @final + */ +class InstalledVersions +{ + /** + * @var mixed[]|null + * @psalm-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}|array{}|null + */ + private static $installed; + + /** + * @var bool|null + */ + private static $canGetVendors; + + /** + * @var array[] + * @psalm-var array}> + */ + private static $installedByVendor = array(); + + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackages() + { + $packages = array(); + foreach (self::getInstalled() as $installed) { + $packages[] = array_keys($installed['versions']); + } + + if (1 === \count($packages)) { + return $packages[0]; + } + + return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); + } + + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + + return $packagesByType; + } + + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @param bool $includeDevRequirements + * @return bool + */ + public static function isInstalled($packageName, $includeDevRequirements = true) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; + } + } + + return false; + } + + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints((string) $constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + + return $provided->matches($constraint); + } + + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + public static function getVersionRanges($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + $ranges = array(); + if (isset($installed['versions'][$packageName]['pretty_version'])) { + $ranges[] = $installed['versions'][$packageName]['pretty_version']; + } + if (array_key_exists('aliases', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); + } + if (array_key_exists('replaced', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); + } + if (array_key_exists('provided', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); + } + + return implode(' || ', $ranges); + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['version'])) { + return null; + } + + return $installed['versions'][$packageName]['version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getPrettyVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['pretty_version'])) { + return null; + } + + return $installed['versions'][$packageName]['pretty_version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference + */ + public static function getReference($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['reference'])) { + return null; + } + + return $installed['versions'][$packageName]['reference']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. + */ + public static function getInstallPath($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @return array + * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} + */ + public static function getRootPackage() + { + $installed = self::getInstalled(); + + return $installed[0]['root']; + } + + /** + * Returns the raw installed.php data for custom implementations + * + * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. + * @return array[] + * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} + */ + public static function getRawData() + { + @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); + + if (null === self::$installed) { + // 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 = include __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + + return self::$installed; + } + + /** + * Returns the raw data of all installed.php which are currently loaded for custom implementations + * + * @return array[] + * @psalm-return list}> + */ + public static function getAllRawData() + { + return self::getInstalled(); + } + + /** + * Lets you reload the static array from another file + * + * This is only useful for complex integrations in which a project needs to use + * this class but then also needs to execute another project's autoloader in process, + * and wants to ensure both projects have access to their version of installed.php. + * + * A typical case would be PHPUnit, where it would need to make sure it reads all + * the data it needs from this class, then call reload() with + * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure + * the project in which it runs can then also use this class safely, without + * interference between PHPUnit's dependencies and the project's dependencies. + * + * @param array[] $data A vendor/composer/installed.php data set + * @return void + * + * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data + */ + public static function reload($data) + { + self::$installed = $data; + self::$installedByVendor = array(); + } + + /** + * @return array[] + * @psalm-return list}> + */ + private static function getInstalled() + { + if (null === self::$canGetVendors) { + self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); + } + + $installed = array(); + + 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')) { + /** @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'; + $installed[] = self::$installedByVendor[$vendorDir] = $required; + if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { + self::$installed = $installed[count($installed) - 1]; + } + } + } + } + + if (null === self::$installed) { + // 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') { + /** @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(); + } + } + + if (self::$installed !== array()) { + $installed[] = self::$installed; + } + + return $installed; + } +} diff --git a/lib/Google/vendor/composer/autoload_classmap.php b/lib/Google/vendor/composer/autoload_classmap.php index 8441ab833..2bda8e960 100644 --- a/lib/Google/vendor/composer/autoload_classmap.php +++ b/lib/Google/vendor/composer/autoload_classmap.php @@ -2,10 +2,12 @@ // autoload_classmap.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( + 'CURLStringFile' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php', + 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', 'Google_AccessToken_Revoke' => $baseDir . '/src/aliases.php', 'Google_AccessToken_Verify' => $baseDir . '/src/aliases.php', 'Google_AuthHandler_AuthHandlerFactory' => $baseDir . '/src/aliases.php', @@ -26,4 +28,5 @@ 'Google_Task_Retryable' => $baseDir . '/src/aliases.php', 'Google_Task_Runner' => $baseDir . '/src/aliases.php', 'Google_Utils_UriTemplate' => $baseDir . '/src/aliases.php', + 'ReturnTypeWillChange' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php', ); diff --git a/lib/Google/vendor/composer/autoload_files.php b/lib/Google/vendor/composer/autoload_files.php index 2f65642f5..1b96f7179 100644 --- a/lib/Google/vendor/composer/autoload_files.php +++ b/lib/Google/vendor/composer/autoload_files.php @@ -2,15 +2,16 @@ // autoload_files.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', - 'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php', '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', - 'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php', + '23c18046f52bef3eea034657bafda50f' => $vendorDir . '/symfony/polyfill-php81/bootstrap.php', 'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php', + '1f87db08236948d07391152dccb70f04' => $vendorDir . '/google/apiclient-services/autoload.php', + 'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php', 'a8d3953fd9959404dd22d3dfcd0a79f0' => $baseDir . '/src/aliases.php', ); diff --git a/lib/Google/vendor/composer/autoload_namespaces.php b/lib/Google/vendor/composer/autoload_namespaces.php index b7fc0125d..15a2ff3ad 100644 --- a/lib/Google/vendor/composer/autoload_namespaces.php +++ b/lib/Google/vendor/composer/autoload_namespaces.php @@ -2,7 +2,7 @@ // autoload_namespaces.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( diff --git a/lib/Google/vendor/composer/autoload_psr4.php b/lib/Google/vendor/composer/autoload_psr4.php index de2fe3828..8f8c57ddb 100644 --- a/lib/Google/vendor/composer/autoload_psr4.php +++ b/lib/Google/vendor/composer/autoload_psr4.php @@ -2,11 +2,12 @@ // autoload_psr4.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( 'phpseclib3\\' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'), + 'Symfony\\Polyfill\\Php81\\' => array($vendorDir . '/symfony/polyfill-php81'), 'Rize\\' => array($vendorDir . '/rize/uri-template/src/Rize'), 'Ramsey\\Uuid\\' => array($vendorDir . '/ramsey/uuid/src'), 'Ramsey\\Collection\\' => array($vendorDir . '/ramsey/collection/src'), @@ -19,9 +20,9 @@ 'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'), 'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'), 'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'), + 'Google\\Service\\' => array($vendorDir . '/google/apiclient-services/src'), 'Google\\Cloud\\Storage\\' => array($vendorDir . '/google/cloud-storage/src'), 'Google\\Cloud\\Core\\' => array($vendorDir . '/google/cloud-core/src'), - 'Google\\CRC32\\' => array($vendorDir . '/google/crc32/src'), 'Google\\Auth\\' => array($vendorDir . '/google/auth/src'), 'Google\\' => array($baseDir . '/src'), 'Firebase\\JWT\\' => array($vendorDir . '/firebase/php-jwt/src'), diff --git a/lib/Google/vendor/composer/autoload_real.php b/lib/Google/vendor/composer/autoload_real.php index b4f8cfd17..a9a344d5e 100644 --- a/lib/Google/vendor/composer/autoload_real.php +++ b/lib/Google/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit8a18562d3013519ef85187fe20fc0499 +class ComposerAutoloaderInit2cd6126242849aa869f10969652c4467 { private static $loader; @@ -22,52 +22,29 @@ public static function getLoader() return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit8a18562d3013519ef85187fe20fc0499', 'loadClassLoader'), true, true); - self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInit8a18562d3013519ef85187fe20fc0499', 'loadClassLoader')); + require __DIR__ . '/platform_check.php'; - $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); - if ($useStaticLoader) { - require_once __DIR__ . '/autoload_static.php'; + spl_autoload_register(array('ComposerAutoloaderInit2cd6126242849aa869f10969652c4467', 'loadClassLoader'), true, true); + self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); + spl_autoload_unregister(array('ComposerAutoloaderInit2cd6126242849aa869f10969652c4467', 'loadClassLoader')); - call_user_func(\Composer\Autoload\ComposerStaticInit8a18562d3013519ef85187fe20fc0499::getInitializer($loader)); - } else { - $map = require __DIR__ . '/autoload_namespaces.php'; - foreach ($map as $namespace => $path) { - $loader->set($namespace, $path); - } - - $map = require __DIR__ . '/autoload_psr4.php'; - foreach ($map as $namespace => $path) { - $loader->setPsr4($namespace, $path); - } - - $classMap = require __DIR__ . '/autoload_classmap.php'; - if ($classMap) { - $loader->addClassMap($classMap); - } - } + require __DIR__ . '/autoload_static.php'; + call_user_func(\Composer\Autoload\ComposerStaticInit2cd6126242849aa869f10969652c4467::getInitializer($loader)); $loader->register(true); - if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInit8a18562d3013519ef85187fe20fc0499::$files; - } else { - $includeFiles = require __DIR__ . '/autoload_files.php'; - } - foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire8a18562d3013519ef85187fe20fc0499($fileIdentifier, $file); + $filesToLoad = \Composer\Autoload\ComposerStaticInit2cd6126242849aa869f10969652c4467::$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; } } - -function composerRequire8a18562d3013519ef85187fe20fc0499($fileIdentifier, $file) -{ - if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { - require $file; - - $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; - } -} diff --git a/lib/Google/vendor/composer/autoload_static.php b/lib/Google/vendor/composer/autoload_static.php index 5f30bbe99..05dbabeaa 100644 --- a/lib/Google/vendor/composer/autoload_static.php +++ b/lib/Google/vendor/composer/autoload_static.php @@ -4,15 +4,16 @@ namespace Composer\Autoload; -class ComposerStaticInit8a18562d3013519ef85187fe20fc0499 +class ComposerStaticInit2cd6126242849aa869f10969652c4467 { public static $files = array ( '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', - 'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php', '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', - 'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php', + '23c18046f52bef3eea034657bafda50f' => __DIR__ . '/..' . '/symfony/polyfill-php81/bootstrap.php', 'e39a8b23c42d4e1452234d762b03835a' => __DIR__ . '/..' . '/ramsey/uuid/src/functions.php', + '1f87db08236948d07391152dccb70f04' => __DIR__ . '/..' . '/google/apiclient-services/autoload.php', + 'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php', 'a8d3953fd9959404dd22d3dfcd0a79f0' => __DIR__ . '/../..' . '/src/aliases.php', ); @@ -21,6 +22,10 @@ class ComposerStaticInit8a18562d3013519ef85187fe20fc0499 array ( 'phpseclib3\\' => 11, ), + 'S' => + array ( + 'Symfony\\Polyfill\\Php81\\' => 23, + ), 'R' => array ( 'Rize\\' => 5, @@ -44,9 +49,9 @@ class ComposerStaticInit8a18562d3013519ef85187fe20fc0499 'GuzzleHttp\\Psr7\\' => 16, 'GuzzleHttp\\Promise\\' => 19, 'GuzzleHttp\\' => 11, + 'Google\\Service\\' => 15, 'Google\\Cloud\\Storage\\' => 21, 'Google\\Cloud\\Core\\' => 18, - 'Google\\CRC32\\' => 13, 'Google\\Auth\\' => 12, 'Google\\' => 7, ), @@ -65,6 +70,10 @@ class ComposerStaticInit8a18562d3013519ef85187fe20fc0499 array ( 0 => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib', ), + 'Symfony\\Polyfill\\Php81\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-php81', + ), 'Rize\\' => array ( 0 => __DIR__ . '/..' . '/rize/uri-template/src/Rize', @@ -114,6 +123,10 @@ class ComposerStaticInit8a18562d3013519ef85187fe20fc0499 array ( 0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src', ), + 'Google\\Service\\' => + array ( + 0 => __DIR__ . '/..' . '/google/apiclient-services/src', + ), 'Google\\Cloud\\Storage\\' => array ( 0 => __DIR__ . '/..' . '/google/cloud-storage/src', @@ -122,10 +135,6 @@ class ComposerStaticInit8a18562d3013519ef85187fe20fc0499 array ( 0 => __DIR__ . '/..' . '/google/cloud-core/src', ), - 'Google\\CRC32\\' => - array ( - 0 => __DIR__ . '/..' . '/google/crc32/src', - ), 'Google\\Auth\\' => array ( 0 => __DIR__ . '/..' . '/google/auth/src', @@ -145,6 +154,8 @@ class ComposerStaticInit8a18562d3013519ef85187fe20fc0499 ); public static $classMap = array ( + 'CURLStringFile' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php', + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 'Google_AccessToken_Revoke' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_AccessToken_Verify' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_AuthHandler_AuthHandlerFactory' => __DIR__ . '/../..' . '/src/aliases.php', @@ -165,14 +176,15 @@ class ComposerStaticInit8a18562d3013519ef85187fe20fc0499 'Google_Task_Retryable' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_Task_Runner' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_Utils_UriTemplate' => __DIR__ . '/../..' . '/src/aliases.php', + 'ReturnTypeWillChange' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php', ); public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit8a18562d3013519ef85187fe20fc0499::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit8a18562d3013519ef85187fe20fc0499::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit8a18562d3013519ef85187fe20fc0499::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit2cd6126242849aa869f10969652c4467::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit2cd6126242849aa869f10969652c4467::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit2cd6126242849aa869f10969652c4467::$classMap; }, null, ClassLoader::class); } diff --git a/lib/Google/vendor/composer/installed.json b/lib/Google/vendor/composer/installed.json index 11af9a3cc..761f6d17c 100644 --- a/lib/Google/vendor/composer/installed.json +++ b/lib/Google/vendor/composer/installed.json @@ -1,1567 +1,1766 @@ -[ - { - "name": "brick/math", - "version": "0.11.0", - "version_normalized": "0.11.0.0", - "source": { - "type": "git", - "url": "https://github.com/brick/math.git", - "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/0ad82ce168c82ba30d1c01ec86116ab52f589478", - "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478", - "shasum": "" - }, - "require": { - "php": "^8.0" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.2", - "phpunit/phpunit": "^9.0", - "vimeo/psalm": "5.0.0" - }, - "time": "2023-01-15T23:15:59+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Brick\\Math\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Arbitrary-precision arithmetic library", - "keywords": [ - "Arbitrary-precision", - "BigInteger", - "BigRational", - "arithmetic", - "bigdecimal", - "bignum", - "brick", - "math" - ], - "funding": [ - { - "url": "https://github.com/BenMorel", - "type": "github" - } - ] - }, - { - "name": "firebase/php-jwt", - "version": "v6.5.0", - "version_normalized": "6.5.0.0", - "source": { - "type": "git", - "url": "https://github.com/firebase/php-jwt.git", - "reference": "e94e7353302b0c11ec3cfff7180cd0b1743975d2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/e94e7353302b0c11ec3cfff7180cd0b1743975d2", - "reference": "e94e7353302b0c11ec3cfff7180cd0b1743975d2", - "shasum": "" - }, - "require": { - "php": "^7.4||^8.0" - }, - "require-dev": { - "guzzlehttp/guzzle": "^6.5||^7.4", - "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.5", - "psr/cache": "^1.0||^2.0", - "psr/http-client": "^1.0", - "psr/http-factory": "^1.0" - }, - "suggest": { - "ext-sodium": "Support EdDSA (Ed25519) signatures", - "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" - }, - "time": "2023-05-12T15:47:07+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Firebase\\JWT\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Neuman Vong", - "email": "neuman+pear@twilio.com", - "role": "Developer" - }, - { - "name": "Anant Narayanan", - "email": "anant@php.net", - "role": "Developer" - } - ], - "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", - "homepage": "https://github.com/firebase/php-jwt", - "keywords": [ - "jwt", - "php" - ] - }, - { - "name": "google/auth", - "version": "v1.28.0", - "version_normalized": "1.28.0.0", - "source": { - "type": "git", - "url": "https://github.com/googleapis/google-auth-library-php.git", - "reference": "07f7f6305f1b7df32b2acf6e101c1225c839c7ac" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/07f7f6305f1b7df32b2acf6e101c1225c839c7ac", - "reference": "07f7f6305f1b7df32b2acf6e101c1225c839c7ac", - "shasum": "" - }, - "require": { - "firebase/php-jwt": "^6.0", - "guzzlehttp/guzzle": "^6.2.1|^7.0", - "guzzlehttp/psr7": "^2.4.5", - "php": "^7.4||^8.0", - "psr/cache": "^1.0||^2.0||^3.0", - "psr/http-message": "^1.1||^2.0" - }, - "require-dev": { - "guzzlehttp/promises": "^1.3", - "kelvinmo/simplejwt": "0.7.0", - "phpseclib/phpseclib": "^3.0", - "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.0.0", - "sebastian/comparator": ">=1.2.3", - "squizlabs/php_codesniffer": "^3.5" - }, - "suggest": { - "phpseclib/phpseclib": "May be used in place of OpenSSL for signing strings or for token management. Please require version ^2." - }, - "time": "2023-05-11T21:58:18+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Google\\Auth\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "description": "Google Auth Library for PHP", - "homepage": "http://github.com/google/google-auth-library-php", - "keywords": [ - "Authentication", - "google", - "oauth2" - ] - }, - { - "name": "google/cloud-core", - "version": "v1.51.2", - "version_normalized": "1.51.2.0", - "source": { - "type": "git", - "url": "https://github.com/googleapis/google-cloud-php-core.git", - "reference": "85dc48d62143f4bbfaa34c24da95003371de7b79" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-cloud-php-core/zipball/85dc48d62143f4bbfaa34c24da95003371de7b79", - "reference": "85dc48d62143f4bbfaa34c24da95003371de7b79", - "shasum": "" - }, - "require": { - "google/auth": "^1.18", - "guzzlehttp/guzzle": "^5.3|^6.5.7|^7.4.4", - "guzzlehttp/promises": "^1.3", - "guzzlehttp/psr7": "^1.7|^2.0", - "monolog/monolog": "^1.1|^2.0|^3.0", - "php": ">=7.4", - "psr/http-message": "^1.0", - "rize/uri-template": "~0.3" - }, - "require-dev": { - "erusev/parsedown": "^1.6", - "google/cloud-common-protos": "^0.4", - "google/gax": "^1.9", - "opis/closure": "^3", - "phpdocumentor/reflection": "^5.0", - "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.0", - "squizlabs/php_codesniffer": "2.*" - }, - "suggest": { - "opis/closure": "May be used to serialize closures to process jobs in the batch daemon. Please require version ^3.", - "symfony/lock": "Required for the Spanner cached based session pool. Please require the following commit: 3.3.x-dev#1ba6ac9" - }, - "time": "2023-05-05T23:01:42+00:00", - "bin": [ - "bin/google-cloud-batch" - ], - "type": "library", - "extra": { - "component": { - "id": "cloud-core", - "target": "googleapis/google-cloud-php-core.git", - "path": "Core", - "entry": "src/ServiceBuilder.php" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Google\\Cloud\\Core\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "description": "Google Cloud PHP shared dependency, providing functionality useful to all components." - }, - { - "name": "google/cloud-storage", - "version": "v1.31.2", - "version_normalized": "1.31.2.0", - "source": { - "type": "git", - "url": "https://github.com/googleapis/google-cloud-php-storage.git", - "reference": "7fe96d56856cda550b21779bb95a066b264852da" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-cloud-php-storage/zipball/7fe96d56856cda550b21779bb95a066b264852da", - "reference": "7fe96d56856cda550b21779bb95a066b264852da", - "shasum": "" - }, - "require": { - "google/cloud-core": "^1.51.1", - "google/crc32": "^0.2.0", - "php": ">=7.4", - "ramsey/uuid": "^4.2.3" - }, - "require-dev": { - "erusev/parsedown": "^1.6", - "google/cloud-pubsub": "^1.0", - "phpdocumentor/reflection": "^5.0", - "phpseclib/phpseclib": "^2.0||^3.0", - "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.0", - "squizlabs/php_codesniffer": "2.*" - }, - "suggest": { - "google/cloud-pubsub": "May be used to register a topic to receive bucket notifications.", - "phpseclib/phpseclib": "May be used in place of OpenSSL for creating signed Cloud Storage URLs. Please require version ^2." - }, - "time": "2023-05-05T23:01:42+00:00", - "type": "library", - "extra": { - "component": { - "id": "cloud-storage", - "target": "googleapis/google-cloud-php-storage.git", - "path": "Storage", - "entry": "src/StorageClient.php" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Google\\Cloud\\Storage\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "description": "Cloud Storage Client for PHP" - }, - { - "name": "google/crc32", - "version": "v0.2.0", - "version_normalized": "0.2.0.0", - "source": { - "type": "git", - "url": "https://github.com/google/php-crc32.git", - "reference": "948f7945d803dcc1a375152c72f63144c2dadf23" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/google/php-crc32/zipball/948f7945d803dcc1a375152c72f63144c2dadf23", - "reference": "948f7945d803dcc1a375152c72f63144c2dadf23", - "shasum": "" - }, - "require": { - "php": ">=7.4" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "v3.15", - "phpunit/phpunit": "^9" - }, - "time": "2023-04-16T22:44:57+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Google\\CRC32\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Andrew Brampton", - "email": "bramp@google.com" - } - ], - "description": "Various CRC32 implementations", - "homepage": "https://github.com/google/php-crc32" - }, - { - "name": "guzzlehttp/guzzle", - "version": "7.7.0", - "version_normalized": "7.7.0.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "fb7566caccf22d74d1ab270de3551f72a58399f5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/fb7566caccf22d74d1ab270de3551f72a58399f5", - "reference": "fb7566caccf22d74d1ab270de3551f72a58399f5", - "shasum": "" - }, - "require": { - "ext-json": "*", - "guzzlehttp/promises": "^1.5.3 || ^2.0", - "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", - "php": "^7.2.5 || ^8.0", - "psr/http-client": "^1.0", - "symfony/deprecation-contracts": "^2.2 || ^3.0" - }, - "provide": { - "psr/http-client-implementation": "1.0" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.1", - "ext-curl": "*", - "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", - "php-http/message-factory": "^1.1", - "phpunit/phpunit": "^8.5.29 || ^9.5.23", - "psr/log": "^1.1 || ^2.0 || ^3.0" - }, - "suggest": { - "ext-curl": "Required for CURL handler support", - "ext-intl": "Required for Internationalized Domain Name (IDN) support", - "psr/log": "Required for using the Log middleware" - }, - "time": "2023-05-21T14:04:53+00:00", - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "GuzzleHttp\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Jeremy Lindblom", - "email": "jeremeamia@gmail.com", - "homepage": "https://github.com/jeremeamia" - }, - { - "name": "George Mponos", - "email": "gmponos@gmail.com", - "homepage": "https://github.com/gmponos" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://github.com/sagikazarmark" - }, - { - "name": "Tobias Schultze", - "email": "webmaster@tubo-world.de", - "homepage": "https://github.com/Tobion" - } - ], - "description": "Guzzle is a PHP HTTP client library", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "psr-18", - "psr-7", - "rest", - "web service" - ], - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://github.com/Nyholm", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", - "type": "tidelift" - } - ] - }, - { - "name": "guzzlehttp/promises", - "version": "1.5.3", - "version_normalized": "1.5.3.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/67ab6e18aaa14d753cc148911d273f6e6cb6721e", - "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e", - "shasum": "" - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.1" - }, - "time": "2023-05-21T12:31:43+00:00", - "type": "library", - "installation-source": "source", - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "GuzzleHttp\\Promise\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - }, - { - "name": "Tobias Schultze", - "email": "webmaster@tubo-world.de", - "homepage": "https://github.com/Tobion" - } - ], - "description": "Guzzle promises library", - "keywords": [ - "promise" - ], - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://github.com/Nyholm", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", - "type": "tidelift" - } - ] - }, - { - "name": "guzzlehttp/psr7", - "version": "2.5.0", - "version_normalized": "2.5.0.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "b635f279edd83fc275f822a1188157ffea568ff6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/b635f279edd83fc275f822a1188157ffea568ff6", - "reference": "b635f279edd83fc275f822a1188157ffea568ff6", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0", - "psr/http-factory": "^1.0", - "psr/http-message": "^1.1 || ^2.0", - "ralouphie/getallheaders": "^3.0" - }, - "provide": { - "psr/http-factory-implementation": "1.0", - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.1", - "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.29 || ^9.5.23" - }, - "suggest": { - "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" - }, - "time": "2023-04-17T16:11:26+00:00", - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "George Mponos", - "email": "gmponos@gmail.com", - "homepage": "https://github.com/gmponos" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://github.com/sagikazarmark" - }, - { - "name": "Tobias Schultze", - "email": "webmaster@tubo-world.de", - "homepage": "https://github.com/Tobion" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://sagikazarmark.hu" - } - ], - "description": "PSR-7 message implementation that also provides common utility methods", - "keywords": [ - "http", - "message", - "psr-7", - "request", - "response", - "stream", - "uri", - "url" - ], - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://github.com/Nyholm", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", - "type": "tidelift" - } - ] - }, - { - "name": "monolog/monolog", - "version": "2.9.1", - "version_normalized": "2.9.1.0", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/monolog.git", - "reference": "f259e2b15fb95494c83f52d3caad003bbf5ffaa1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f259e2b15fb95494c83f52d3caad003bbf5ffaa1", - "reference": "f259e2b15fb95494c83f52d3caad003bbf5ffaa1", - "shasum": "" - }, - "require": { - "php": ">=7.2", - "psr/log": "^1.0.1 || ^2.0 || ^3.0" - }, - "provide": { - "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0" - }, - "require-dev": { - "aws/aws-sdk-php": "^2.4.9 || ^3.0", - "doctrine/couchdb": "~1.0@dev", - "elasticsearch/elasticsearch": "^7 || ^8", - "ext-json": "*", - "graylog2/gelf-php": "^1.4.2 || ^2@dev", - "guzzlehttp/guzzle": "^7.4", - "guzzlehttp/psr7": "^2.2", - "mongodb/mongodb": "^1.8", - "php-amqplib/php-amqplib": "~2.4 || ^3", - "phpspec/prophecy": "^1.15", - "phpstan/phpstan": "^0.12.91", - "phpunit/phpunit": "^8.5.14", - "predis/predis": "^1.1 || ^2.0", - "rollbar/rollbar": "^1.3 || ^2 || ^3", - "ruflin/elastica": "^7", - "swiftmailer/swiftmailer": "^5.3|^6.0", - "symfony/mailer": "^5.4 || ^6", - "symfony/mime": "^5.4 || ^6" - }, - "suggest": { - "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", - "doctrine/couchdb": "Allow sending log messages to a CouchDB server", - "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", - "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", - "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", - "ext-mbstring": "Allow to work properly with unicode symbols", - "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", - "ext-openssl": "Required to send log messages using SSL", - "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", - "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", - "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", - "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", - "rollbar/rollbar": "Allow sending log messages to Rollbar", - "ruflin/elastica": "Allow sending log messages to an Elastic Search server" - }, - "time": "2023-02-06T13:44:46+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Monolog\\": "src/Monolog" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "https://seld.be" - } - ], - "description": "Sends your logs to files, sockets, inboxes, databases and various web services", - "homepage": "https://github.com/Seldaek/monolog", - "keywords": [ - "log", - "logging", - "psr-3" - ], - "funding": [ - { - "url": "https://github.com/Seldaek", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", - "type": "tidelift" - } - ] - }, - { - "name": "paragonie/constant_time_encoding", - "version": "v2.6.3", - "version_normalized": "2.6.3.0", - "source": { - "type": "git", - "url": "https://github.com/paragonie/constant_time_encoding.git", - "reference": "58c3f47f650c94ec05a151692652a868995d2938" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/58c3f47f650c94ec05a151692652a868995d2938", - "reference": "58c3f47f650c94ec05a151692652a868995d2938", - "shasum": "" - }, - "require": { - "php": "^7|^8" - }, - "require-dev": { - "phpunit/phpunit": "^6|^7|^8|^9", - "vimeo/psalm": "^1|^2|^3|^4" - }, - "time": "2022-06-14T06:56:20+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "ParagonIE\\ConstantTime\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com", - "role": "Maintainer" - }, - { - "name": "Steve 'Sc00bz' Thomas", - "email": "steve@tobtu.com", - "homepage": "https://www.tobtu.com", - "role": "Original Developer" - } - ], - "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", - "keywords": [ - "base16", - "base32", - "base32_decode", - "base32_encode", - "base64", - "base64_decode", - "base64_encode", - "bin2hex", - "encoding", - "hex", - "hex2bin", - "rfc4648" - ] - }, - { - "name": "paragonie/random_compat", - "version": "v9.99.100", - "version_normalized": "9.99.100.0", - "source": { - "type": "git", - "url": "https://github.com/paragonie/random_compat.git", - "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", - "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", - "shasum": "" - }, - "require": { - "php": ">= 7" - }, - "require-dev": { - "phpunit/phpunit": "4.*|5.*", - "vimeo/psalm": "^1" - }, - "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." - }, - "time": "2020-10-15T08:29:30+00:00", - "type": "library", - "installation-source": "dist", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" - } - ], - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", - "keywords": [ - "csprng", - "polyfill", - "pseudorandom", - "random" - ] - }, - { - "name": "phpseclib/phpseclib", - "version": "3.0.19", - "version_normalized": "3.0.19.0", - "source": { - "type": "git", - "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "cc181005cf548bfd8a4896383bb825d859259f95" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/cc181005cf548bfd8a4896383bb825d859259f95", - "reference": "cc181005cf548bfd8a4896383bb825d859259f95", - "shasum": "" - }, - "require": { - "paragonie/constant_time_encoding": "^1|^2", - "paragonie/random_compat": "^1.4|^2.0|^9.99.99", - "php": ">=5.6.1" - }, - "require-dev": { - "phpunit/phpunit": "*" - }, - "suggest": { - "ext-dom": "Install the DOM extension to load XML formatted public keys.", - "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", - "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", - "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", - "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." - }, - "time": "2023-03-05T17:13:09+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "files": [ - "phpseclib/bootstrap.php" - ], - "psr-4": { - "phpseclib3\\": "phpseclib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jim Wigginton", - "email": "terrafrost@php.net", - "role": "Lead Developer" - }, - { - "name": "Patrick Monnerat", - "email": "pm@datasphere.ch", - "role": "Developer" - }, - { - "name": "Andreas Fischer", - "email": "bantu@phpbb.com", - "role": "Developer" - }, - { - "name": "Hans-Jürgen Petrich", - "email": "petrich@tronic-media.com", - "role": "Developer" - }, - { - "name": "Graham Campbell", - "email": "graham@alt-three.com", - "role": "Developer" - } - ], - "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", - "homepage": "http://phpseclib.sourceforge.net", - "keywords": [ - "BigInteger", - "aes", - "asn.1", - "asn1", - "blowfish", - "crypto", - "cryptography", - "encryption", - "rsa", - "security", - "sftp", - "signature", - "signing", - "ssh", - "twofish", - "x.509", - "x509" - ], - "funding": [ - { - "url": "https://github.com/terrafrost", - "type": "github" - }, - { - "url": "https://www.patreon.com/phpseclib", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", - "type": "tidelift" - } - ] - }, - { - "name": "psr/cache", - "version": "2.0.0", - "version_normalized": "2.0.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/cache.git", - "reference": "213f9dbc5b9bfbc4f8db86d2838dc968752ce13b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/213f9dbc5b9bfbc4f8db86d2838dc968752ce13b", - "reference": "213f9dbc5b9bfbc4f8db86d2838dc968752ce13b", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "time": "2021-02-03T23:23:37+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "source", - "autoload": { - "psr-4": { - "Psr\\Cache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for caching libraries", - "keywords": [ - "cache", - "psr", - "psr-6" - ] - }, - { - "name": "psr/http-client", - "version": "1.0.2", - "version_normalized": "1.0.2.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-client.git", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0", - "psr/http-message": "^1.0 || ^2.0" - }, - "time": "2023-04-10T20:12:12+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Http\\Client\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP clients", - "homepage": "https://github.com/php-fig/http-client", - "keywords": [ - "http", - "http-client", - "psr", - "psr-18" - ] - }, - { - "name": "psr/http-factory", - "version": "1.0.2", - "version_normalized": "1.0.2.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-factory.git", - "reference": "e616d01114759c4c489f93b099585439f795fe35" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", - "reference": "e616d01114759c4c489f93b099585439f795fe35", - "shasum": "" - }, - "require": { - "php": ">=7.0.0", - "psr/http-message": "^1.0 || ^2.0" - }, - "time": "2023-04-10T20:10:41+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interfaces for PSR-7 HTTP message factories", - "keywords": [ - "factory", - "http", - "message", - "psr", - "psr-17", - "psr-7", - "request", - "response" - ] - }, - { - "name": "psr/http-message", - "version": "1.1", - "version_normalized": "1.1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", - "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "time": "2023-04-04T09:50:52+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ] - }, - { - "name": "psr/log", - "version": "1.1.4", - "version_normalized": "1.1.4.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "time": "2021-05-03T11:20:27+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Log\\": "Psr/Log/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ] - }, - { - "name": "ralouphie/getallheaders", - "version": "3.0.3", - "version_normalized": "3.0.3.0", - "source": { - "type": "git", - "url": "https://github.com/ralouphie/getallheaders.git", - "reference": "120b605dfeb996808c31b6477290a714d356e822" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", - "reference": "120b605dfeb996808c31b6477290a714d356e822", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.1", - "phpunit/phpunit": "^5 || ^6.5" - }, - "time": "2019-03-08T08:55:37+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "files": [ - "src/getallheaders.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ralph Khattar", - "email": "ralph.khattar@gmail.com" - } - ], - "description": "A polyfill for getallheaders." - }, - { - "name": "ramsey/collection", - "version": "2.0.0", - "version_normalized": "2.0.0.0", - "source": { - "type": "git", - "url": "https://github.com/ramsey/collection.git", - "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", - "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", - "shasum": "" - }, - "require": { - "php": "^8.1" - }, - "require-dev": { - "captainhook/plugin-composer": "^5.3", - "ergebnis/composer-normalize": "^2.28.3", - "fakerphp/faker": "^1.21", - "hamcrest/hamcrest-php": "^2.0", - "jangregor/phpstan-prophecy": "^1.0", - "mockery/mockery": "^1.5", - "php-parallel-lint/php-console-highlighter": "^1.0", - "php-parallel-lint/php-parallel-lint": "^1.3", - "phpcsstandards/phpcsutils": "^1.0.0-rc1", - "phpspec/prophecy-phpunit": "^2.0", - "phpstan/extension-installer": "^1.2", - "phpstan/phpstan": "^1.9", - "phpstan/phpstan-mockery": "^1.1", - "phpstan/phpstan-phpunit": "^1.3", - "phpunit/phpunit": "^9.5", - "psalm/plugin-mockery": "^1.1", - "psalm/plugin-phpunit": "^0.18.4", - "ramsey/coding-standard": "^2.0.3", - "ramsey/conventional-commits": "^1.3", - "vimeo/psalm": "^5.4" - }, - "time": "2022-12-31T21:50:55+00:00", - "type": "library", - "extra": { - "captainhook": { - "force-install": true - }, - "ramsey/conventional-commits": { - "configFile": "conventional-commits.json" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Ramsey\\Collection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ben Ramsey", - "email": "ben@benramsey.com", - "homepage": "https://benramsey.com" - } - ], - "description": "A PHP library for representing and manipulating collections.", - "keywords": [ - "array", - "collection", - "hash", - "map", - "queue", - "set" - ], - "funding": [ - { - "url": "https://github.com/ramsey", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/ramsey/collection", - "type": "tidelift" - } - ] - }, - { - "name": "ramsey/uuid", - "version": "4.7.4", - "version_normalized": "4.7.4.0", - "source": { - "type": "git", - "url": "https://github.com/ramsey/uuid.git", - "reference": "60a4c63ab724854332900504274f6150ff26d286" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/60a4c63ab724854332900504274f6150ff26d286", - "reference": "60a4c63ab724854332900504274f6150ff26d286", - "shasum": "" - }, - "require": { - "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11", - "ext-json": "*", - "php": "^8.0", - "ramsey/collection": "^1.2 || ^2.0" - }, - "replace": { - "rhumsaa/uuid": "self.version" - }, - "require-dev": { - "captainhook/captainhook": "^5.10", - "captainhook/plugin-composer": "^5.3", - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", - "doctrine/annotations": "^1.8", - "ergebnis/composer-normalize": "^2.15", - "mockery/mockery": "^1.3", - "paragonie/random-lib": "^2", - "php-mock/php-mock": "^2.2", - "php-mock/php-mock-mockery": "^1.3", - "php-parallel-lint/php-parallel-lint": "^1.1", - "phpbench/phpbench": "^1.0", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-mockery": "^1.1", - "phpstan/phpstan-phpunit": "^1.1", - "phpunit/phpunit": "^8.5 || ^9", - "ramsey/composer-repl": "^1.4", - "slevomat/coding-standard": "^8.4", - "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "^4.9" - }, - "suggest": { - "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", - "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", - "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", - "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", - "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." - }, - "time": "2023-04-15T23:01:58+00:00", - "type": "library", - "extra": { - "captainhook": { - "force-install": true - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "Ramsey\\Uuid\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", - "keywords": [ - "guid", - "identifier", - "uuid" - ], - "funding": [ - { - "url": "https://github.com/ramsey", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", - "type": "tidelift" - } - ] - }, - { - "name": "rize/uri-template", - "version": "0.3.5", - "version_normalized": "0.3.5.0", - "source": { - "type": "git", - "url": "https://github.com/rize/UriTemplate.git", - "reference": "5ed4ba8ea34af84485dea815d4b6b620794d1168" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/rize/UriTemplate/zipball/5ed4ba8ea34af84485dea815d4b6b620794d1168", - "reference": "5ed4ba8ea34af84485dea815d4b6b620794d1168", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.8.36" - }, - "time": "2022-10-12T17:22:51+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Rize\\": "src/Rize" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marut K", - "homepage": "http://twitter.com/rezigned" - } - ], - "description": "PHP URI Template (RFC 6570) supports both expansion & extraction", - "keywords": [ - "RFC 6570", - "template", - "uri" - ], - "funding": [ - { - "url": "https://www.paypal.me/rezigned", - "type": "custom" - }, - { - "url": "https://github.com/rezigned", - "type": "github" - }, - { - "url": "https://opencollective.com/rize-uri-template", - "type": "open_collective" - } - ] - }, - { - "name": "symfony/deprecation-contracts", - "version": "v3.2.1", - "version_normalized": "3.2.1.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e", - "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "time": "2023-03-01T10:25:55+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.3-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "function.php" - ] - }, - "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": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "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" - } - ] - } -] +{ + "packages": [ + { + "name": "brick/math", + "version": "0.11.0", + "version_normalized": "0.11.0.0", + "source": { + "type": "git", + "url": "https://github.com/brick/math.git", + "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/brick/math/zipball/0ad82ce168c82ba30d1c01ec86116ab52f589478", + "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^9.0", + "vimeo/psalm": "5.0.0" + }, + "time": "2023-01-15T23:15:59+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Brick\\Math\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Arbitrary-precision arithmetic library", + "keywords": [ + "Arbitrary-precision", + "BigInteger", + "BigRational", + "arithmetic", + "bigdecimal", + "bignum", + "brick", + "math" + ], + "support": { + "issues": "https://github.com/brick/math/issues", + "source": "https://github.com/brick/math/tree/0.11.0" + }, + "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + } + ], + "install-path": "../brick/math" + }, + { + "name": "firebase/php-jwt", + "version": "v6.10.0", + "version_normalized": "6.10.0.0", + "source": { + "type": "git", + "url": "https://github.com/firebase/php-jwt.git", + "reference": "a49db6f0a5033aef5143295342f1c95521b075ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/a49db6f0a5033aef5143295342f1c95521b075ff", + "reference": "a49db6f0a5033aef5143295342f1c95521b075ff", + "shasum": "" + }, + "require": { + "php": "^7.4||^8.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^6.5||^7.4", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "psr/cache": "^1.0||^2.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0" + }, + "suggest": { + "ext-sodium": "Support EdDSA (Ed25519) signatures", + "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" + }, + "time": "2023-12-01T16:26:39+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Firebase\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt", + "keywords": [ + "jwt", + "php" + ], + "support": { + "issues": "https://github.com/firebase/php-jwt/issues", + "source": "https://github.com/firebase/php-jwt/tree/v6.10.0" + }, + "install-path": "../firebase/php-jwt" + }, + { + "name": "google/apiclient-services", + "version": "v0.323.0", + "version_normalized": "0.323.0.0", + "source": { + "type": "git", + "url": "https://github.com/googleapis/google-api-php-client-services.git", + "reference": "d5497d30ddfafe7592102ca48bedaf222a4ca7a6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/d5497d30ddfafe7592102ca48bedaf222a4ca7a6", + "reference": "d5497d30ddfafe7592102ca48bedaf222a4ca7a6", + "shasum": "" + }, + "require": { + "php": "^7.4||^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7||^8.5.13" + }, + "time": "2023-11-06T01:08:38+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "autoload.php" + ], + "psr-4": { + "Google\\Service\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "Client library for Google APIs", + "homepage": "http://developers.google.com/api-client-library/php", + "keywords": [ + "google" + ], + "support": { + "issues": "https://github.com/googleapis/google-api-php-client-services/issues", + "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.323.0" + }, + "install-path": "../google/apiclient-services" + }, + { + "name": "google/auth", + "version": "v1.33.0", + "version_normalized": "1.33.0.0", + "source": { + "type": "git", + "url": "https://github.com/googleapis/google-auth-library-php.git", + "reference": "682dc6c30bb509953c9e43bb0960d901582da00b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/682dc6c30bb509953c9e43bb0960d901582da00b", + "reference": "682dc6c30bb509953c9e43bb0960d901582da00b", + "shasum": "" + }, + "require": { + "firebase/php-jwt": "^6.0", + "guzzlehttp/guzzle": "^6.2.1|^7.0", + "guzzlehttp/psr7": "^2.4.5", + "php": "^7.4||^8.0", + "psr/cache": "^1.0||^2.0||^3.0", + "psr/http-message": "^1.1||^2.0" + }, + "require-dev": { + "guzzlehttp/promises": "^2.0", + "kelvinmo/simplejwt": "0.7.1", + "phpseclib/phpseclib": "^3.0", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.0.0", + "sebastian/comparator": ">=1.2.3", + "squizlabs/php_codesniffer": "^3.5" + }, + "suggest": { + "phpseclib/phpseclib": "May be used in place of OpenSSL for signing strings or for token management. Please require version ^2." + }, + "time": "2023-11-30T15:49:27+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Google\\Auth\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "Google Auth Library for PHP", + "homepage": "http://github.com/google/google-auth-library-php", + "keywords": [ + "Authentication", + "google", + "oauth2" + ], + "support": { + "docs": "https://googleapis.github.io/google-auth-library-php/main/", + "issues": "https://github.com/googleapis/google-auth-library-php/issues", + "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.33.0" + }, + "install-path": "../google/auth" + }, + { + "name": "google/cloud-core", + "version": "v1.52.10", + "version_normalized": "1.52.10.0", + "source": { + "type": "git", + "url": "https://github.com/googleapis/google-cloud-php-core.git", + "reference": "5e34556498ecadee2161402fd1024bec7ce33186" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/googleapis/google-cloud-php-core/zipball/5e34556498ecadee2161402fd1024bec7ce33186", + "reference": "5e34556498ecadee2161402fd1024bec7ce33186", + "shasum": "" + }, + "require": { + "google/auth": "^1.18", + "guzzlehttp/guzzle": "^6.5.8|^7.4.4", + "guzzlehttp/promises": "^1.4||^2.0", + "guzzlehttp/psr7": "^1.7|^2.0", + "monolog/monolog": "^1.1|^2.0|^3.0", + "php": ">=7.4", + "psr/http-message": "^1.0|^2.0", + "rize/uri-template": "~0.3" + }, + "require-dev": { + "erusev/parsedown": "^1.6", + "google/cloud-common-protos": "^0.4", + "google/gax": "^1.24.0", + "opis/closure": "^3", + "phpdocumentor/reflection": "^5.0", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.0", + "squizlabs/php_codesniffer": "2.*" + }, + "suggest": { + "opis/closure": "May be used to serialize closures to process jobs in the batch daemon. Please require version ^3.", + "symfony/lock": "Required for the Spanner cached based session pool. Please require the following commit: 3.3.x-dev#1ba6ac9" + }, + "time": "2023-12-08T22:36:35+00:00", + "bin": [ + "bin/google-cloud-batch" + ], + "type": "library", + "extra": { + "component": { + "id": "cloud-core", + "target": "googleapis/google-cloud-php-core.git", + "path": "Core", + "entry": "src/ServiceBuilder.php" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Google\\Cloud\\Core\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "Google Cloud PHP shared dependency, providing functionality useful to all components.", + "support": { + "source": "https://github.com/googleapis/google-cloud-php-core/tree/v1.52.10" + }, + "install-path": "../google/cloud-core" + }, + { + "name": "google/cloud-storage", + "version": "v1.36.0", + "version_normalized": "1.36.0.0", + "source": { + "type": "git", + "url": "https://github.com/googleapis/google-cloud-php-storage.git", + "reference": "94215228fd03e548590134d1e521a34ec727460c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/googleapis/google-cloud-php-storage/zipball/94215228fd03e548590134d1e521a34ec727460c", + "reference": "94215228fd03e548590134d1e521a34ec727460c", + "shasum": "" + }, + "require": { + "google/cloud-core": "^1.52.7", + "php": ">=7.4", + "ramsey/uuid": "^4.2.3" + }, + "require-dev": { + "erusev/parsedown": "^1.6", + "google/cloud-pubsub": "^1.0", + "phpdocumentor/reflection": "^5.0", + "phpseclib/phpseclib": "^2.0||^3.0", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.0", + "squizlabs/php_codesniffer": "2.*" + }, + "suggest": { + "google/cloud-pubsub": "May be used to register a topic to receive bucket notifications.", + "phpseclib/phpseclib": "May be used in place of OpenSSL for creating signed Cloud Storage URLs. Please require version ^2." + }, + "time": "2023-12-08T22:36:35+00:00", + "type": "library", + "extra": { + "component": { + "id": "cloud-storage", + "target": "googleapis/google-cloud-php-storage.git", + "path": "Storage", + "entry": "src/StorageClient.php" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Google\\Cloud\\Storage\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "Cloud Storage Client for PHP", + "support": { + "source": "https://github.com/googleapis/google-cloud-php-storage/tree/v1.36.0" + }, + "install-path": "../google/cloud-storage" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.8.1", + "version_normalized": "7.8.1.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104", + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5.3 || ^2.0.1", + "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-curl": "*", + "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "time": "2023-12-03T20:35:24+00:00", + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.8.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "install-path": "../guzzlehttp/guzzle" + }, + { + "name": "guzzlehttp/promises", + "version": "2.0.2", + "version_normalized": "2.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223", + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" + }, + "time": "2023-12-03T20:19:20+00:00", + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "install-path": "../guzzlehttp/promises" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.6.2", + "version_normalized": "2.6.2.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "time": "2023-12-03T20:05:35+00:00", + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.6.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "install-path": "../guzzlehttp/psr7" + }, + { + "name": "monolog/monolog", + "version": "2.9.2", + "version_normalized": "2.9.2.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "437cb3628f4cf6042cc10ae97fc2b8472e48ca1f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/437cb3628f4cf6042cc10ae97fc2b8472e48ca1f", + "reference": "437cb3628f4cf6042cc10ae97fc2b8472e48ca1f", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9 || ^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", + "graylog2/gelf-php": "^1.4.2 || ^2@dev", + "guzzlehttp/guzzle": "^7.4", + "guzzlehttp/psr7": "^2.2", + "mongodb/mongodb": "^1.8", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "phpspec/prophecy": "^1.15", + "phpstan/phpstan": "^0.12.91", + "phpunit/phpunit": "^8.5.14", + "predis/predis": "^1.1 || ^2.0", + "rollbar/rollbar": "^1.3 || ^2 || ^3", + "ruflin/elastica": "^7", + "swiftmailer/swiftmailer": "^5.3|^6.0", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "time": "2023-10-27T15:25:26+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/2.9.2" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "install-path": "../monolog/monolog" + }, + { + "name": "paragonie/constant_time_encoding", + "version": "v2.6.3", + "version_normalized": "2.6.3.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "58c3f47f650c94ec05a151692652a868995d2938" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/58c3f47f650c94ec05a151692652a868995d2938", + "reference": "58c3f47f650c94ec05a151692652a868995d2938", + "shasum": "" + }, + "require": { + "php": "^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^6|^7|^8|^9", + "vimeo/psalm": "^1|^2|^3|^4" + }, + "time": "2022-06-14T06:56:20+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "install-path": "../paragonie/constant_time_encoding" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "version_normalized": "9.99.100.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "time": "2020-10-15T08:29:30+00:00", + "type": "library", + "installation-source": "dist", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "install-path": "../paragonie/random_compat" + }, + { + "name": "phpseclib/phpseclib", + "version": "3.0.37", + "version_normalized": "3.0.37.0", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "cfa2013d0f68c062055180dd4328cc8b9d1f30b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/cfa2013d0f68c062055180dd4328cc8b9d1f30b8", + "reference": "cfa2013d0f68c062055180dd4328cc8b9d1f30b8", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1|^2", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-dom": "Install the DOM extension to load XML formatted public keys.", + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "time": "2024-03-03T02:14:58+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.37" + }, + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "install-path": "../phpseclib/phpseclib" + }, + { + "name": "psr/cache", + "version": "2.0.0", + "version_normalized": "2.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "213f9dbc5b9bfbc4f8db86d2838dc968752ce13b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/213f9dbc5b9bfbc4f8db86d2838dc968752ce13b", + "reference": "213f9dbc5b9bfbc4f8db86d2838dc968752ce13b", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "time": "2021-02-03T23:23:37+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/2.0.0" + }, + "install-path": "../psr/cache" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "version_normalized": "1.0.3.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "time": "2023-09-23T14:17:50+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "install-path": "../psr/http-client" + }, + { + "name": "psr/http-factory", + "version": "1.0.2", + "version_normalized": "1.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "e616d01114759c4c489f93b099585439f795fe35" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "time": "2023-04-10T20:10:41+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/1.0.2" + }, + "install-path": "../psr/http-factory" + }, + { + "name": "psr/http-message", + "version": "2.0", + "version_normalized": "2.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "time": "2023-04-04T09:54:51+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "install-path": "../psr/http-message" + }, + { + "name": "psr/log", + "version": "1.1.4", + "version_normalized": "1.1.4.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2021-05-03T11:20:27+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "install-path": "../psr/log" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "version_normalized": "3.0.3.0", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "time": "2019-03-08T08:55:37+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "install-path": "../ralouphie/getallheaders" + }, + { + "name": "ramsey/collection", + "version": "1.3.0", + "version_normalized": "1.3.0.0", + "source": { + "type": "git", + "url": "https://github.com/ramsey/collection.git", + "reference": "ad7475d1c9e70b190ecffc58f2d989416af339b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/collection/zipball/ad7475d1c9e70b190ecffc58f2d989416af339b4", + "reference": "ad7475d1c9e70b190ecffc58f2d989416af339b4", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "symfony/polyfill-php81": "^1.23" + }, + "require-dev": { + "captainhook/plugin-composer": "^5.3", + "ergebnis/composer-normalize": "^2.28.3", + "fakerphp/faker": "^1.21", + "hamcrest/hamcrest-php": "^2.0", + "jangregor/phpstan-prophecy": "^1.0", + "mockery/mockery": "^1.5", + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpcsstandards/phpcsutils": "^1.0.0-rc1", + "phpspec/prophecy-phpunit": "^2.0", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5", + "psalm/plugin-mockery": "^1.1", + "psalm/plugin-phpunit": "^0.18.4", + "ramsey/coding-standard": "^2.0.3", + "ramsey/conventional-commits": "^1.3", + "vimeo/psalm": "^5.4" + }, + "time": "2022-12-27T19:12:24+00:00", + "type": "library", + "extra": { + "captainhook": { + "force-install": true + }, + "ramsey/conventional-commits": { + "configFile": "conventional-commits.json" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Ramsey\\Collection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "A PHP library for representing and manipulating collections.", + "keywords": [ + "array", + "collection", + "hash", + "map", + "queue", + "set" + ], + "support": { + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/1.3.0" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/collection", + "type": "tidelift" + } + ], + "install-path": "../ramsey/collection" + }, + { + "name": "ramsey/uuid", + "version": "4.7.5", + "version_normalized": "4.7.5.0", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e", + "reference": "5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e", + "shasum": "" + }, + "require": { + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11", + "ext-json": "*", + "php": "^8.0", + "ramsey/collection": "^1.2 || ^2.0" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "captainhook/captainhook": "^5.10", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "doctrine/annotations": "^1.8", + "ergebnis/composer-normalize": "^2.15", + "mockery/mockery": "^1.3", + "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.2", + "php-mock/php-mock-mockery": "^1.3", + "php-parallel-lint/php-parallel-lint": "^1.1", + "phpbench/phpbench": "^1.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^8.5 || ^9", + "ramsey/composer-repl": "^1.4", + "slevomat/coding-standard": "^8.4", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.9" + }, + "suggest": { + "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", + "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "time": "2023-11-08T05:53:05+00:00", + "type": "library", + "extra": { + "captainhook": { + "force-install": true + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "source": "https://github.com/ramsey/uuid/tree/4.7.5" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", + "type": "tidelift" + } + ], + "install-path": "../ramsey/uuid" + }, + { + "name": "rize/uri-template", + "version": "0.3.5", + "version_normalized": "0.3.5.0", + "source": { + "type": "git", + "url": "https://github.com/rize/UriTemplate.git", + "reference": "5ed4ba8ea34af84485dea815d4b6b620794d1168" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rize/UriTemplate/zipball/5ed4ba8ea34af84485dea815d4b6b620794d1168", + "reference": "5ed4ba8ea34af84485dea815d4b6b620794d1168", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8.36" + }, + "time": "2022-10-12T17:22:51+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Rize\\": "src/Rize" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marut K", + "homepage": "http://twitter.com/rezigned" + } + ], + "description": "PHP URI Template (RFC 6570) supports both expansion & extraction", + "keywords": [ + "RFC 6570", + "template", + "uri" + ], + "support": { + "issues": "https://github.com/rize/UriTemplate/issues", + "source": "https://github.com/rize/UriTemplate/tree/0.3.5" + }, + "funding": [ + { + "url": "https://www.paypal.me/rezigned", + "type": "custom" + }, + { + "url": "https://github.com/rezigned", + "type": "github" + }, + { + "url": "https://opencollective.com/rize-uri-template", + "type": "open_collective" + } + ], + "install-path": "../rize/uri-template" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.0.2", + "version_normalized": "3.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", + "shasum": "" + }, + "require": { + "php": ">=8.0.2" + }, + "time": "2022-01-02T09:55:41+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "function.php" + ] + }, + "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": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.2" + }, + "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/deprecation-contracts" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.28.0", + "version_normalized": "1.28.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/7581cd600fa9fd681b797d00b02f068e2f13263b", + "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "time": "2023-01-26T09:26:14+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "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 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.28.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-php81" + } + ], + "dev": false, + "dev-package-names": [] +} diff --git a/lib/Google/vendor/composer/installed.php b/lib/Google/vendor/composer/installed.php new file mode 100644 index 000000000..2b0615279 --- /dev/null +++ b/lib/Google/vendor/composer/installed.php @@ -0,0 +1,269 @@ + array( + 'name' => 'google/apiclient', + 'pretty_version' => 'dev-latest', + 'version' => 'dev-latest', + 'reference' => 'cb005f7d32cc2da68e63ac4cc39bbd53a556d581', + 'type' => 'library', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev' => false, + ), + 'versions' => array( + 'brick/math' => array( + 'pretty_version' => '0.11.0', + 'version' => '0.11.0.0', + 'reference' => '0ad82ce168c82ba30d1c01ec86116ab52f589478', + 'type' => 'library', + 'install_path' => __DIR__ . '/../brick/math', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'firebase/php-jwt' => array( + 'pretty_version' => 'v6.10.0', + 'version' => '6.10.0.0', + 'reference' => 'a49db6f0a5033aef5143295342f1c95521b075ff', + 'type' => 'library', + 'install_path' => __DIR__ . '/../firebase/php-jwt', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'google/apiclient' => array( + 'pretty_version' => 'dev-latest', + 'version' => 'dev-latest', + 'reference' => 'cb005f7d32cc2da68e63ac4cc39bbd53a556d581', + 'type' => 'library', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'google/apiclient-services' => array( + 'pretty_version' => 'v0.323.0', + 'version' => '0.323.0.0', + 'reference' => 'd5497d30ddfafe7592102ca48bedaf222a4ca7a6', + 'type' => 'library', + 'install_path' => __DIR__ . '/../google/apiclient-services', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'google/auth' => array( + 'pretty_version' => 'v1.33.0', + 'version' => '1.33.0.0', + 'reference' => '682dc6c30bb509953c9e43bb0960d901582da00b', + 'type' => 'library', + 'install_path' => __DIR__ . '/../google/auth', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'google/cloud-core' => array( + 'pretty_version' => 'v1.52.10', + 'version' => '1.52.10.0', + 'reference' => '5e34556498ecadee2161402fd1024bec7ce33186', + 'type' => 'library', + 'install_path' => __DIR__ . '/../google/cloud-core', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'google/cloud-storage' => array( + 'pretty_version' => 'v1.36.0', + 'version' => '1.36.0.0', + 'reference' => '94215228fd03e548590134d1e521a34ec727460c', + 'type' => 'library', + 'install_path' => __DIR__ . '/../google/cloud-storage', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'guzzlehttp/guzzle' => array( + 'pretty_version' => '7.8.1', + 'version' => '7.8.1.0', + 'reference' => '41042bc7ab002487b876a0683fc8dce04ddce104', + 'type' => 'library', + 'install_path' => __DIR__ . '/../guzzlehttp/guzzle', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'guzzlehttp/promises' => array( + 'pretty_version' => '2.0.2', + 'version' => '2.0.2.0', + 'reference' => 'bbff78d96034045e58e13dedd6ad91b5d1253223', + 'type' => 'library', + 'install_path' => __DIR__ . '/../guzzlehttp/promises', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'guzzlehttp/psr7' => array( + 'pretty_version' => '2.6.2', + 'version' => '2.6.2.0', + 'reference' => '45b30f99ac27b5ca93cb4831afe16285f57b8221', + 'type' => 'library', + 'install_path' => __DIR__ . '/../guzzlehttp/psr7', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'monolog/monolog' => array( + 'pretty_version' => '2.9.2', + 'version' => '2.9.2.0', + 'reference' => '437cb3628f4cf6042cc10ae97fc2b8472e48ca1f', + 'type' => 'library', + 'install_path' => __DIR__ . '/../monolog/monolog', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'paragonie/constant_time_encoding' => array( + 'pretty_version' => 'v2.6.3', + 'version' => '2.6.3.0', + 'reference' => '58c3f47f650c94ec05a151692652a868995d2938', + 'type' => 'library', + 'install_path' => __DIR__ . '/../paragonie/constant_time_encoding', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'paragonie/random_compat' => array( + 'pretty_version' => 'v9.99.100', + 'version' => '9.99.100.0', + 'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a', + 'type' => 'library', + 'install_path' => __DIR__ . '/../paragonie/random_compat', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'phpseclib/phpseclib' => array( + 'pretty_version' => '3.0.37', + 'version' => '3.0.37.0', + 'reference' => 'cfa2013d0f68c062055180dd4328cc8b9d1f30b8', + 'type' => 'library', + 'install_path' => __DIR__ . '/../phpseclib/phpseclib', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/cache' => array( + 'pretty_version' => '2.0.0', + 'version' => '2.0.0.0', + 'reference' => '213f9dbc5b9bfbc4f8db86d2838dc968752ce13b', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/cache', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-client' => array( + 'pretty_version' => '1.0.3', + 'version' => '1.0.3.0', + 'reference' => 'bb5906edc1c324c9a05aa0873d40117941e5fa90', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-client', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-client-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0', + ), + ), + 'psr/http-factory' => array( + 'pretty_version' => '1.0.2', + 'version' => '1.0.2.0', + 'reference' => 'e616d01114759c4c489f93b099585439f795fe35', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-factory', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-factory-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0', + ), + ), + 'psr/http-message' => array( + 'pretty_version' => '2.0', + 'version' => '2.0.0.0', + 'reference' => '402d35bcb92c70c026d1a6a9883f06b2ead23d71', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-message', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-message-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0', + ), + ), + 'psr/log' => array( + 'pretty_version' => '1.1.4', + 'version' => '1.1.4.0', + 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/log', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/log-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0.0 || 2.0.0 || 3.0.0', + ), + ), + 'ralouphie/getallheaders' => array( + 'pretty_version' => '3.0.3', + 'version' => '3.0.3.0', + 'reference' => '120b605dfeb996808c31b6477290a714d356e822', + 'type' => 'library', + 'install_path' => __DIR__ . '/../ralouphie/getallheaders', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'ramsey/collection' => array( + 'pretty_version' => '1.3.0', + 'version' => '1.3.0.0', + 'reference' => 'ad7475d1c9e70b190ecffc58f2d989416af339b4', + 'type' => 'library', + 'install_path' => __DIR__ . '/../ramsey/collection', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'ramsey/uuid' => array( + 'pretty_version' => '4.7.5', + 'version' => '4.7.5.0', + 'reference' => '5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e', + 'type' => 'library', + 'install_path' => __DIR__ . '/../ramsey/uuid', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'rhumsaa/uuid' => array( + 'dev_requirement' => false, + 'replaced' => array( + 0 => '4.7.5', + ), + ), + 'rize/uri-template' => array( + 'pretty_version' => '0.3.5', + 'version' => '0.3.5.0', + 'reference' => '5ed4ba8ea34af84485dea815d4b6b620794d1168', + 'type' => 'library', + 'install_path' => __DIR__ . '/../rize/uri-template', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/deprecation-contracts' => array( + 'pretty_version' => 'v3.0.2', + 'version' => '3.0.2.0', + 'reference' => '26954b3d62a6c5fd0ea8a2a00c0353a14978d05c', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/deprecation-contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-php81' => array( + 'pretty_version' => 'v1.28.0', + 'version' => '1.28.0.0', + 'reference' => '7581cd600fa9fd681b797d00b02f068e2f13263b', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-php81', + 'aliases' => array(), + 'dev_requirement' => false, + ), + ), +); diff --git a/lib/Google/vendor/composer/platform_check.php b/lib/Google/vendor/composer/platform_check.php new file mode 100644 index 000000000..b168ddd5d --- /dev/null +++ b/lib/Google/vendor/composer/platform_check.php @@ -0,0 +1,26 @@ += 80002)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 8.0.2". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR + ); +} diff --git a/lib/Google/vendor/firebase/php-jwt/CHANGELOG.md b/lib/Google/vendor/firebase/php-jwt/CHANGELOG.md index 35e97fe86..644fa0bea 100644 --- a/lib/Google/vendor/firebase/php-jwt/CHANGELOG.md +++ b/lib/Google/vendor/firebase/php-jwt/CHANGELOG.md @@ -1,5 +1,58 @@ # Changelog +## [6.10.0](https://github.com/firebase/php-jwt/compare/v6.9.0...v6.10.0) (2023-11-28) + + +### Features + +* allow typ header override ([#546](https://github.com/firebase/php-jwt/issues/546)) ([79cb30b](https://github.com/firebase/php-jwt/commit/79cb30b729a22931b2fbd6b53f20629a83031ba9)) + +## [6.9.0](https://github.com/firebase/php-jwt/compare/v6.8.1...v6.9.0) (2023-10-04) + + +### Features + +* add payload to jwt exception ([#521](https://github.com/firebase/php-jwt/issues/521)) ([175edf9](https://github.com/firebase/php-jwt/commit/175edf958bb61922ec135b2333acf5622f2238a2)) + +## [6.8.1](https://github.com/firebase/php-jwt/compare/v6.8.0...v6.8.1) (2023-07-14) + + +### Bug Fixes + +* accept float claims but round down to ignore them ([#492](https://github.com/firebase/php-jwt/issues/492)) ([3936842](https://github.com/firebase/php-jwt/commit/39368423beeaacb3002afa7dcb75baebf204fe7e)) +* different BeforeValidException messages for nbf and iat ([#526](https://github.com/firebase/php-jwt/issues/526)) ([0a53cf2](https://github.com/firebase/php-jwt/commit/0a53cf2986e45c2bcbf1a269f313ebf56a154ee4)) + +## [6.8.0](https://github.com/firebase/php-jwt/compare/v6.7.0...v6.8.0) (2023-06-14) + + +### Features + +* add support for P-384 curve ([#515](https://github.com/firebase/php-jwt/issues/515)) ([5de4323](https://github.com/firebase/php-jwt/commit/5de4323f4baf4d70bca8663bd87682a69c656c3d)) + + +### Bug Fixes + +* handle invalid http responses ([#508](https://github.com/firebase/php-jwt/issues/508)) ([91c39c7](https://github.com/firebase/php-jwt/commit/91c39c72b22fc3e1191e574089552c1f2041c718)) + +## [6.7.0](https://github.com/firebase/php-jwt/compare/v6.6.0...v6.7.0) (2023-06-14) + + +### Features + +* add ed25519 support to JWK (public keys) ([#452](https://github.com/firebase/php-jwt/issues/452)) ([e53979a](https://github.com/firebase/php-jwt/commit/e53979abae927de916a75b9d239cfda8ce32be2a)) + +## [6.6.0](https://github.com/firebase/php-jwt/compare/v6.5.0...v6.6.0) (2023-06-13) + + +### Features + +* allow get headers when decoding token ([#442](https://github.com/firebase/php-jwt/issues/442)) ([fb85f47](https://github.com/firebase/php-jwt/commit/fb85f47cfaeffdd94faf8defdf07164abcdad6c3)) + + +### Bug Fixes + +* only check iat if nbf is not used ([#493](https://github.com/firebase/php-jwt/issues/493)) ([398ccd2](https://github.com/firebase/php-jwt/commit/398ccd25ea12fa84b9e4f1085d5ff448c21ec797)) + ## [6.5.0](https://github.com/firebase/php-jwt/compare/v6.4.0...v6.5.0) (2023-05-12) diff --git a/lib/Google/vendor/firebase/php-jwt/README.md b/lib/Google/vendor/firebase/php-jwt/README.md index f03826673..701de23a8 100644 --- a/lib/Google/vendor/firebase/php-jwt/README.md +++ b/lib/Google/vendor/firebase/php-jwt/README.md @@ -45,9 +45,12 @@ $payload = [ */ $jwt = JWT::encode($payload, $key, 'HS256'); $decoded = JWT::decode($jwt, new Key($key, 'HS256')); - print_r($decoded); +// Pass a stdClass in as the third parameter to get the decoded header values +$decoded = JWT::decode($jwt, new Key($key, 'HS256'), $headers = new stdClass()); +print_r($headers); + /* NOTE: This will now be an object instead of an associative array. To get an associative array, you will need to cast it as such: @@ -70,8 +73,8 @@ Example encode/decode headers Decoding the JWT headers without verifying the JWT first is NOT recommended, and is not supported by this library. This is because without verifying the JWT, the header values could have been tampered with. Any value pulled from an unverified header should be treated as if it could be any string sent in from an -attacker. If this is something you still want to do in your application for whatever reason, it's possible to -decode the header values manually simply by calling `json_decode` and `base64_decode` on the JWT +attacker. If this is something you still want to do in your application for whatever reason, it's possible to +decode the header values manually simply by calling `json_decode` and `base64_decode` on the JWT header part: ```php use Firebase\JWT\JWT; @@ -373,6 +376,8 @@ All exceptions in the `Firebase\JWT` namespace extend `UnexpectedValueException` like this: ```php +use Firebase\JWT\JWT; +use UnexpectedValueException; try { $decoded = JWT::decode($payload, $keys); } catch (LogicException $e) { diff --git a/lib/Google/vendor/firebase/php-jwt/src/BeforeValidException.php b/lib/Google/vendor/firebase/php-jwt/src/BeforeValidException.php index c147852b9..595164bf3 100644 --- a/lib/Google/vendor/firebase/php-jwt/src/BeforeValidException.php +++ b/lib/Google/vendor/firebase/php-jwt/src/BeforeValidException.php @@ -2,6 +2,17 @@ namespace Firebase\JWT; -class BeforeValidException extends \UnexpectedValueException +class BeforeValidException extends \UnexpectedValueException implements JWTExceptionWithPayloadInterface { + private object $payload; + + public function setPayload(object $payload): void + { + $this->payload = $payload; + } + + public function getPayload(): object + { + return $this->payload; + } } diff --git a/lib/Google/vendor/firebase/php-jwt/src/CachedKeySet.php b/lib/Google/vendor/firebase/php-jwt/src/CachedKeySet.php index baf801f13..ee529f9f5 100644 --- a/lib/Google/vendor/firebase/php-jwt/src/CachedKeySet.php +++ b/lib/Google/vendor/firebase/php-jwt/src/CachedKeySet.php @@ -178,6 +178,16 @@ private function keyIdExists(string $keyId): bool } $request = $this->httpFactory->createRequest('GET', $this->jwksUri); $jwksResponse = $this->httpClient->sendRequest($request); + if ($jwksResponse->getStatusCode() !== 200) { + throw new UnexpectedValueException( + sprintf('HTTP Error: %d %s for URI "%s"', + $jwksResponse->getStatusCode(), + $jwksResponse->getReasonPhrase(), + $this->jwksUri, + ), + $jwksResponse->getStatusCode() + ); + } $this->keySet = $this->formatJwksForCache((string) $jwksResponse->getBody()); if (!isset($this->keySet[$keyId])) { diff --git a/lib/Google/vendor/firebase/php-jwt/src/ExpiredException.php b/lib/Google/vendor/firebase/php-jwt/src/ExpiredException.php index 81ba52d43..12fef0944 100644 --- a/lib/Google/vendor/firebase/php-jwt/src/ExpiredException.php +++ b/lib/Google/vendor/firebase/php-jwt/src/ExpiredException.php @@ -2,6 +2,17 @@ namespace Firebase\JWT; -class ExpiredException extends \UnexpectedValueException +class ExpiredException extends \UnexpectedValueException implements JWTExceptionWithPayloadInterface { + private object $payload; + + public function setPayload(object $payload): void + { + $this->payload = $payload; + } + + public function getPayload(): object + { + return $this->payload; + } } diff --git a/lib/Google/vendor/firebase/php-jwt/src/JWK.php b/lib/Google/vendor/firebase/php-jwt/src/JWK.php index c7eff8ae4..63fb2484b 100644 --- a/lib/Google/vendor/firebase/php-jwt/src/JWK.php +++ b/lib/Google/vendor/firebase/php-jwt/src/JWK.php @@ -27,10 +27,16 @@ class JWK private const EC_CURVES = [ 'P-256' => '1.2.840.10045.3.1.7', // Len: 64 'secp256k1' => '1.3.132.0.10', // Len: 64 - // 'P-384' => '1.3.132.0.34', // Len: 96 (not yet supported) + 'P-384' => '1.3.132.0.34', // Len: 96 // 'P-521' => '1.3.132.0.35', // Len: 132 (not supported) ]; + // For keys with "kty" equal to "OKP" (Octet Key Pair), the "crv" parameter must contain the key subtype. + // This library supports the following subtypes: + private const OKP_SUBTYPES = [ + 'Ed25519' => true, // RFC 8037 + ]; + /** * Parse a set of JWK keys * @@ -145,8 +151,28 @@ public static function parseKey(array $jwk, string $defaultAlg = null): ?Key $publicKey = self::createPemFromCrvAndXYCoordinates($jwk['crv'], $jwk['x'], $jwk['y']); return new Key($publicKey, $jwk['alg']); + case 'OKP': + if (isset($jwk['d'])) { + // The key is actually a private key + throw new UnexpectedValueException('Key data must be for a public key'); + } + + if (!isset($jwk['crv'])) { + throw new UnexpectedValueException('crv not set'); + } + + if (empty(self::OKP_SUBTYPES[$jwk['crv']])) { + throw new DomainException('Unrecognised or unsupported OKP key subtype'); + } + + if (empty($jwk['x'])) { + throw new UnexpectedValueException('x not set'); + } + + // This library works internally with EdDSA keys (Ed25519) encoded in standard base64. + $publicKey = JWT::convertBase64urlToBase64($jwk['x']); + return new Key($publicKey, $jwk['alg']); default: - // Currently only RSA is supported break; } @@ -156,7 +182,7 @@ public static function parseKey(array $jwk, string $defaultAlg = null): ?Key /** * Converts the EC JWK values to pem format. * - * @param string $crv The EC curve (only P-256 is supported) + * @param string $crv The EC curve (only P-256 & P-384 is supported) * @param string $x The EC x-coordinate * @param string $y The EC y-coordinate * diff --git a/lib/Google/vendor/firebase/php-jwt/src/JWT.php b/lib/Google/vendor/firebase/php-jwt/src/JWT.php index c83ff0990..263492068 100644 --- a/lib/Google/vendor/firebase/php-jwt/src/JWT.php +++ b/lib/Google/vendor/firebase/php-jwt/src/JWT.php @@ -78,6 +78,7 @@ class JWT * Supported algorithms are 'ES384','ES256', * 'HS256', 'HS384', 'HS512', 'RS256', 'RS384' * and 'RS512'. + * @param stdClass $headers Optional. Populates stdClass with headers. * * @return stdClass The JWT's payload as a PHP object * @@ -94,7 +95,8 @@ class JWT */ public static function decode( string $jwt, - $keyOrKeyArray + $keyOrKeyArray, + stdClass &$headers = null ): stdClass { // Validate JWT $timestamp = \is_null(static::$timestamp) ? \time() : static::$timestamp; @@ -111,6 +113,9 @@ public static function decode( if (null === ($header = static::jsonDecode($headerRaw))) { throw new UnexpectedValueException('Invalid header encoding'); } + if ($headers !== null) { + $headers = $header; + } $payloadRaw = static::urlsafeB64Decode($bodyb64); if (null === ($payload = static::jsonDecode($payloadRaw))) { throw new UnexpectedValueException('Invalid claims encoding'); @@ -147,24 +152,30 @@ public static function decode( // Check the nbf if it is defined. This is the time that the // token can actually be used. If it's not yet that time, abort. - if (isset($payload->nbf) && $payload->nbf > ($timestamp + static::$leeway)) { - throw new BeforeValidException( - 'Cannot handle token prior to ' . \date(DateTime::ISO8601, $payload->nbf) + if (isset($payload->nbf) && floor($payload->nbf) > ($timestamp + static::$leeway)) { + $ex = new BeforeValidException( + 'Cannot handle token with nbf prior to ' . \date(DateTime::ISO8601, (int) $payload->nbf) ); + $ex->setPayload($payload); + throw $ex; } // Check that this token has been created before 'now'. This prevents // using tokens that have been created for later use (and haven't // correctly used the nbf claim). - if (isset($payload->iat) && $payload->iat > ($timestamp + static::$leeway)) { - throw new BeforeValidException( - 'Cannot handle token prior to ' . \date(DateTime::ISO8601, $payload->iat) + if (!isset($payload->nbf) && isset($payload->iat) && floor($payload->iat) > ($timestamp + static::$leeway)) { + $ex = new BeforeValidException( + 'Cannot handle token with iat prior to ' . \date(DateTime::ISO8601, (int) $payload->iat) ); + $ex->setPayload($payload); + throw $ex; } // Check if this token has expired. if (isset($payload->exp) && ($timestamp - static::$leeway) >= $payload->exp) { - throw new ExpiredException('Expired token'); + $ex = new ExpiredException('Expired token'); + $ex->setPayload($payload); + throw $ex; } return $payload; @@ -192,13 +203,14 @@ public static function encode( string $keyId = null, array $head = null ): string { - $header = ['typ' => 'JWT', 'alg' => $alg]; + $header = ['typ' => 'JWT']; + if (isset($head) && \is_array($head)) { + $header = \array_merge($header, $head); + } + $header['alg'] = $alg; if ($keyId !== null) { $header['kid'] = $keyId; } - if (isset($head) && \is_array($head)) { - $header = \array_merge($head, $header); - } $segments = []; $segments[] = static::urlsafeB64Encode((string) static::jsonEncode($header)); $segments[] = static::urlsafeB64Encode((string) static::jsonEncode($payload)); @@ -215,7 +227,7 @@ public static function encode( * * @param string $msg The message to sign * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key. - * @param string $alg Supported algorithms are 'ES384','ES256', 'ES256K', 'HS256', + * @param string $alg Supported algorithms are 'EdDSA', 'ES384', 'ES256', 'ES256K', 'HS256', * 'HS384', 'HS512', 'RS256', 'RS384', and 'RS512' * * @return string An encrypted message @@ -278,7 +290,7 @@ public static function sign( * * @param string $msg The original message (header and body) * @param string $signature The original signature - * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial For HS*, a string key works. for RS*, must be an instance of OpenSSLAsymmetricKey + * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial For Ed*, ES*, HS*, a string key works. for RS*, must be an instance of OpenSSLAsymmetricKey * @param string $alg The algorithm * * @return bool @@ -399,13 +411,28 @@ public static function jsonEncode(array $input): string * @throws InvalidArgumentException invalid base64 characters */ public static function urlsafeB64Decode(string $input): string + { + return \base64_decode(self::convertBase64UrlToBase64($input)); + } + + /** + * Convert a string in the base64url (URL-safe Base64) encoding to standard base64. + * + * @param string $input A Base64 encoded string with URL-safe characters (-_ and no padding) + * + * @return string A Base64 encoded string with standard characters (+/) and padding (=), when + * needed. + * + * @see https://www.rfc-editor.org/rfc/rfc4648 + */ + public static function convertBase64UrlToBase64(string $input): string { $remainder = \strlen($input) % 4; if ($remainder) { $padlen = 4 - $remainder; $input .= \str_repeat('=', $padlen); } - return \base64_decode(\strtr($input, '-_', '+/')); + return \strtr($input, '-_', '+/'); } /** diff --git a/lib/Google/vendor/firebase/php-jwt/src/JWTExceptionWithPayloadInterface.php b/lib/Google/vendor/firebase/php-jwt/src/JWTExceptionWithPayloadInterface.php new file mode 100644 index 000000000..7933ed68b --- /dev/null +++ b/lib/Google/vendor/firebase/php-jwt/src/JWTExceptionWithPayloadInterface.php @@ -0,0 +1,20 @@ + 'Google_Client', + 'Google\\Service' => 'Google_Service', + 'Google\\Service\\Resource' => 'Google_Service_Resource', + 'Google\\Model' => 'Google_Model', + 'Google\\Collection' => 'Google_Collection', + ]; + foreach ($servicesClassMap as $alias => $class) { + class_alias($class, $alias); + } + } +} +spl_autoload_register(function ($class) { + if (0 === strpos($class, 'Google_Service_')) { + // Autoload the new class, which will also create an alias for the + // old class by changing underscores to namespaces: + // Google_Service_Speech_Resource_Operations + // => Google\Service\Speech\Resource\Operations + $classExists = class_exists($newClass = str_replace('_', '\\', $class)); + if ($classExists) { + return true; + } + } +}, true, true); diff --git a/lib/Google/vendor/google/apiclient-services/composer.json b/lib/Google/vendor/google/apiclient-services/composer.json new file mode 100644 index 000000000..ecc41f4e1 --- /dev/null +++ b/lib/Google/vendor/google/apiclient-services/composer.json @@ -0,0 +1,27 @@ +{ + "name": "google/apiclient-services", + "type": "library", + "description": "Client library for Google APIs", + "keywords": ["google"], + "homepage": "http://developers.google.com/api-client-library/php", + "license": "Apache-2.0", + "require": { + "php": "^7.4||^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7||^8.5.13" + }, + "autoload": { + "psr-4": { + "Google\\Service\\": "src" + }, + "files": [ + "autoload.php" + ] + }, + "autoload-dev": { + "psr-4": { + "Google\\": "tests/mocks" + } + } +} diff --git a/lib/Google/src/Service/Storage.php b/lib/Google/vendor/google/apiclient-services/src/Storage.php similarity index 79% rename from lib/Google/src/Service/Storage.php rename to lib/Google/vendor/google/apiclient-services/src/Storage.php index ae676e286..9f8fb34e4 100644 --- a/lib/Google/src/Service/Storage.php +++ b/lib/Google/vendor/google/apiclient-services/src/Storage.php @@ -50,13 +50,16 @@ class Storage extends \Google\Service const DEVSTORAGE_READ_WRITE = "https://www.googleapis.com/auth/devstorage.read_write"; + public $anywhereCache; public $bucketAccessControls; public $buckets; public $channels; public $defaultObjectAccessControls; + public $managedFolders; public $notifications; public $objectAccessControls; public $objects; + public $operations; public $projects_hmacKeys; public $projects_serviceAccount; @@ -76,6 +79,119 @@ public function __construct($clientOrConfig = [], $rootUrl = null) $this->version = 'v1'; $this->serviceName = 'storage'; + $this->anywhereCache = new Storage\Resource\AnywhereCache( + $this, + $this->serviceName, + 'anywhereCache', + [ + 'methods' => [ + 'disable' => [ + 'path' => 'b/{bucket}/anywhereCaches/{anywhereCacheId}/disable', + 'httpMethod' => 'POST', + 'parameters' => [ + 'bucket' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'anywhereCacheId' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + ], + ],'get' => [ + 'path' => 'b/{bucket}/anywhereCaches/{anywhereCacheId}', + 'httpMethod' => 'GET', + 'parameters' => [ + 'bucket' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'anywhereCacheId' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + ], + ],'insert' => [ + 'path' => 'b/{bucket}/anywhereCaches', + 'httpMethod' => 'POST', + 'parameters' => [ + 'bucket' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + ], + ],'list' => [ + 'path' => 'b/{bucket}/anywhereCache', + 'httpMethod' => 'GET', + 'parameters' => [ + 'bucket' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'pageSize' => [ + 'location' => 'query', + 'type' => 'integer', + ], + 'pageToken' => [ + 'location' => 'query', + 'type' => 'string', + ], + ], + ],'pause' => [ + 'path' => 'b/{bucket}/anywhereCaches/{anywhereCacheId}/pause', + 'httpMethod' => 'POST', + 'parameters' => [ + 'bucket' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'anywhereCacheId' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + ], + ],'resume' => [ + 'path' => 'b/{bucket}/anywhereCaches/{anywhereCacheId}/resume', + 'httpMethod' => 'POST', + 'parameters' => [ + 'bucket' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'anywhereCacheId' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + ], + ],'update' => [ + 'path' => 'b/{bucket}/anywhereCaches/{anywhereCacheId}', + 'httpMethod' => 'PATCH', + 'parameters' => [ + 'bucket' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'anywhereCacheId' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + ], + ], + ] + ] + ); $this->bucketAccessControls = new Storage\Resource\BucketAccessControls( $this, $this->serviceName, @@ -271,6 +387,10 @@ public function __construct($clientOrConfig = [], $rootUrl = null) 'type' => 'string', 'required' => true, ], + 'enableObjectRetention' => [ + 'location' => 'query', + 'type' => 'boolean', + ], 'predefinedAcl' => [ 'location' => 'query', 'type' => 'string', @@ -579,6 +699,161 @@ public function __construct($clientOrConfig = [], $rootUrl = null) ] ] ); + $this->managedFolders = new Storage\Resource\ManagedFolders( + $this, + $this->serviceName, + 'managedFolders', + [ + 'methods' => [ + 'delete' => [ + 'path' => 'b/{bucket}/managedFolders/{managedFolder}', + 'httpMethod' => 'DELETE', + 'parameters' => [ + 'bucket' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'managedFolder' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'ifMetagenerationMatch' => [ + 'location' => 'query', + 'type' => 'string', + ], + 'ifMetagenerationNotMatch' => [ + 'location' => 'query', + 'type' => 'string', + ], + ], + ],'get' => [ + 'path' => 'b/{bucket}/managedFolders/{managedFolder}', + 'httpMethod' => 'GET', + 'parameters' => [ + 'bucket' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'managedFolder' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'ifMetagenerationMatch' => [ + 'location' => 'query', + 'type' => 'string', + ], + 'ifMetagenerationNotMatch' => [ + 'location' => 'query', + 'type' => 'string', + ], + ], + ],'getIamPolicy' => [ + 'path' => 'b/{bucket}/managedFolders/{managedFolder}/iam', + 'httpMethod' => 'GET', + 'parameters' => [ + 'bucket' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'managedFolder' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'optionsRequestedPolicyVersion' => [ + 'location' => 'query', + 'type' => 'integer', + ], + 'userProject' => [ + 'location' => 'query', + 'type' => 'string', + ], + ], + ],'insert' => [ + 'path' => 'b/{bucket}/managedFolders', + 'httpMethod' => 'POST', + 'parameters' => [ + 'bucket' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + ], + ],'list' => [ + 'path' => 'b/{bucket}/managedFolders', + 'httpMethod' => 'GET', + 'parameters' => [ + 'bucket' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'pageSize' => [ + 'location' => 'query', + 'type' => 'integer', + ], + 'pageToken' => [ + 'location' => 'query', + 'type' => 'string', + ], + 'prefix' => [ + 'location' => 'query', + 'type' => 'string', + ], + ], + ],'setIamPolicy' => [ + 'path' => 'b/{bucket}/managedFolders/{managedFolder}/iam', + 'httpMethod' => 'PUT', + 'parameters' => [ + 'bucket' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'managedFolder' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'userProject' => [ + 'location' => 'query', + 'type' => 'string', + ], + ], + ],'testIamPermissions' => [ + 'path' => 'b/{bucket}/managedFolders/{managedFolder}/iam/testPermissions', + 'httpMethod' => 'GET', + 'parameters' => [ + 'bucket' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'managedFolder' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'permissions' => [ + 'location' => 'query', + 'type' => 'string', + 'repeated' => true, + 'required' => true, + ], + 'userProject' => [ + 'location' => 'query', + 'type' => 'string', + ], + ], + ], + ] + ] + ); $this->notifications = new Storage\Resource\Notifications( $this, $this->serviceName, @@ -829,7 +1104,17 @@ public function __construct($clientOrConfig = [], $rootUrl = null) 'objects', [ 'methods' => [ - 'compose' => [ + 'bulkRestore' => [ + 'path' => 'b/{bucket}/o/bulkRestore', + 'httpMethod' => 'POST', + 'parameters' => [ + 'bucket' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + ], + ],'compose' => [ 'path' => 'b/{destinationBucket}/o/{destinationObject}/compose', 'httpMethod' => 'POST', 'parameters' => [ @@ -1018,6 +1303,10 @@ public function __construct($clientOrConfig = [], $rootUrl = null) 'location' => 'query', 'type' => 'string', ], + 'softDeleted' => [ + 'location' => 'query', + 'type' => 'boolean', + ], 'userProject' => [ 'location' => 'query', 'type' => 'string', @@ -1113,6 +1402,10 @@ public function __construct($clientOrConfig = [], $rootUrl = null) 'location' => 'query', 'type' => 'string', ], + 'includeFoldersAsPrefixes' => [ + 'location' => 'query', + 'type' => 'boolean', + ], 'includeTrailingDelimiter' => [ 'location' => 'query', 'type' => 'boolean', @@ -1137,6 +1430,10 @@ public function __construct($clientOrConfig = [], $rootUrl = null) 'location' => 'query', 'type' => 'string', ], + 'softDeleted' => [ + 'location' => 'query', + 'type' => 'boolean', + ], 'startOffset' => [ 'location' => 'query', 'type' => 'string', @@ -1184,6 +1481,10 @@ public function __construct($clientOrConfig = [], $rootUrl = null) 'location' => 'query', 'type' => 'string', ], + 'overrideUnlockedRetention' => [ + 'location' => 'query', + 'type' => 'boolean', + ], 'predefinedAcl' => [ 'location' => 'query', 'type' => 'string', @@ -1197,6 +1498,54 @@ public function __construct($clientOrConfig = [], $rootUrl = null) 'type' => 'string', ], ], + ],'restore' => [ + 'path' => 'b/{bucket}/o/{object}/restore', + 'httpMethod' => 'POST', + 'parameters' => [ + 'bucket' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'object' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'copySourceAcl' => [ + 'location' => 'query', + 'type' => 'boolean', + ], + 'generation' => [ + 'location' => 'query', + 'type' => 'string', + 'required' => true, + ], + 'ifGenerationMatch' => [ + 'location' => 'query', + 'type' => 'string', + ], + 'ifGenerationNotMatch' => [ + 'location' => 'query', + 'type' => 'string', + ], + 'ifMetagenerationMatch' => [ + 'location' => 'query', + 'type' => 'string', + ], + 'ifMetagenerationNotMatch' => [ + 'location' => 'query', + 'type' => 'string', + ], + 'projection' => [ + 'location' => 'query', + 'type' => 'string', + ], + 'userProject' => [ + 'location' => 'query', + 'type' => 'string', + ], + ], ],'rewrite' => [ 'path' => 'b/{sourceBucket}/o/{sourceObject}/rewriteTo/b/{destinationBucket}/o/{destinationObject}', 'httpMethod' => 'POST', @@ -1368,6 +1717,10 @@ public function __construct($clientOrConfig = [], $rootUrl = null) 'location' => 'query', 'type' => 'string', ], + 'overrideUnlockedRetention' => [ + 'location' => 'query', + 'type' => 'boolean', + ], 'predefinedAcl' => [ 'location' => 'query', 'type' => 'string', @@ -1435,6 +1788,68 @@ public function __construct($clientOrConfig = [], $rootUrl = null) ] ] ); + $this->operations = new Storage\Resource\Operations( + $this, + $this->serviceName, + 'operations', + [ + 'methods' => [ + 'cancel' => [ + 'path' => 'b/{bucket}/operations/{operationId}/cancel', + 'httpMethod' => 'POST', + 'parameters' => [ + 'bucket' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'operationId' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + ], + ],'get' => [ + 'path' => 'b/{bucket}/operations/{operationId}', + 'httpMethod' => 'GET', + 'parameters' => [ + 'bucket' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'operationId' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + ], + ],'list' => [ + 'path' => 'b/{bucket}/operations', + 'httpMethod' => 'GET', + 'parameters' => [ + 'bucket' => [ + 'location' => 'path', + 'type' => 'string', + 'required' => true, + ], + 'filter' => [ + 'location' => 'query', + 'type' => 'string', + ], + 'pageSize' => [ + 'location' => 'query', + 'type' => 'integer', + ], + 'pageToken' => [ + 'location' => 'query', + 'type' => 'string', + ], + ], + ], + ] + ] + ); $this->projects_hmacKeys = new Storage\Resource\ProjectsHmacKeys( $this, $this->serviceName, diff --git a/lib/Google/vendor/google/apiclient-services/src/Storage/AnywhereCache.php b/lib/Google/vendor/google/apiclient-services/src/Storage/AnywhereCache.php new file mode 100644 index 000000000..d31c489a5 --- /dev/null +++ b/lib/Google/vendor/google/apiclient-services/src/Storage/AnywhereCache.php @@ -0,0 +1,224 @@ +admissionPolicy = $admissionPolicy; + } + /** + * @return string + */ + public function getAdmissionPolicy() + { + return $this->admissionPolicy; + } + /** + * @param string + */ + public function setAnywhereCacheId($anywhereCacheId) + { + $this->anywhereCacheId = $anywhereCacheId; + } + /** + * @return string + */ + public function getAnywhereCacheId() + { + return $this->anywhereCacheId; + } + /** + * @param string + */ + public function setBucket($bucket) + { + $this->bucket = $bucket; + } + /** + * @return string + */ + public function getBucket() + { + return $this->bucket; + } + /** + * @param string + */ + public function setCreateTime($createTime) + { + $this->createTime = $createTime; + } + /** + * @return string + */ + public function getCreateTime() + { + return $this->createTime; + } + /** + * @param string + */ + public function setId($id) + { + $this->id = $id; + } + /** + * @return string + */ + public function getId() + { + return $this->id; + } + /** + * @param string + */ + public function setKind($kind) + { + $this->kind = $kind; + } + /** + * @return string + */ + public function getKind() + { + return $this->kind; + } + /** + * @param bool + */ + public function setPendingUpdate($pendingUpdate) + { + $this->pendingUpdate = $pendingUpdate; + } + /** + * @return bool + */ + public function getPendingUpdate() + { + return $this->pendingUpdate; + } + /** + * @param string + */ + public function setSelfLink($selfLink) + { + $this->selfLink = $selfLink; + } + /** + * @return string + */ + public function getSelfLink() + { + return $this->selfLink; + } + /** + * @param string + */ + public function setState($state) + { + $this->state = $state; + } + /** + * @return string + */ + public function getState() + { + return $this->state; + } + /** + * @param string + */ + public function setTtl($ttl) + { + $this->ttl = $ttl; + } + /** + * @return string + */ + public function getTtl() + { + return $this->ttl; + } + /** + * @param string + */ + public function setUpdateTime($updateTime) + { + $this->updateTime = $updateTime; + } + /** + * @return string + */ + public function getUpdateTime() + { + return $this->updateTime; + } +} + +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(AnywhereCache::class, 'Google_Service_Storage_AnywhereCache'); diff --git a/lib/Google/vendor/google/apiclient-services/src/Storage/AnywhereCaches.php b/lib/Google/vendor/google/apiclient-services/src/Storage/AnywhereCaches.php new file mode 100644 index 000000000..14874aea2 --- /dev/null +++ b/lib/Google/vendor/google/apiclient-services/src/Storage/AnywhereCaches.php @@ -0,0 +1,79 @@ +items = $items; + } + /** + * @return AnywhereCache[] + */ + public function getItems() + { + return $this->items; + } + /** + * @param string + */ + public function setKind($kind) + { + $this->kind = $kind; + } + /** + * @return string + */ + public function getKind() + { + return $this->kind; + } + /** + * @param string + */ + public function setNextPageToken($nextPageToken) + { + $this->nextPageToken = $nextPageToken; + } + /** + * @return string + */ + public function getNextPageToken() + { + return $this->nextPageToken; + } +} + +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(AnywhereCaches::class, 'Google_Service_Storage_AnywhereCaches'); diff --git a/lib/Google/src/Service/Storage/Bucket.php b/lib/Google/vendor/google/apiclient-services/src/Storage/Bucket.php similarity index 92% rename from lib/Google/src/Service/Storage/Bucket.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/Bucket.php index 655fea046..ac732ea62 100644 --- a/lib/Google/src/Service/Storage/Bucket.php +++ b/lib/Google/vendor/google/apiclient-services/src/Storage/Bucket.php @@ -76,6 +76,8 @@ class Bucket extends \Google\Collection * @var string */ public $name; + protected $objectRetentionType = BucketObjectRetention::class; + protected $objectRetentionDataType = ''; protected $ownerType = BucketOwner::class; protected $ownerDataType = ''; /** @@ -96,6 +98,8 @@ class Bucket extends \Google\Collection * @var string */ public $selfLink; + protected $softDeletePolicyType = BucketSoftDeletePolicy::class; + protected $softDeletePolicyDataType = ''; /** * @var string */ @@ -379,6 +383,20 @@ public function getName() { return $this->name; } + /** + * @param BucketObjectRetention + */ + public function setObjectRetention(BucketObjectRetention $objectRetention) + { + $this->objectRetention = $objectRetention; + } + /** + * @return BucketObjectRetention + */ + public function getObjectRetention() + { + return $this->objectRetention; + } /** * @param BucketOwner */ @@ -463,6 +481,20 @@ public function getSelfLink() { return $this->selfLink; } + /** + * @param BucketSoftDeletePolicy + */ + public function setSoftDeletePolicy(BucketSoftDeletePolicy $softDeletePolicy) + { + $this->softDeletePolicy = $softDeletePolicy; + } + /** + * @return BucketSoftDeletePolicy + */ + public function getSoftDeletePolicy() + { + return $this->softDeletePolicy; + } /** * @param string */ diff --git a/lib/Google/src/Service/Storage/BucketAccessControl.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketAccessControl.php similarity index 100% rename from lib/Google/src/Service/Storage/BucketAccessControl.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/BucketAccessControl.php diff --git a/lib/Google/src/Service/Storage/BucketAccessControlProjectTeam.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketAccessControlProjectTeam.php similarity index 100% rename from lib/Google/src/Service/Storage/BucketAccessControlProjectTeam.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/BucketAccessControlProjectTeam.php diff --git a/lib/Google/src/Service/Storage/BucketAccessControls.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketAccessControls.php similarity index 100% rename from lib/Google/src/Service/Storage/BucketAccessControls.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/BucketAccessControls.php diff --git a/lib/Google/src/Service/Storage/BucketAutoclass.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketAutoclass.php similarity index 64% rename from lib/Google/src/Service/Storage/BucketAutoclass.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/BucketAutoclass.php index 42e8bdcc1..956676ae8 100644 --- a/lib/Google/src/Service/Storage/BucketAutoclass.php +++ b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketAutoclass.php @@ -23,6 +23,14 @@ class BucketAutoclass extends \Google\Model * @var bool */ public $enabled; + /** + * @var string + */ + public $terminalStorageClass; + /** + * @var string + */ + public $terminalStorageClassUpdateTime; /** * @var string */ @@ -42,6 +50,34 @@ public function getEnabled() { return $this->enabled; } + /** + * @param string + */ + public function setTerminalStorageClass($terminalStorageClass) + { + $this->terminalStorageClass = $terminalStorageClass; + } + /** + * @return string + */ + public function getTerminalStorageClass() + { + return $this->terminalStorageClass; + } + /** + * @param string + */ + public function setTerminalStorageClassUpdateTime($terminalStorageClassUpdateTime) + { + $this->terminalStorageClassUpdateTime = $terminalStorageClassUpdateTime; + } + /** + * @return string + */ + public function getTerminalStorageClassUpdateTime() + { + return $this->terminalStorageClassUpdateTime; + } /** * @param string */ diff --git a/lib/Google/src/Service/Storage/BucketBilling.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketBilling.php similarity index 100% rename from lib/Google/src/Service/Storage/BucketBilling.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/BucketBilling.php diff --git a/lib/Google/src/Service/Storage/BucketCors.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketCors.php similarity index 100% rename from lib/Google/src/Service/Storage/BucketCors.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/BucketCors.php diff --git a/lib/Google/src/Service/Storage/BucketCustomPlacementConfig.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketCustomPlacementConfig.php similarity index 100% rename from lib/Google/src/Service/Storage/BucketCustomPlacementConfig.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/BucketCustomPlacementConfig.php diff --git a/lib/Google/src/Service/Storage/BucketEncryption.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketEncryption.php similarity index 100% rename from lib/Google/src/Service/Storage/BucketEncryption.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/BucketEncryption.php diff --git a/lib/Google/src/Service/Storage/BucketIamConfiguration.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketIamConfiguration.php similarity index 100% rename from lib/Google/src/Service/Storage/BucketIamConfiguration.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/BucketIamConfiguration.php diff --git a/lib/Google/src/Service/Storage/BucketIamConfigurationBucketPolicyOnly.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketIamConfigurationBucketPolicyOnly.php similarity index 100% rename from lib/Google/src/Service/Storage/BucketIamConfigurationBucketPolicyOnly.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/BucketIamConfigurationBucketPolicyOnly.php diff --git a/lib/Google/src/Service/Storage/BucketIamConfigurationUniformBucketLevelAccess.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketIamConfigurationUniformBucketLevelAccess.php similarity index 100% rename from lib/Google/src/Service/Storage/BucketIamConfigurationUniformBucketLevelAccess.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/BucketIamConfigurationUniformBucketLevelAccess.php diff --git a/lib/Google/src/Service/Storage/BucketLifecycle.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketLifecycle.php similarity index 100% rename from lib/Google/src/Service/Storage/BucketLifecycle.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/BucketLifecycle.php diff --git a/lib/Google/src/Service/Storage/BucketLifecycleRule.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketLifecycleRule.php similarity index 100% rename from lib/Google/src/Service/Storage/BucketLifecycleRule.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/BucketLifecycleRule.php diff --git a/lib/Google/src/Service/Storage/BucketLifecycleRuleAction.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketLifecycleRuleAction.php similarity index 100% rename from lib/Google/src/Service/Storage/BucketLifecycleRuleAction.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/BucketLifecycleRuleAction.php diff --git a/lib/Google/src/Service/Storage/BucketLifecycleRuleCondition.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketLifecycleRuleCondition.php similarity index 100% rename from lib/Google/src/Service/Storage/BucketLifecycleRuleCondition.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/BucketLifecycleRuleCondition.php diff --git a/lib/Google/src/Service/Storage/BucketLogging.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketLogging.php similarity index 100% rename from lib/Google/src/Service/Storage/BucketLogging.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/BucketLogging.php diff --git a/lib/Google/vendor/google/apiclient-services/src/Storage/BucketObjectRetention.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketObjectRetention.php new file mode 100644 index 000000000..5d4a29d9e --- /dev/null +++ b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketObjectRetention.php @@ -0,0 +1,44 @@ +mode = $mode; + } + /** + * @return string + */ + public function getMode() + { + return $this->mode; + } +} + +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(BucketObjectRetention::class, 'Google_Service_Storage_BucketObjectRetention'); diff --git a/lib/Google/src/Service/Storage/BucketOwner.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketOwner.php similarity index 100% rename from lib/Google/src/Service/Storage/BucketOwner.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/BucketOwner.php diff --git a/lib/Google/src/Service/Storage/BucketRetentionPolicy.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketRetentionPolicy.php similarity index 100% rename from lib/Google/src/Service/Storage/BucketRetentionPolicy.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/BucketRetentionPolicy.php diff --git a/lib/Google/vendor/google/apiclient-services/src/Storage/BucketSoftDeletePolicy.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketSoftDeletePolicy.php new file mode 100644 index 000000000..5c28f9b26 --- /dev/null +++ b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketSoftDeletePolicy.php @@ -0,0 +1,62 @@ +effectiveTime = $effectiveTime; + } + /** + * @return string + */ + public function getEffectiveTime() + { + return $this->effectiveTime; + } + /** + * @param string + */ + public function setRetentionDurationSeconds($retentionDurationSeconds) + { + $this->retentionDurationSeconds = $retentionDurationSeconds; + } + /** + * @return string + */ + public function getRetentionDurationSeconds() + { + return $this->retentionDurationSeconds; + } +} + +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(BucketSoftDeletePolicy::class, 'Google_Service_Storage_BucketSoftDeletePolicy'); diff --git a/lib/Google/src/Service/Storage/BucketVersioning.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketVersioning.php similarity index 100% rename from lib/Google/src/Service/Storage/BucketVersioning.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/BucketVersioning.php diff --git a/lib/Google/src/Service/Storage/BucketWebsite.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BucketWebsite.php similarity index 100% rename from lib/Google/src/Service/Storage/BucketWebsite.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/BucketWebsite.php diff --git a/lib/Google/src/Service/Storage/Buckets.php b/lib/Google/vendor/google/apiclient-services/src/Storage/Buckets.php similarity index 100% rename from lib/Google/src/Service/Storage/Buckets.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/Buckets.php diff --git a/lib/Google/vendor/google/apiclient-services/src/Storage/BulkRestoreObjectsRequest.php b/lib/Google/vendor/google/apiclient-services/src/Storage/BulkRestoreObjectsRequest.php new file mode 100644 index 000000000..d7feda6f0 --- /dev/null +++ b/lib/Google/vendor/google/apiclient-services/src/Storage/BulkRestoreObjectsRequest.php @@ -0,0 +1,117 @@ +allowOverwrite = $allowOverwrite; + } + /** + * @return bool + */ + public function getAllowOverwrite() + { + return $this->allowOverwrite; + } + /** + * @param bool + */ + public function setCopySourceAcl($copySourceAcl) + { + $this->copySourceAcl = $copySourceAcl; + } + /** + * @return bool + */ + public function getCopySourceAcl() + { + return $this->copySourceAcl; + } + /** + * @param string[] + */ + public function setMatchGlobs($matchGlobs) + { + $this->matchGlobs = $matchGlobs; + } + /** + * @return string[] + */ + public function getMatchGlobs() + { + return $this->matchGlobs; + } + /** + * @param string + */ + public function setSoftDeletedAfterTime($softDeletedAfterTime) + { + $this->softDeletedAfterTime = $softDeletedAfterTime; + } + /** + * @return string + */ + public function getSoftDeletedAfterTime() + { + return $this->softDeletedAfterTime; + } + /** + * @param string + */ + public function setSoftDeletedBeforeTime($softDeletedBeforeTime) + { + $this->softDeletedBeforeTime = $softDeletedBeforeTime; + } + /** + * @return string + */ + public function getSoftDeletedBeforeTime() + { + return $this->softDeletedBeforeTime; + } +} + +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(BulkRestoreObjectsRequest::class, 'Google_Service_Storage_BulkRestoreObjectsRequest'); diff --git a/lib/Google/src/Service/Storage/Channel.php b/lib/Google/vendor/google/apiclient-services/src/Storage/Channel.php similarity index 100% rename from lib/Google/src/Service/Storage/Channel.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/Channel.php diff --git a/lib/Google/src/Service/Storage/ComposeRequest.php b/lib/Google/vendor/google/apiclient-services/src/Storage/ComposeRequest.php similarity index 100% rename from lib/Google/src/Service/Storage/ComposeRequest.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/ComposeRequest.php diff --git a/lib/Google/src/Service/Storage/ComposeRequestSourceObjects.php b/lib/Google/vendor/google/apiclient-services/src/Storage/ComposeRequestSourceObjects.php similarity index 100% rename from lib/Google/src/Service/Storage/ComposeRequestSourceObjects.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/ComposeRequestSourceObjects.php diff --git a/lib/Google/src/Service/Storage/ComposeRequestSourceObjectsObjectPreconditions.php b/lib/Google/vendor/google/apiclient-services/src/Storage/ComposeRequestSourceObjectsObjectPreconditions.php similarity index 100% rename from lib/Google/src/Service/Storage/ComposeRequestSourceObjectsObjectPreconditions.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/ComposeRequestSourceObjectsObjectPreconditions.php diff --git a/lib/Google/src/Service/Storage/Expr.php b/lib/Google/vendor/google/apiclient-services/src/Storage/Expr.php similarity index 100% rename from lib/Google/src/Service/Storage/Expr.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/Expr.php diff --git a/lib/Google/vendor/google/apiclient-services/src/Storage/GoogleLongrunningListOperationsResponse.php b/lib/Google/vendor/google/apiclient-services/src/Storage/GoogleLongrunningListOperationsResponse.php new file mode 100644 index 000000000..55efd1fed --- /dev/null +++ b/lib/Google/vendor/google/apiclient-services/src/Storage/GoogleLongrunningListOperationsResponse.php @@ -0,0 +1,61 @@ +nextPageToken = $nextPageToken; + } + /** + * @return string + */ + public function getNextPageToken() + { + return $this->nextPageToken; + } + /** + * @param GoogleLongrunningOperation[] + */ + public function setOperations($operations) + { + $this->operations = $operations; + } + /** + * @return GoogleLongrunningOperation[] + */ + public function getOperations() + { + return $this->operations; + } +} + +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(GoogleLongrunningListOperationsResponse::class, 'Google_Service_Storage_GoogleLongrunningListOperationsResponse'); diff --git a/lib/Google/vendor/google/apiclient-services/src/Storage/GoogleLongrunningOperation.php b/lib/Google/vendor/google/apiclient-services/src/Storage/GoogleLongrunningOperation.php new file mode 100644 index 000000000..42db42881 --- /dev/null +++ b/lib/Google/vendor/google/apiclient-services/src/Storage/GoogleLongrunningOperation.php @@ -0,0 +1,114 @@ +done = $done; + } + /** + * @return bool + */ + public function getDone() + { + return $this->done; + } + /** + * @param GoogleRpcStatus + */ + public function setError(GoogleRpcStatus $error) + { + $this->error = $error; + } + /** + * @return GoogleRpcStatus + */ + public function getError() + { + return $this->error; + } + /** + * @param array[] + */ + public function setMetadata($metadata) + { + $this->metadata = $metadata; + } + /** + * @return array[] + */ + public function getMetadata() + { + return $this->metadata; + } + /** + * @param string + */ + public function setName($name) + { + $this->name = $name; + } + /** + * @return string + */ + public function getName() + { + return $this->name; + } + /** + * @param array[] + */ + public function setResponse($response) + { + $this->response = $response; + } + /** + * @return array[] + */ + public function getResponse() + { + return $this->response; + } +} + +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(GoogleLongrunningOperation::class, 'Google_Service_Storage_GoogleLongrunningOperation'); diff --git a/lib/Google/vendor/google/apiclient-services/src/Storage/GoogleRpcStatus.php b/lib/Google/vendor/google/apiclient-services/src/Storage/GoogleRpcStatus.php new file mode 100644 index 000000000..4a9bf3f05 --- /dev/null +++ b/lib/Google/vendor/google/apiclient-services/src/Storage/GoogleRpcStatus.php @@ -0,0 +1,81 @@ +code = $code; + } + /** + * @return int + */ + public function getCode() + { + return $this->code; + } + /** + * @param array[] + */ + public function setDetails($details) + { + $this->details = $details; + } + /** + * @return array[] + */ + public function getDetails() + { + return $this->details; + } + /** + * @param string + */ + public function setMessage($message) + { + $this->message = $message; + } + /** + * @return string + */ + public function getMessage() + { + return $this->message; + } +} + +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(GoogleRpcStatus::class, 'Google_Service_Storage_GoogleRpcStatus'); diff --git a/lib/Google/src/Service/Storage/HmacKey.php b/lib/Google/vendor/google/apiclient-services/src/Storage/HmacKey.php similarity index 100% rename from lib/Google/src/Service/Storage/HmacKey.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/HmacKey.php diff --git a/lib/Google/src/Service/Storage/HmacKeyMetadata.php b/lib/Google/vendor/google/apiclient-services/src/Storage/HmacKeyMetadata.php similarity index 100% rename from lib/Google/src/Service/Storage/HmacKeyMetadata.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/HmacKeyMetadata.php diff --git a/lib/Google/src/Service/Storage/HmacKeysMetadata.php b/lib/Google/vendor/google/apiclient-services/src/Storage/HmacKeysMetadata.php similarity index 100% rename from lib/Google/src/Service/Storage/HmacKeysMetadata.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/HmacKeysMetadata.php diff --git a/lib/Google/vendor/google/apiclient-services/src/Storage/ManagedFolder.php b/lib/Google/vendor/google/apiclient-services/src/Storage/ManagedFolder.php new file mode 100644 index 000000000..cca7d25fa --- /dev/null +++ b/lib/Google/vendor/google/apiclient-services/src/Storage/ManagedFolder.php @@ -0,0 +1,170 @@ +bucket = $bucket; + } + /** + * @return string + */ + public function getBucket() + { + return $this->bucket; + } + /** + * @param string + */ + public function setCreateTime($createTime) + { + $this->createTime = $createTime; + } + /** + * @return string + */ + public function getCreateTime() + { + return $this->createTime; + } + /** + * @param string + */ + public function setId($id) + { + $this->id = $id; + } + /** + * @return string + */ + public function getId() + { + return $this->id; + } + /** + * @param string + */ + public function setKind($kind) + { + $this->kind = $kind; + } + /** + * @return string + */ + public function getKind() + { + return $this->kind; + } + /** + * @param string + */ + public function setMetageneration($metageneration) + { + $this->metageneration = $metageneration; + } + /** + * @return string + */ + public function getMetageneration() + { + return $this->metageneration; + } + /** + * @param string + */ + public function setName($name) + { + $this->name = $name; + } + /** + * @return string + */ + public function getName() + { + return $this->name; + } + /** + * @param string + */ + public function setSelfLink($selfLink) + { + $this->selfLink = $selfLink; + } + /** + * @return string + */ + public function getSelfLink() + { + return $this->selfLink; + } + /** + * @param string + */ + public function setUpdateTime($updateTime) + { + $this->updateTime = $updateTime; + } + /** + * @return string + */ + public function getUpdateTime() + { + return $this->updateTime; + } +} + +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(ManagedFolder::class, 'Google_Service_Storage_ManagedFolder'); diff --git a/lib/Google/vendor/google/apiclient-services/src/Storage/ManagedFolders.php b/lib/Google/vendor/google/apiclient-services/src/Storage/ManagedFolders.php new file mode 100644 index 000000000..582c4fe93 --- /dev/null +++ b/lib/Google/vendor/google/apiclient-services/src/Storage/ManagedFolders.php @@ -0,0 +1,79 @@ +items = $items; + } + /** + * @return ManagedFolder[] + */ + public function getItems() + { + return $this->items; + } + /** + * @param string + */ + public function setKind($kind) + { + $this->kind = $kind; + } + /** + * @return string + */ + public function getKind() + { + return $this->kind; + } + /** + * @param string + */ + public function setNextPageToken($nextPageToken) + { + $this->nextPageToken = $nextPageToken; + } + /** + * @return string + */ + public function getNextPageToken() + { + return $this->nextPageToken; + } +} + +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(ManagedFolders::class, 'Google_Service_Storage_ManagedFolders'); diff --git a/lib/Google/src/Service/Storage/Notification.php b/lib/Google/vendor/google/apiclient-services/src/Storage/Notification.php similarity index 100% rename from lib/Google/src/Service/Storage/Notification.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/Notification.php diff --git a/lib/Google/src/Service/Storage/Notifications.php b/lib/Google/vendor/google/apiclient-services/src/Storage/Notifications.php similarity index 100% rename from lib/Google/src/Service/Storage/Notifications.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/Notifications.php diff --git a/lib/Google/src/Service/Storage/ObjectAccessControl.php b/lib/Google/vendor/google/apiclient-services/src/Storage/ObjectAccessControl.php similarity index 100% rename from lib/Google/src/Service/Storage/ObjectAccessControl.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/ObjectAccessControl.php diff --git a/lib/Google/src/Service/Storage/ObjectAccessControlProjectTeam.php b/lib/Google/vendor/google/apiclient-services/src/Storage/ObjectAccessControlProjectTeam.php similarity index 100% rename from lib/Google/src/Service/Storage/ObjectAccessControlProjectTeam.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/ObjectAccessControlProjectTeam.php diff --git a/lib/Google/src/Service/Storage/ObjectAccessControls.php b/lib/Google/vendor/google/apiclient-services/src/Storage/ObjectAccessControls.php similarity index 100% rename from lib/Google/src/Service/Storage/ObjectAccessControls.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/ObjectAccessControls.php diff --git a/lib/Google/src/Service/Storage/Objects.php b/lib/Google/vendor/google/apiclient-services/src/Storage/Objects.php similarity index 100% rename from lib/Google/src/Service/Storage/Objects.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/Objects.php diff --git a/lib/Google/src/Service/Storage/Policy.php b/lib/Google/vendor/google/apiclient-services/src/Storage/Policy.php similarity index 100% rename from lib/Google/src/Service/Storage/Policy.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/Policy.php diff --git a/lib/Google/src/Service/Storage/PolicyBindings.php b/lib/Google/vendor/google/apiclient-services/src/Storage/PolicyBindings.php similarity index 100% rename from lib/Google/src/Service/Storage/PolicyBindings.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/PolicyBindings.php diff --git a/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/AnywhereCache.php b/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/AnywhereCache.php new file mode 100644 index 000000000..5b2a6934a --- /dev/null +++ b/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/AnywhereCache.php @@ -0,0 +1,142 @@ + + * $storageService = new Google\Service\Storage(...); + * $anywhereCache = $storageService->anywhereCache; + * + */ +class AnywhereCache extends \Google\Service\Resource +{ + /** + * Disables an Anywhere Cache instance. (anywhereCache.disable) + * + * @param string $bucket Name of the partent bucket + * @param string $anywhereCacheId The ID of requested Anywhere Cache instance. + * @param array $optParams Optional parameters. + * @return AnywhereCacheModel + */ + public function disable($bucket, $anywhereCacheId, $optParams = []) + { + $params = ['bucket' => $bucket, 'anywhereCacheId' => $anywhereCacheId]; + $params = array_merge($params, $optParams); + return $this->call('disable', [$params], AnywhereCacheModel::class); + } + /** + * Returns the metadata of an Anywhere Cache instance. (anywhereCache.get) + * + * @param string $bucket Name of the partent bucket + * @param string $anywhereCacheId The ID of requested Anywhere Cache instance. + * @param array $optParams Optional parameters. + * @return AnywhereCacheModel + */ + public function get($bucket, $anywhereCacheId, $optParams = []) + { + $params = ['bucket' => $bucket, 'anywhereCacheId' => $anywhereCacheId]; + $params = array_merge($params, $optParams); + return $this->call('get', [$params], AnywhereCacheModel::class); + } + /** + * Creates an Anywhere Cache instance. (anywhereCache.insert) + * + * @param string $bucket Name of the partent bucket + * @param AnywhereCacheModel $postBody + * @param array $optParams Optional parameters. + * @return GoogleLongrunningOperation + */ + public function insert($bucket, AnywhereCacheModel $postBody, $optParams = []) + { + $params = ['bucket' => $bucket, 'postBody' => $postBody]; + $params = array_merge($params, $optParams); + return $this->call('insert', [$params], GoogleLongrunningOperation::class); + } + /** + * Returns a list of Anywhere Cache instances of the bucket matching the + * criteria. (anywhereCache.listAnywhereCache) + * + * @param string $bucket Name of the partent bucket + * @param array $optParams Optional parameters. + * + * @opt_param int pageSize Maximum number of items return in a single page of + * responses. Maximum 1000. + * @opt_param string pageToken A previously-returned page token representing + * part of the larger set of results to view. + * @return AnywhereCaches + */ + public function listAnywhereCache($bucket, $optParams = []) + { + $params = ['bucket' => $bucket]; + $params = array_merge($params, $optParams); + return $this->call('list', [$params], AnywhereCaches::class); + } + /** + * Pauses an Anywhere Cache instance. (anywhereCache.pause) + * + * @param string $bucket Name of the partent bucket + * @param string $anywhereCacheId The ID of requested Anywhere Cache instance. + * @param array $optParams Optional parameters. + * @return AnywhereCacheModel + */ + public function pause($bucket, $anywhereCacheId, $optParams = []) + { + $params = ['bucket' => $bucket, 'anywhereCacheId' => $anywhereCacheId]; + $params = array_merge($params, $optParams); + return $this->call('pause', [$params], AnywhereCacheModel::class); + } + /** + * Resumes a paused or disabled Anywhere Cache instance. (anywhereCache.resume) + * + * @param string $bucket Name of the partent bucket + * @param string $anywhereCacheId The ID of requested Anywhere Cache instance. + * @param array $optParams Optional parameters. + * @return AnywhereCacheModel + */ + public function resume($bucket, $anywhereCacheId, $optParams = []) + { + $params = ['bucket' => $bucket, 'anywhereCacheId' => $anywhereCacheId]; + $params = array_merge($params, $optParams); + return $this->call('resume', [$params], AnywhereCacheModel::class); + } + /** + * Updates the config(ttl and admissionPolicy) of an Anywhere Cache instance. + * (anywhereCache.update) + * + * @param string $bucket Name of the partent bucket + * @param string $anywhereCacheId The ID of requested Anywhere Cache instance. + * @param AnywhereCacheModel $postBody + * @param array $optParams Optional parameters. + * @return GoogleLongrunningOperation + */ + public function update($bucket, $anywhereCacheId, AnywhereCacheModel $postBody, $optParams = []) + { + $params = ['bucket' => $bucket, 'anywhereCacheId' => $anywhereCacheId, 'postBody' => $postBody]; + $params = array_merge($params, $optParams); + return $this->call('update', [$params], GoogleLongrunningOperation::class); + } +} + +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(AnywhereCache::class, 'Google_Service_Storage_Resource_AnywhereCache'); diff --git a/lib/Google/src/Service/Storage/Resource/BucketAccessControls.php b/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/BucketAccessControls.php similarity index 100% rename from lib/Google/src/Service/Storage/Resource/BucketAccessControls.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/Resource/BucketAccessControls.php diff --git a/lib/Google/src/Service/Storage/Resource/Buckets.php b/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Buckets.php similarity index 98% rename from lib/Google/src/Service/Storage/Resource/Buckets.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Buckets.php index 9ba71daae..8e79cb55b 100644 --- a/lib/Google/src/Service/Storage/Resource/Buckets.php +++ b/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Buckets.php @@ -100,6 +100,8 @@ public function getIamPolicy($bucket, $optParams = []) * @param Bucket $postBody * @param array $optParams Optional parameters. * + * @opt_param bool enableObjectRetention When set to true, object retention is + * enabled for this bucket. * @opt_param string predefinedAcl Apply a predefined set of access controls to * this bucket. * @opt_param string predefinedDefaultObjectAcl Apply a predefined set of diff --git a/lib/Google/src/Service/Storage/Resource/Channels.php b/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Channels.php similarity index 100% rename from lib/Google/src/Service/Storage/Resource/Channels.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Channels.php diff --git a/lib/Google/src/Service/Storage/Resource/DefaultObjectAccessControls.php b/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/DefaultObjectAccessControls.php similarity index 99% rename from lib/Google/src/Service/Storage/Resource/DefaultObjectAccessControls.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/Resource/DefaultObjectAccessControls.php index 4bd61bcff..ac0002422 100644 --- a/lib/Google/src/Service/Storage/Resource/DefaultObjectAccessControls.php +++ b/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/DefaultObjectAccessControls.php @@ -101,7 +101,7 @@ public function insert($bucket, ObjectAccessControl $postBody, $optParams = []) * value. * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. - * @return ObjectAccessControls + * @return ObjectAccessControlsModel */ public function listDefaultObjectAccessControls($bucket, $optParams = []) { diff --git a/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/ManagedFolders.php b/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/ManagedFolders.php new file mode 100644 index 000000000..d5e06e144 --- /dev/null +++ b/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/ManagedFolders.php @@ -0,0 +1,171 @@ + + * $storageService = new Google\Service\Storage(...); + * $managedFolders = $storageService->managedFolders; + * + */ +class ManagedFolders extends \Google\Service\Resource +{ + /** + * Permanently deletes a managed folder. (managedFolders.delete) + * + * @param string $bucket Name of the bucket containing the managed folder. + * @param string $managedFolder The managed folder name/path. + * @param array $optParams Optional parameters. + * + * @opt_param string ifMetagenerationMatch If set, only deletes the managed + * folder if its metageneration matches this value. + * @opt_param string ifMetagenerationNotMatch If set, only deletes the managed + * folder if its metageneration does not match this value. + */ + public function delete($bucket, $managedFolder, $optParams = []) + { + $params = ['bucket' => $bucket, 'managedFolder' => $managedFolder]; + $params = array_merge($params, $optParams); + return $this->call('delete', [$params]); + } + /** + * Returns metadata of the specified managed folder. (managedFolders.get) + * + * @param string $bucket Name of the bucket containing the managed folder. + * @param string $managedFolder The managed folder name/path. + * @param array $optParams Optional parameters. + * + * @opt_param string ifMetagenerationMatch Makes the return of the managed + * folder metadata conditional on whether the managed folder's current + * metageneration matches the given value. + * @opt_param string ifMetagenerationNotMatch Makes the return of the managed + * folder metadata conditional on whether the managed folder's current + * metageneration does not match the given value. + * @return ManagedFolder + */ + public function get($bucket, $managedFolder, $optParams = []) + { + $params = ['bucket' => $bucket, 'managedFolder' => $managedFolder]; + $params = array_merge($params, $optParams); + return $this->call('get', [$params], ManagedFolder::class); + } + /** + * Returns an IAM policy for the specified managed folder. + * (managedFolders.getIamPolicy) + * + * @param string $bucket Name of the bucket containing the managed folder. + * @param string $managedFolder The managed folder name/path. + * @param array $optParams Optional parameters. + * + * @opt_param int optionsRequestedPolicyVersion The IAM policy format version to + * be returned. If the optionsRequestedPolicyVersion is for an older version + * that doesn't support part of the requested IAM policy, the request fails. + * @opt_param string userProject The project to be billed for this request. + * Required for Requester Pays buckets. + * @return Policy + */ + public function getIamPolicy($bucket, $managedFolder, $optParams = []) + { + $params = ['bucket' => $bucket, 'managedFolder' => $managedFolder]; + $params = array_merge($params, $optParams); + return $this->call('getIamPolicy', [$params], Policy::class); + } + /** + * Creates a new managed folder. (managedFolders.insert) + * + * @param string $bucket Name of the bucket containing the managed folder. + * @param ManagedFolder $postBody + * @param array $optParams Optional parameters. + * @return ManagedFolder + */ + public function insert($bucket, ManagedFolder $postBody, $optParams = []) + { + $params = ['bucket' => $bucket, 'postBody' => $postBody]; + $params = array_merge($params, $optParams); + return $this->call('insert', [$params], ManagedFolder::class); + } + /** + * Lists managed folders in the given bucket. + * (managedFolders.listManagedFolders) + * + * @param string $bucket Name of the bucket containing the managed folder. + * @param array $optParams Optional parameters. + * + * @opt_param int pageSize Maximum number of items return in a single page of + * responses. + * @opt_param string pageToken A previously-returned page token representing + * part of the larger set of results to view. + * @opt_param string prefix The managed folder name/path prefix to filter the + * output list of results. + * @return ManagedFoldersModel + */ + public function listManagedFolders($bucket, $optParams = []) + { + $params = ['bucket' => $bucket]; + $params = array_merge($params, $optParams); + return $this->call('list', [$params], ManagedFoldersModel::class); + } + /** + * Updates an IAM policy for the specified managed folder. + * (managedFolders.setIamPolicy) + * + * @param string $bucket Name of the bucket containing the managed folder. + * @param string $managedFolder The managed folder name/path. + * @param Policy $postBody + * @param array $optParams Optional parameters. + * + * @opt_param string userProject The project to be billed for this request. + * Required for Requester Pays buckets. + * @return Policy + */ + public function setIamPolicy($bucket, $managedFolder, Policy $postBody, $optParams = []) + { + $params = ['bucket' => $bucket, 'managedFolder' => $managedFolder, 'postBody' => $postBody]; + $params = array_merge($params, $optParams); + return $this->call('setIamPolicy', [$params], Policy::class); + } + /** + * Tests a set of permissions on the given managed folder to see which, if any, + * are held by the caller. (managedFolders.testIamPermissions) + * + * @param string $bucket Name of the bucket containing the managed folder. + * @param string $managedFolder The managed folder name/path. + * @param string|array $permissions Permissions to test. + * @param array $optParams Optional parameters. + * + * @opt_param string userProject The project to be billed for this request. + * Required for Requester Pays buckets. + * @return TestIamPermissionsResponse + */ + public function testIamPermissions($bucket, $managedFolder, $permissions, $optParams = []) + { + $params = ['bucket' => $bucket, 'managedFolder' => $managedFolder, 'permissions' => $permissions]; + $params = array_merge($params, $optParams); + return $this->call('testIamPermissions', [$params], TestIamPermissionsResponse::class); + } +} + +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(ManagedFolders::class, 'Google_Service_Storage_Resource_ManagedFolders'); diff --git a/lib/Google/src/Service/Storage/Resource/Notifications.php b/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Notifications.php similarity index 100% rename from lib/Google/src/Service/Storage/Resource/Notifications.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Notifications.php diff --git a/lib/Google/src/Service/Storage/Resource/ObjectAccessControls.php b/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/ObjectAccessControls.php similarity index 89% rename from lib/Google/src/Service/Storage/Resource/ObjectAccessControls.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/Resource/ObjectAccessControls.php index 7a930ac18..3976d1211 100644 --- a/lib/Google/src/Service/Storage/Resource/ObjectAccessControls.php +++ b/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/ObjectAccessControls.php @@ -36,7 +36,8 @@ class ObjectAccessControls extends \Google\Service\Resource * * @param string $bucket Name of a bucket. * @param string $object Name of the object. For information about how to URL - * encode object names to be path safe, see Encoding URI Path Parts. + * encode object names to be path safe, see [Encoding URI Path + * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. @@ -59,7 +60,8 @@ public function delete($bucket, $object, $entity, $optParams = []) * * @param string $bucket Name of a bucket. * @param string $object Name of the object. For information about how to URL - * encode object names to be path safe, see Encoding URI Path Parts. + * encode object names to be path safe, see [Encoding URI Path + * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. @@ -83,7 +85,8 @@ public function get($bucket, $object, $entity, $optParams = []) * * @param string $bucket Name of a bucket. * @param string $object Name of the object. For information about how to URL - * encode object names to be path safe, see Encoding URI Path Parts. + * encode object names to be path safe, see [Encoding URI Path + * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param ObjectAccessControl $postBody * @param array $optParams Optional parameters. * @@ -105,7 +108,8 @@ public function insert($bucket, $object, ObjectAccessControl $postBody, $optPara * * @param string $bucket Name of a bucket. * @param string $object Name of the object. For information about how to URL - * encode object names to be path safe, see Encoding URI Path Parts. + * encode object names to be path safe, see [Encoding URI Path + * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param array $optParams Optional parameters. * * @opt_param string generation If present, selects a specific revision of this @@ -125,7 +129,8 @@ public function listObjectAccessControls($bucket, $object, $optParams = []) * * @param string $bucket Name of a bucket. * @param string $object Name of the object. For information about how to URL - * encode object names to be path safe, see Encoding URI Path Parts. + * encode object names to be path safe, see [Encoding URI Path + * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. @@ -149,7 +154,8 @@ public function patch($bucket, $object, $entity, ObjectAccessControl $postBody, * * @param string $bucket Name of a bucket. * @param string $object Name of the object. For information about how to URL - * encode object names to be path safe, see Encoding URI Path Parts. + * encode object names to be path safe, see [Encoding URI Path + * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. diff --git a/lib/Google/src/Service/Storage/Resource/Objects.php b/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Objects.php similarity index 83% rename from lib/Google/src/Service/Storage/Resource/Objects.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Objects.php index c74c0a9a3..fe3998c99 100644 --- a/lib/Google/src/Service/Storage/Resource/Objects.php +++ b/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Objects.php @@ -17,8 +17,10 @@ namespace Google\Service\Storage\Resource; +use Google\Service\Storage\BulkRestoreObjectsRequest; use Google\Service\Storage\Channel; use Google\Service\Storage\ComposeRequest; +use Google\Service\Storage\GoogleLongrunningOperation; use Google\Service\Storage\Objects as ObjectsModel; use Google\Service\Storage\Policy; use Google\Service\Storage\RewriteResponse; @@ -35,6 +37,21 @@ */ class Objects extends \Google\Service\Resource { + /** + * Initiates a long-running bulk restore operation on the specified bucket. + * (objects.bulkRestore) + * + * @param string $bucket Name of the bucket in which the object resides. + * @param BulkRestoreObjectsRequest $postBody + * @param array $optParams Optional parameters. + * @return GoogleLongrunningOperation + */ + public function bulkRestore($bucket, BulkRestoreObjectsRequest $postBody, $optParams = []) + { + $params = ['bucket' => $bucket, 'postBody' => $postBody]; + $params = array_merge($params, $optParams); + return $this->call('bulkRestore', [$params], GoogleLongrunningOperation::class); + } /** * Concatenates a list of existing objects into a new object in the same bucket. * (objects.compose) @@ -42,8 +59,8 @@ class Objects extends \Google\Service\Resource * @param string $destinationBucket Name of the bucket containing the source * objects. The destination object is stored in this bucket. * @param string $destinationObject Name of the new object. For information - * about how to URL encode object names to be path safe, see Encoding URI Path - * Parts. + * about how to URL encode object names to be path safe, see [Encoding URI Path + * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param ComposeRequest $postBody * @param array $optParams Optional parameters. * @@ -75,11 +92,13 @@ public function compose($destinationBucket, $destinationObject, ComposeRequest $ * @param string $sourceBucket Name of the bucket in which to find the source * object. * @param string $sourceObject Name of the source object. For information about - * how to URL encode object names to be path safe, see Encoding URI Path Parts. + * how to URL encode object names to be path safe, see [Encoding URI Path + * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param string $destinationBucket Name of the bucket in which to store the new * object. Overrides the provided object metadata's bucket value, if any.For * information about how to URL encode object names to be path safe, see - * Encoding URI Path Parts. + * [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request- + * endpoints#encoding). * @param string $destinationObject Name of the new object. Required when the * object metadata is not otherwise provided. Overrides the object metadata's * name value, if any. @@ -87,9 +106,9 @@ public function compose($destinationBucket, $destinationObject, ComposeRequest $ * @param array $optParams Optional parameters. * * @opt_param string destinationKmsKeyName Resource name of the Cloud KMS key, - * of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys - * /my-key, that will be used to encrypt the object. Overrides the object - * metadata's kms_key_name value, if any. + * of the form projects/my-project/locations/global/keyRings/my- + * kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the + * object metadata's kms_key_name value, if any. * @opt_param string destinationPredefinedAcl Apply a predefined set of access * controls to the destination object. * @opt_param string ifGenerationMatch Makes the operation conditional on @@ -139,7 +158,8 @@ public function copy($sourceBucket, $sourceObject, $destinationBucket, $destinat * * @param string $bucket Name of the bucket in which the object resides. * @param string $object Name of the object. For information about how to URL - * encode object names to be path safe, see Encoding URI Path Parts. + * encode object names to be path safe, see [Encoding URI Path + * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param array $optParams Optional parameters. * * @opt_param string generation If present, permanently deletes a specific @@ -169,7 +189,8 @@ public function delete($bucket, $object, $optParams = []) * * @param string $bucket Name of the bucket in which the object resides. * @param string $object Name of the object. For information about how to URL - * encode object names to be path safe, see Encoding URI Path Parts. + * encode object names to be path safe, see [Encoding URI Path + * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param array $optParams Optional parameters. * * @opt_param string generation If present, selects a specific revision of this @@ -186,6 +207,8 @@ public function delete($bucket, $object, $optParams = []) * @opt_param string ifMetagenerationNotMatch Makes the operation conditional on * whether the object's current metageneration does not match the given value. * @opt_param string projection Set of properties to return. Defaults to noAcl. + * @opt_param bool softDeleted If true, only soft-deleted object versions will + * be listed. The default is false. For more information, see Soft Delete. * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return StorageObject @@ -201,7 +224,8 @@ public function get($bucket, $object, $optParams = []) * * @param string $bucket Name of the bucket in which the object resides. * @param string $object Name of the object. For information about how to URL - * encode object names to be path safe, see Encoding URI Path Parts. + * encode object names to be path safe, see [Encoding URI Path + * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param array $optParams Optional parameters. * * @opt_param string generation If present, selects a specific revision of this @@ -247,7 +271,8 @@ public function getIamPolicy($bucket, $object, $optParams = []) * @opt_param string name Name of the object. Required when the object metadata * is not otherwise provided. Overrides the object metadata's name value, if * any. For information about how to URL encode object names to be path safe, - * see Encoding URI Path Parts. + * see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request- + * endpoints#encoding). * @opt_param string predefinedAcl Apply a predefined set of access controls to * this object. * @opt_param string projection Set of properties to return. Defaults to noAcl, @@ -278,6 +303,9 @@ public function insert($bucket, StorageObject $postBody, $optParams = []) * lexicographically before endOffset. If startOffset is also set, the objects * listed will have names between startOffset (inclusive) and endOffset * (exclusive). + * @opt_param bool includeFoldersAsPrefixes Only applicable if delimiter is set + * to '/'. If true, will also include folders and managed folders (besides + * objects) in the returned prefixes. * @opt_param bool includeTrailingDelimiter If true, objects that end in exactly * one instance of delimiter will have their metadata included in items in * addition to prefixes. @@ -292,6 +320,8 @@ public function insert($bucket, StorageObject $postBody, $optParams = []) * @opt_param string prefix Filter results to objects whose names begin with * this prefix. * @opt_param string projection Set of properties to return. Defaults to noAcl. + * @opt_param bool softDeleted If true, only soft-deleted object versions will + * be listed. The default is false. For more information, see Soft Delete. * @opt_param string startOffset Filter results to objects whose names are * lexicographically equal to or after startOffset. If endOffset is also set, * the objects listed will have names between startOffset (inclusive) and @@ -313,7 +343,8 @@ public function listObjects($bucket, $optParams = []) * * @param string $bucket Name of the bucket in which the object resides. * @param string $object Name of the object. For information about how to URL - * encode object names to be path safe, see Encoding URI Path Parts. + * encode object names to be path safe, see [Encoding URI Path + * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param StorageObject $postBody * @param array $optParams Optional parameters. * @@ -330,6 +361,9 @@ public function listObjects($bucket, $optParams = []) * whether the object's current metageneration matches the given value. * @opt_param string ifMetagenerationNotMatch Makes the operation conditional on * whether the object's current metageneration does not match the given value. + * @opt_param bool overrideUnlockedRetention Must be true to remove the + * retention configuration, reduce its unlocked retention period, or change its + * mode from unlocked to locked. * @opt_param string predefinedAcl Apply a predefined set of access controls to * this object. * @opt_param string projection Set of properties to return. Defaults to full. @@ -343,6 +377,41 @@ public function patch($bucket, $object, StorageObject $postBody, $optParams = [] $params = array_merge($params, $optParams); return $this->call('patch', [$params], StorageObject::class); } + /** + * Restores a soft-deleted object. (objects.restore) + * + * @param string $bucket Name of the bucket in which the object resides. + * @param string $object Name of the object. For information about how to URL + * encode object names to be path safe, see Encoding URI Path Parts. + * @param string $generation Selects a specific revision of this object. + * @param StorageObject $postBody + * @param array $optParams Optional parameters. + * + * @opt_param bool copySourceAcl If true, copies the source object's ACL; + * otherwise, uses the bucket's default object ACL. The default is false. + * @opt_param string ifGenerationMatch Makes the operation conditional on + * whether the object's one live generation matches the given value. Setting to + * 0 makes the operation succeed only if there are no live versions of the + * object. + * @opt_param string ifGenerationNotMatch Makes the operation conditional on + * whether none of the object's live generations match the given value. If no + * live object exists, the precondition fails. Setting to 0 makes the operation + * succeed only if there is a live version of the object. + * @opt_param string ifMetagenerationMatch Makes the operation conditional on + * whether the object's one live metageneration matches the given value. + * @opt_param string ifMetagenerationNotMatch Makes the operation conditional on + * whether none of the object's live metagenerations match the given value. + * @opt_param string projection Set of properties to return. Defaults to full. + * @opt_param string userProject The project to be billed for this request. + * Required for Requester Pays buckets. + * @return StorageObject + */ + public function restore($bucket, $object, $generation, StorageObject $postBody, $optParams = []) + { + $params = ['bucket' => $bucket, 'object' => $object, 'generation' => $generation, 'postBody' => $postBody]; + $params = array_merge($params, $optParams); + return $this->call('restore', [$params], StorageObject::class); + } /** * Rewrites a source object to a destination object. Optionally overrides * metadata. (objects.rewrite) @@ -350,20 +419,22 @@ public function patch($bucket, $object, StorageObject $postBody, $optParams = [] * @param string $sourceBucket Name of the bucket in which to find the source * object. * @param string $sourceObject Name of the source object. For information about - * how to URL encode object names to be path safe, see Encoding URI Path Parts. + * how to URL encode object names to be path safe, see [Encoding URI Path + * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param string $destinationBucket Name of the bucket in which to store the new * object. Overrides the provided object metadata's bucket value, if any. * @param string $destinationObject Name of the new object. Required when the * object metadata is not otherwise provided. Overrides the object metadata's * name value, if any. For information about how to URL encode object names to - * be path safe, see Encoding URI Path Parts. + * be path safe, see [Encoding URI Path + * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param StorageObject $postBody * @param array $optParams Optional parameters. * * @opt_param string destinationKmsKeyName Resource name of the Cloud KMS key, - * of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys - * /my-key, that will be used to encrypt the object. Overrides the object - * metadata's kms_key_name value, if any. + * of the form projects/my-project/locations/global/keyRings/my- + * kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the + * object metadata's kms_key_name value, if any. * @opt_param string destinationPredefinedAcl Apply a predefined set of access * controls to the destination object. * @opt_param string ifGenerationMatch Makes the operation conditional on @@ -422,7 +493,8 @@ public function rewrite($sourceBucket, $sourceObject, $destinationBucket, $desti * * @param string $bucket Name of the bucket in which the object resides. * @param string $object Name of the object. For information about how to URL - * encode object names to be path safe, see Encoding URI Path Parts. + * encode object names to be path safe, see [Encoding URI Path + * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param Policy $postBody * @param array $optParams Optional parameters. * @@ -444,7 +516,8 @@ public function setIamPolicy($bucket, $object, Policy $postBody, $optParams = [] * * @param string $bucket Name of the bucket in which the object resides. * @param string $object Name of the object. For information about how to URL - * encode object names to be path safe, see Encoding URI Path Parts. + * encode object names to be path safe, see [Encoding URI Path + * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param string|array $permissions Permissions to test. * @param array $optParams Optional parameters. * @@ -465,7 +538,8 @@ public function testIamPermissions($bucket, $object, $permissions, $optParams = * * @param string $bucket Name of the bucket in which the object resides. * @param string $object Name of the object. For information about how to URL - * encode object names to be path safe, see Encoding URI Path Parts. + * encode object names to be path safe, see [Encoding URI Path + * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param StorageObject $postBody * @param array $optParams Optional parameters. * @@ -482,6 +556,9 @@ public function testIamPermissions($bucket, $object, $permissions, $optParams = * whether the object's current metageneration matches the given value. * @opt_param string ifMetagenerationNotMatch Makes the operation conditional on * whether the object's current metageneration does not match the given value. + * @opt_param bool overrideUnlockedRetention Must be true to remove the + * retention configuration, reduce its unlocked retention period, or change its + * mode from unlocked to locked. * @opt_param string predefinedAcl Apply a predefined set of access controls to * this object. * @opt_param string projection Set of properties to return. Defaults to full. diff --git a/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Operations.php b/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Operations.php new file mode 100644 index 000000000..bff19b4b4 --- /dev/null +++ b/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Operations.php @@ -0,0 +1,88 @@ + + * $storageService = new Google\Service\Storage(...); + * $operations = $storageService->operations; + * + */ +class Operations extends \Google\Service\Resource +{ + /** + * Starts asynchronous cancellation on a long-running operation. The server + * makes a best effort to cancel the operation, but success is not guaranteed. + * (operations.cancel) + * + * @param string $bucket The parent bucket of the operation resource. + * @param string $operationId The ID of the operation resource. + * @param array $optParams Optional parameters. + */ + public function cancel($bucket, $operationId, $optParams = []) + { + $params = ['bucket' => $bucket, 'operationId' => $operationId]; + $params = array_merge($params, $optParams); + return $this->call('cancel', [$params]); + } + /** + * Gets the latest state of a long-running operation. (operations.get) + * + * @param string $bucket The parent bucket of the operation resource. + * @param string $operationId The ID of the operation resource. + * @param array $optParams Optional parameters. + * @return GoogleLongrunningOperation + */ + public function get($bucket, $operationId, $optParams = []) + { + $params = ['bucket' => $bucket, 'operationId' => $operationId]; + $params = array_merge($params, $optParams); + return $this->call('get', [$params], GoogleLongrunningOperation::class); + } + /** + * Lists operations that match the specified filter in the request. + * (operations.listOperations) + * + * @param string $bucket Name of the bucket in which to look for operations. + * @param array $optParams Optional parameters. + * + * @opt_param string filter A filter to narrow down results to a preferred + * subset. The filtering language is documented in more detail in + * [AIP-160](https://google.aip.dev/160). + * @opt_param int pageSize Maximum number of items to return in a single page of + * responses. Fewer total results may be returned than requested. The service + * uses this parameter or 100 items, whichever is smaller. + * @opt_param string pageToken A previously-returned page token representing + * part of the larger set of results to view. + * @return GoogleLongrunningListOperationsResponse + */ + public function listOperations($bucket, $optParams = []) + { + $params = ['bucket' => $bucket]; + $params = array_merge($params, $optParams); + return $this->call('list', [$params], GoogleLongrunningListOperationsResponse::class); + } +} + +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(Operations::class, 'Google_Service_Storage_Resource_Operations'); diff --git a/lib/Google/src/Service/Storage/Resource/Projects.php b/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Projects.php similarity index 100% rename from lib/Google/src/Service/Storage/Resource/Projects.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Projects.php diff --git a/lib/Google/src/Service/Storage/Resource/ProjectsHmacKeys.php b/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/ProjectsHmacKeys.php similarity index 100% rename from lib/Google/src/Service/Storage/Resource/ProjectsHmacKeys.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/Resource/ProjectsHmacKeys.php diff --git a/lib/Google/src/Service/Storage/Resource/ProjectsServiceAccount.php b/lib/Google/vendor/google/apiclient-services/src/Storage/Resource/ProjectsServiceAccount.php similarity index 100% rename from lib/Google/src/Service/Storage/Resource/ProjectsServiceAccount.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/Resource/ProjectsServiceAccount.php diff --git a/lib/Google/src/Service/Storage/RewriteResponse.php b/lib/Google/vendor/google/apiclient-services/src/Storage/RewriteResponse.php similarity index 100% rename from lib/Google/src/Service/Storage/RewriteResponse.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/RewriteResponse.php diff --git a/lib/Google/src/Service/Storage/ServiceAccount.php b/lib/Google/vendor/google/apiclient-services/src/Storage/ServiceAccount.php similarity index 100% rename from lib/Google/src/Service/Storage/ServiceAccount.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/ServiceAccount.php diff --git a/lib/Google/src/Service/Storage/StorageObject.php b/lib/Google/vendor/google/apiclient-services/src/Storage/StorageObject.php similarity index 91% rename from lib/Google/src/Service/Storage/StorageObject.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/StorageObject.php index 2ca42efcd..cb666b2ae 100644 --- a/lib/Google/src/Service/Storage/StorageObject.php +++ b/lib/Google/vendor/google/apiclient-services/src/Storage/StorageObject.php @@ -72,6 +72,10 @@ class StorageObject extends \Google\Collection * @var string */ public $generation; + /** + * @var string + */ + public $hardDeleteTime; /** * @var string */ @@ -106,6 +110,8 @@ class StorageObject extends \Google\Collection public $name; protected $ownerType = StorageObjectOwner::class; protected $ownerDataType = ''; + protected $retentionType = StorageObjectRetention::class; + protected $retentionDataType = ''; /** * @var string */ @@ -118,6 +124,10 @@ class StorageObject extends \Google\Collection * @var string */ public $size; + /** + * @var string + */ + public $softDeleteTime; /** * @var string */ @@ -339,6 +349,20 @@ public function getGeneration() { return $this->generation; } + /** + * @param string + */ + public function setHardDeleteTime($hardDeleteTime) + { + $this->hardDeleteTime = $hardDeleteTime; + } + /** + * @return string + */ + public function getHardDeleteTime() + { + return $this->hardDeleteTime; + } /** * @param string */ @@ -465,6 +489,20 @@ public function getOwner() { return $this->owner; } + /** + * @param StorageObjectRetention + */ + public function setRetention(StorageObjectRetention $retention) + { + $this->retention = $retention; + } + /** + * @return StorageObjectRetention + */ + public function getRetention() + { + return $this->retention; + } /** * @param string */ @@ -507,6 +545,20 @@ public function getSize() { return $this->size; } + /** + * @param string + */ + public function setSoftDeleteTime($softDeleteTime) + { + $this->softDeleteTime = $softDeleteTime; + } + /** + * @return string + */ + public function getSoftDeleteTime() + { + return $this->softDeleteTime; + } /** * @param string */ diff --git a/lib/Google/src/Service/Storage/StorageObjectCustomerEncryption.php b/lib/Google/vendor/google/apiclient-services/src/Storage/StorageObjectCustomerEncryption.php similarity index 100% rename from lib/Google/src/Service/Storage/StorageObjectCustomerEncryption.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/StorageObjectCustomerEncryption.php diff --git a/lib/Google/src/Service/Storage/StorageObjectOwner.php b/lib/Google/vendor/google/apiclient-services/src/Storage/StorageObjectOwner.php similarity index 100% rename from lib/Google/src/Service/Storage/StorageObjectOwner.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/StorageObjectOwner.php diff --git a/lib/Google/vendor/google/apiclient-services/src/Storage/StorageObjectRetention.php b/lib/Google/vendor/google/apiclient-services/src/Storage/StorageObjectRetention.php new file mode 100644 index 000000000..d871f9afa --- /dev/null +++ b/lib/Google/vendor/google/apiclient-services/src/Storage/StorageObjectRetention.php @@ -0,0 +1,62 @@ +mode = $mode; + } + /** + * @return string + */ + public function getMode() + { + return $this->mode; + } + /** + * @param string + */ + public function setRetainUntilTime($retainUntilTime) + { + $this->retainUntilTime = $retainUntilTime; + } + /** + * @return string + */ + public function getRetainUntilTime() + { + return $this->retainUntilTime; + } +} + +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(StorageObjectRetention::class, 'Google_Service_Storage_StorageObjectRetention'); diff --git a/lib/Google/src/Service/Storage/TestIamPermissionsResponse.php b/lib/Google/vendor/google/apiclient-services/src/Storage/TestIamPermissionsResponse.php similarity index 100% rename from lib/Google/src/Service/Storage/TestIamPermissionsResponse.php rename to lib/Google/vendor/google/apiclient-services/src/Storage/TestIamPermissionsResponse.php diff --git a/lib/Google/vendor/google/auth/README.md b/lib/Google/vendor/google/auth/README.md index 91f12b2db..87f6f6064 100644 --- a/lib/Google/vendor/google/auth/README.md +++ b/lib/Google/vendor/google/auth/README.md @@ -257,6 +257,18 @@ print_r((string) $response->getBody()); [iap-proxy-header]: https://cloud.google.com/iap/docs/authentication-howto#authenticating_from_proxy-authorization_header +#### External credentials (Workload identity federation) + +Using workload identity federation, your application can access Google Cloud resources from Amazon Web Services (AWS), +Microsoft Azure or any identity provider that supports OpenID Connect (OIDC). + +Traditionally, applications running outside Google Cloud have used service account keys to access Google Cloud +resources. Using identity federation, you can allow your workload to impersonate a service account. This lets you access +Google Cloud resources directly, eliminating the maintenance and security burden associated with service account keys. + +Follow the detailed instructions on how to +[Configure Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation-with-other-clouds). + #### Verifying JWTs If you are [using Google ID tokens to authenticate users][google-id-tokens], use diff --git a/lib/Google/vendor/google/auth/composer.json b/lib/Google/vendor/google/auth/composer.json index 47f673c48..9e6466d61 100644 --- a/lib/Google/vendor/google/auth/composer.json +++ b/lib/Google/vendor/google/auth/composer.json @@ -17,13 +17,13 @@ "psr/cache": "^1.0||^2.0||^3.0" }, "require-dev": { - "guzzlehttp/promises": "^1.3", + "guzzlehttp/promises": "^2.0", "squizlabs/php_codesniffer": "^3.5", "phpunit/phpunit": "^9.0.0", "phpspec/prophecy-phpunit": "^2.0", "sebastian/comparator": ">=1.2.3", "phpseclib/phpseclib": "^3.0", - "kelvinmo/simplejwt": "0.7.0" + "kelvinmo/simplejwt": "0.7.1" }, "suggest": { "phpseclib/phpseclib": "May be used in place of OpenSSL for signing strings or for token management. Please require version ^2." diff --git a/lib/Google/vendor/google/auth/src/AccessToken.php b/lib/Google/vendor/google/auth/src/AccessToken.php index 52bad396e..0afc4ca1e 100644 --- a/lib/Google/vendor/google/auth/src/AccessToken.php +++ b/lib/Google/vendor/google/auth/src/AccessToken.php @@ -18,7 +18,6 @@ namespace Google\Auth; use DateTime; -use Exception; use Firebase\JWT\ExpiredException; use Firebase\JWT\JWT; use Firebase\JWT\Key; @@ -312,11 +311,9 @@ private function getCerts($location, $cacheKey, array $options = []) $cacheItem = $this->cache->getItem($cacheKey); $certs = $cacheItem ? $cacheItem->get() : null; - $gotNewCerts = false; + $expireTime = null; if (!$certs) { - $certs = $this->retrieveCertsFromLocation($location, $options); - - $gotNewCerts = true; + list($certs, $expireTime) = $this->retrieveCertsFromLocation($location, $options); } if (!isset($certs['keys'])) { @@ -332,8 +329,8 @@ private function getCerts($location, $cacheKey, array $options = []) // Push caching off until after verifying certs are in a valid format. // Don't want to cache bad data. - if ($gotNewCerts) { - $cacheItem->expiresAt(new DateTime('+1 hour')); + if ($expireTime) { + $cacheItem->expiresAt(new DateTime($expireTime)); $cacheItem->set($certs); $this->cache->save($cacheItem); } @@ -346,13 +343,14 @@ private function getCerts($location, $cacheKey, array $options = []) * * @param string $url location * @param array $options [optional] Configuration options. - * @return array certificates + * @return array{array, string} * @throws InvalidArgumentException If certs could not be retrieved from a local file. * @throws RuntimeException If certs could not be retrieved from a remote location. */ private function retrieveCertsFromLocation($url, array $options = []) { // If we're retrieving a local file, just grab it. + $expireTime = '+1 hour'; if (strpos($url, 'http') !== 0) { if (!file_exists($url)) { throw new InvalidArgumentException(sprintf( @@ -361,14 +359,28 @@ private function retrieveCertsFromLocation($url, array $options = []) )); } - return json_decode((string) file_get_contents($url), true); + return [ + json_decode((string) file_get_contents($url), true), + $expireTime + ]; } $httpHandler = $this->httpHandler; $response = $httpHandler(new Request('GET', $url), $options); if ($response->getStatusCode() == 200) { - return json_decode((string) $response->getBody(), true); + if ($cacheControl = $response->getHeaderLine('Cache-Control')) { + array_map(function ($value) use (&$expireTime) { + list($key, $value) = explode('=', $value) + [null, null]; + if (trim($key) == 'max-age') { + $expireTime = '+' . $value . ' seconds'; + } + }, explode(',', $cacheControl)); + } + return [ + json_decode((string) $response->getBody(), true), + $expireTime + ]; } throw new RuntimeException(sprintf( @@ -409,7 +421,7 @@ private function loadPhpsecPublicKey(string $modulus, string $exponent): string $exponent ]), 256), ]); - return $key->toString('PKCS1'); + return $key->toString('PKCS8'); } /** diff --git a/lib/Google/vendor/google/auth/src/CredentialSource/AwsNativeSource.php b/lib/Google/vendor/google/auth/src/CredentialSource/AwsNativeSource.php new file mode 100644 index 000000000..3a8c20eaa --- /dev/null +++ b/lib/Google/vendor/google/auth/src/CredentialSource/AwsNativeSource.php @@ -0,0 +1,360 @@ +audience = $audience; + $this->regionalCredVerificationUrl = $regionalCredVerificationUrl; + $this->regionUrl = $regionUrl; + $this->securityCredentialsUrl = $securityCredentialsUrl; + $this->imdsv2SessionTokenUrl = $imdsv2SessionTokenUrl; + } + + public function fetchSubjectToken(callable $httpHandler = null): string + { + if (is_null($httpHandler)) { + $httpHandler = HttpHandlerFactory::build(HttpClientCache::getHttpClient()); + } + + $headers = []; + if ($this->imdsv2SessionTokenUrl) { + $headers = [ + 'X-aws-ec2-metadata-token' => self::getImdsV2SessionToken($this->imdsv2SessionTokenUrl, $httpHandler) + ]; + } + + if (!$signingVars = self::getSigningVarsFromEnv()) { + if (!$this->securityCredentialsUrl) { + throw new \LogicException('Unable to get credentials from ENV, and no security credentials URL provided'); + } + $signingVars = self::getSigningVarsFromUrl( + $httpHandler, + $this->securityCredentialsUrl, + self::getRoleName($httpHandler, $this->securityCredentialsUrl, $headers), + $headers + ); + } + + if (!$region = self::getRegionFromEnv()) { + if (!$this->regionUrl) { + throw new \LogicException('Unable to get region from ENV, and no region URL provided'); + } + $region = self::getRegionFromUrl($httpHandler, $this->regionUrl, $headers); + } + $url = str_replace('{region}', $region, $this->regionalCredVerificationUrl); + $host = parse_url($url)['host'] ?? ''; + + // From here we use the signing vars to create the signed request to receive a token + [$accessKeyId, $secretAccessKey, $securityToken] = $signingVars; + $headers = self::getSignedRequestHeaders($region, $host, $accessKeyId, $secretAccessKey, $securityToken); + + // Inject x-goog-cloud-target-resource into header + $headers['x-goog-cloud-target-resource'] = $this->audience; + + // Format headers as they're expected in the subject token + $formattedHeaders= array_map( + fn ($k, $v) => ['key' => $k, 'value' => $v], + array_keys($headers), + $headers, + ); + + $request = [ + 'headers' => $formattedHeaders, + 'method' => 'POST', + 'url' => $url, + ]; + + return urlencode(json_encode($request) ?: ''); + } + + /** + * @internal + */ + public static function getImdsV2SessionToken(string $imdsV2Url, callable $httpHandler): string + { + $headers = [ + 'X-aws-ec2-metadata-token-ttl-seconds' => '21600' + ]; + $request = new Request( + 'PUT', + $imdsV2Url, + $headers + ); + + $response = $httpHandler($request); + return (string) $response->getBody(); + } + + /** + * @see http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html + * + * @internal + * + * @return array + */ + public static function getSignedRequestHeaders( + string $region, + string $host, + string $accessKeyId, + string $secretAccessKey, + ?string $securityToken + ): array { + $service = 'sts'; + + # Create a date for headers and the credential string in ISO-8601 format + $amzdate = date('Ymd\THis\Z'); + $datestamp = date('Ymd'); # Date w/o time, used in credential scope + + # Create the canonical headers and signed headers. Header names + # must be trimmed and lowercase, and sorted in code point order from + # low to high. Note that there is a trailing \n. + $canonicalHeaders = sprintf("host:%s\nx-amz-date:%s\n", $host, $amzdate); + if ($securityToken) { + $canonicalHeaders .= sprintf("x-amz-security-token:%s\n", $securityToken); + } + + # Step 5: Create the list of signed headers. This lists the headers + # in the canonicalHeaders list, delimited with ";" and in alpha order. + # Note: The request can include any headers; $canonicalHeaders and + # $signedHeaders lists those that you want to be included in the + # hash of the request. "Host" and "x-amz-date" are always required. + $signedHeaders = 'host;x-amz-date'; + if ($securityToken) { + $signedHeaders .= ';x-amz-security-token'; + } + + # Step 6: Create payload hash (hash of the request body content). For GET + # requests, the payload is an empty string (""). + $payloadHash = hash('sha256', ''); + + # Step 7: Combine elements to create canonical request + $canonicalRequest = implode("\n", [ + 'POST', // method + '/', // canonical URL + self::CRED_VERIFICATION_QUERY, // query string + $canonicalHeaders, + $signedHeaders, + $payloadHash + ]); + + # ************* TASK 2: CREATE THE STRING TO SIGN************* + # Match the algorithm to the hashing algorithm you use, either SHA-1 or + # SHA-256 (recommended) + $algorithm = 'AWS4-HMAC-SHA256'; + $scope = implode('/', [$datestamp, $region, $service, 'aws4_request']); + $stringToSign = implode("\n", [$algorithm, $amzdate, $scope, hash('sha256', $canonicalRequest)]); + + # ************* TASK 3: CALCULATE THE SIGNATURE ************* + # Create the signing key using the function defined above. + // (done above) + $signingKey = self::getSignatureKey($secretAccessKey, $datestamp, $region, $service); + + # Sign the string_to_sign using the signing_key + $signature = bin2hex(self::hmacSign($signingKey, $stringToSign)); + + # ************* TASK 4: ADD SIGNING INFORMATION TO THE REQUEST ************* + # The signing information can be either in a query string value or in + # a header named Authorization. This code shows how to use a header. + # Create authorization header and add to request headers + $authorizationHeader = sprintf( + '%s Credential=%s/%s, SignedHeaders=%s, Signature=%s', + $algorithm, + $accessKeyId, + $scope, + $signedHeaders, + $signature + ); + + # The request can include any headers, but MUST include "host", "x-amz-date", + # and (for this scenario) "Authorization". "host" and "x-amz-date" must + # be included in the canonical_headers and signed_headers, as noted + # earlier. Order here is not significant. + $headers = [ + 'host' => $host, + 'x-amz-date' => $amzdate, + 'Authorization' => $authorizationHeader, + ]; + if ($securityToken) { + $headers['x-amz-security-token'] = $securityToken; + } + + return $headers; + } + + /** + * @internal + */ + public static function getRegionFromEnv(): ?string + { + $region = getenv('AWS_REGION'); + if (empty($region)) { + $region = getenv('AWS_DEFAULT_REGION'); + } + return $region ?: null; + } + + /** + * @internal + * + * @param callable $httpHandler + * @param string $regionUrl + * @param array $headers Request headers to send in with the request. + */ + public static function getRegionFromUrl(callable $httpHandler, string $regionUrl, array $headers): string + { + // get the region/zone from the region URL + $regionRequest = new Request('GET', $regionUrl, $headers); + $regionResponse = $httpHandler($regionRequest); + + // Remove last character. For example, if us-east-2b is returned, + // the region would be us-east-2. + return substr((string) $regionResponse->getBody(), 0, -1); + } + + /** + * @internal + * + * @param callable $httpHandler + * @param string $securityCredentialsUrl + * @param array $headers Request headers to send in with the request. + */ + public static function getRoleName(callable $httpHandler, string $securityCredentialsUrl, array $headers): string + { + // Get the AWS role name + $roleRequest = new Request('GET', $securityCredentialsUrl, $headers); + $roleResponse = $httpHandler($roleRequest); + $roleName = (string) $roleResponse->getBody(); + + return $roleName; + } + + /** + * @internal + * + * @param callable $httpHandler + * @param string $securityCredentialsUrl + * @param array $headers Request headers to send in with the request. + * @return array{string, string, ?string} + */ + public static function getSigningVarsFromUrl( + callable $httpHandler, + string $securityCredentialsUrl, + string $roleName, + array $headers + ): array { + // Get the AWS credentials + $credsRequest = new Request( + 'GET', + $securityCredentialsUrl . '/' . $roleName, + $headers + ); + $credsResponse = $httpHandler($credsRequest); + $awsCreds = json_decode((string) $credsResponse->getBody(), true); + return [ + $awsCreds['AccessKeyId'], // accessKeyId + $awsCreds['SecretAccessKey'], // secretAccessKey + $awsCreds['Token'], // token + ]; + } + + /** + * @internal + * + * @return array{string, string, ?string} + */ + public static function getSigningVarsFromEnv(): ?array + { + $accessKeyId = getenv('AWS_ACCESS_KEY_ID'); + $secretAccessKey = getenv('AWS_SECRET_ACCESS_KEY'); + if ($accessKeyId && $secretAccessKey) { + return [ + $accessKeyId, + $secretAccessKey, + getenv('AWS_SESSION_TOKEN') ?: null, // session token (can be null) + ]; + } + + return null; + } + + /** + * Return HMAC hash in binary string + */ + private static function hmacSign(string $key, string $msg): string + { + return hash_hmac('sha256', self::utf8Encode($msg), $key, true); + } + + /** + * @TODO add a fallback when mbstring is not available + */ + private static function utf8Encode(string $string): string + { + return mb_convert_encoding($string, 'UTF-8', 'ISO-8859-1'); + } + + private static function getSignatureKey( + string $key, + string $dateStamp, + string $regionName, + string $serviceName + ): string { + $kDate = self::hmacSign(self::utf8Encode('AWS4' . $key), $dateStamp); + $kRegion = self::hmacSign($kDate, $regionName); + $kService = self::hmacSign($kRegion, $serviceName); + $kSigning = self::hmacSign($kService, 'aws4_request'); + + return $kSigning; + } +} diff --git a/lib/Google/vendor/google/auth/src/CredentialSource/FileSource.php b/lib/Google/vendor/google/auth/src/CredentialSource/FileSource.php new file mode 100644 index 000000000..e2afc6c58 --- /dev/null +++ b/lib/Google/vendor/google/auth/src/CredentialSource/FileSource.php @@ -0,0 +1,75 @@ +file = $file; + + if ($format === 'json' && is_null($subjectTokenFieldName)) { + throw new InvalidArgumentException( + 'subject_token_field_name must be set when format is JSON' + ); + } + + $this->format = $format; + $this->subjectTokenFieldName = $subjectTokenFieldName; + } + + public function fetchSubjectToken(callable $httpHandler = null): string + { + $contents = file_get_contents($this->file); + if ($this->format === 'json') { + if (!$json = json_decode((string) $contents, true)) { + throw new UnexpectedValueException( + 'Unable to decode JSON file' + ); + } + if (!isset($json[$this->subjectTokenFieldName])) { + throw new UnexpectedValueException( + 'subject_token_field_name not found in JSON file' + ); + } + $contents = $json[$this->subjectTokenFieldName]; + } + + return $contents; + } +} diff --git a/lib/Google/vendor/google/auth/src/CredentialSource/UrlSource.php b/lib/Google/vendor/google/auth/src/CredentialSource/UrlSource.php new file mode 100644 index 000000000..0acb3c6ef --- /dev/null +++ b/lib/Google/vendor/google/auth/src/CredentialSource/UrlSource.php @@ -0,0 +1,97 @@ + + */ + private ?array $headers; + + /** + * @param string $url The URL to fetch the subject token from. + * @param string $format The format of the token in the response. Can be null or "json". + * @param string $subjectTokenFieldName The name of the field containing the token in the response. This is required + * when format is "json". + * @param array $headers Request headers to send in with the request to the URL. + */ + public function __construct( + string $url, + string $format = null, + string $subjectTokenFieldName = null, + array $headers = null + ) { + $this->url = $url; + + if ($format === 'json' && is_null($subjectTokenFieldName)) { + throw new InvalidArgumentException( + 'subject_token_field_name must be set when format is JSON' + ); + } + + $this->format = $format; + $this->subjectTokenFieldName = $subjectTokenFieldName; + $this->headers = $headers; + } + + public function fetchSubjectToken(callable $httpHandler = null): string + { + if (is_null($httpHandler)) { + $httpHandler = HttpHandlerFactory::build(HttpClientCache::getHttpClient()); + } + + $request = new Request( + 'GET', + $this->url, + $this->headers ?: [] + ); + + $response = $httpHandler($request); + $body = (string) $response->getBody(); + if ($this->format === 'json') { + if (!$json = json_decode((string) $body, true)) { + throw new UnexpectedValueException( + 'Unable to decode JSON response' + ); + } + if (!isset($json[$this->subjectTokenFieldName])) { + throw new UnexpectedValueException( + 'subject_token_field_name not found in JSON file' + ); + } + $body = $json[$this->subjectTokenFieldName]; + } + + return $body; + } +} diff --git a/lib/Google/vendor/google/auth/src/Credentials/ExternalAccountCredentials.php b/lib/Google/vendor/google/auth/src/Credentials/ExternalAccountCredentials.php new file mode 100644 index 000000000..b2716bfaa --- /dev/null +++ b/lib/Google/vendor/google/auth/src/Credentials/ExternalAccountCredentials.php @@ -0,0 +1,241 @@ + $jsonKey JSON credentials as an associative array. + */ + public function __construct( + $scope, + array $jsonKey + ) { + if (!array_key_exists('type', $jsonKey)) { + throw new InvalidArgumentException('json key is missing the type field'); + } + if ($jsonKey['type'] !== self::EXTERNAL_ACCOUNT_TYPE) { + throw new InvalidArgumentException(sprintf( + 'expected "%s" type but received "%s"', + self::EXTERNAL_ACCOUNT_TYPE, + $jsonKey['type'] + )); + } + + if (!array_key_exists('token_url', $jsonKey)) { + throw new InvalidArgumentException( + 'json key is missing the token_url field' + ); + } + + if (!array_key_exists('audience', $jsonKey)) { + throw new InvalidArgumentException( + 'json key is missing the audience field' + ); + } + + if (!array_key_exists('subject_token_type', $jsonKey)) { + throw new InvalidArgumentException( + 'json key is missing the subject_token_type field' + ); + } + + if (!array_key_exists('credential_source', $jsonKey)) { + throw new InvalidArgumentException( + 'json key is missing the credential_source field' + ); + } + + if (array_key_exists('service_account_impersonation_url', $jsonKey)) { + $this->serviceAccountImpersonationUrl = $jsonKey['service_account_impersonation_url']; + } + + $this->quotaProject = $jsonKey['quota_project_id'] ?? null; + + $this->auth = new OAuth2([ + 'tokenCredentialUri' => $jsonKey['token_url'], + 'audience' => $jsonKey['audience'], + 'scope' => $scope, + 'subjectTokenType' => $jsonKey['subject_token_type'], + 'subjectTokenFetcher' => self::buildCredentialSource($jsonKey), + ]); + } + + /** + * @param array $jsonKey + */ + private static function buildCredentialSource(array $jsonKey): ExternalAccountCredentialSourceInterface + { + $credentialSource = $jsonKey['credential_source']; + if (isset($credentialSource['file'])) { + return new FileSource( + $credentialSource['file'], + $credentialSource['format']['type'] ?? null, + $credentialSource['format']['subject_token_field_name'] ?? null + ); + } + + if ( + isset($credentialSource['environment_id']) + && 1 === preg_match('/^aws(\d+)$/', $credentialSource['environment_id'], $matches) + ) { + if ($matches[1] !== '1') { + throw new InvalidArgumentException( + "aws version \"$matches[1]\" is not supported in the current build." + ); + } + if (!array_key_exists('regional_cred_verification_url', $credentialSource)) { + throw new InvalidArgumentException( + 'The regional_cred_verification_url field is required for aws1 credential source.' + ); + } + if (!array_key_exists('audience', $jsonKey)) { + throw new InvalidArgumentException( + 'aws1 credential source requires an audience to be set in the JSON file.' + ); + } + + return new AwsNativeSource( + $jsonKey['audience'], + $credentialSource['regional_cred_verification_url'], // $regionalCredVerificationUrl + $credentialSource['region_url'] ?? null, // $regionUrl + $credentialSource['url'] ?? null, // $securityCredentialsUrl + $credentialSource['imdsv2_session_token_url'] ?? null, // $imdsV2TokenUrl + ); + } + + if (isset($credentialSource['url'])) { + return new UrlSource( + $credentialSource['url'], + $credentialSource['format']['type'] ?? null, + $credentialSource['format']['subject_token_field_name'] ?? null, + $credentialSource['headers'] ?? null, + ); + } + + throw new InvalidArgumentException('Unable to determine credential source from json key.'); + } + /** + * @param string $stsToken + * @param callable $httpHandler + * + * @return array { + * A set of auth related metadata, containing the following + * + * @type string $access_token + * @type int $expires_at + * } + */ + private function getImpersonatedAccessToken(string $stsToken, callable $httpHandler = null): array + { + if (!isset($this->serviceAccountImpersonationUrl)) { + throw new InvalidArgumentException( + 'service_account_impersonation_url must be set in JSON credentials.' + ); + } + $request = new Request( + 'POST', + $this->serviceAccountImpersonationUrl, + [ + 'Content-Type' => 'application/json', + 'Authorization' => 'Bearer ' . $stsToken, + ], + (string) json_encode([ + 'lifetime' => sprintf('%ss', OAuth2::DEFAULT_EXPIRY_SECONDS), + 'scope' => $this->auth->getScope(), + ]), + ); + if (is_null($httpHandler)) { + $httpHandler = HttpHandlerFactory::build(HttpClientCache::getHttpClient()); + } + $response = $httpHandler($request); + $body = json_decode((string) $response->getBody(), true); + return [ + 'access_token' => $body['accessToken'], + 'expires_at' => strtotime($body['expireTime']), + ]; + } + + /** + * @param callable $httpHandler + * + * @return array { + * A set of auth related metadata, containing the following + * + * @type string $access_token + * @type int $expires_at (impersonated service accounts only) + * @type int $expires_in (identity pool only) + * @type string $issued_token_type (identity pool only) + * @type string $token_type (identity pool only) + * } + */ + public function fetchAuthToken(callable $httpHandler = null) + { + $stsToken = $this->auth->fetchAuthToken($httpHandler); + + if (isset($this->serviceAccountImpersonationUrl)) { + return $this->getImpersonatedAccessToken($stsToken['access_token'], $httpHandler); + } + + return $stsToken; + } + + public function getCacheKey() + { + return $this->auth->getCacheKey(); + } + + public function getLastReceivedToken() + { + return $this->auth->getLastReceivedToken(); + } + + /** + * Get the quota project used for this API request + * + * @return string|null + */ + public function getQuotaProject() + { + return $this->quotaProject; + } +} diff --git a/lib/Google/vendor/google/auth/src/Credentials/GCECredentials.php b/lib/Google/vendor/google/auth/src/Credentials/GCECredentials.php index 0a2c019de..991589b52 100644 --- a/lib/Google/vendor/google/auth/src/Credentials/GCECredentials.php +++ b/lib/Google/vendor/google/auth/src/Credentials/GCECredentials.php @@ -100,6 +100,11 @@ class GCECredentials extends CredentialsLoader implements */ const FLAVOR_HEADER = 'Metadata-Flavor'; + /** + * The Linux file which contains the product name. + */ + private const GKE_PRODUCT_NAME_FILE = '/sys/class/dmi/id/product_name'; + /** * Note: the explicit `timeout` and `tries` below is a workaround. The underlying * issue is that resolving an unknown host on some networks will take @@ -340,6 +345,22 @@ public static function onGce(callable $httpHandler = null) } catch (ConnectException $e) { } } + + if (PHP_OS === 'Windows') { + // @TODO: implement GCE residency detection on Windows + return false; + } + + // Detect GCE residency on Linux + return self::detectResidencyLinux(self::GKE_PRODUCT_NAME_FILE); + } + + private static function detectResidencyLinux(string $productNameFile): bool + { + if (file_exists($productNameFile)) { + $productName = trim((string) file_get_contents($productNameFile)); + return 0 === strpos($productName, 'Google'); + } return false; } diff --git a/lib/Google/vendor/google/auth/src/Credentials/ImpersonatedServiceAccountCredentials.php b/lib/Google/vendor/google/auth/src/Credentials/ImpersonatedServiceAccountCredentials.php index 577fe2298..1b4e46eaf 100644 --- a/lib/Google/vendor/google/auth/src/Credentials/ImpersonatedServiceAccountCredentials.php +++ b/lib/Google/vendor/google/auth/src/Credentials/ImpersonatedServiceAccountCredentials.php @@ -37,13 +37,13 @@ class ImpersonatedServiceAccountCredentials extends CredentialsLoader implements protected $sourceCredentials; /** - * Instantiate an instance of ImpersonatedServiceAccountCredentials from a credentials file that has be created with - * the --impersonated-service-account flag. + * Instantiate an instance of ImpersonatedServiceAccountCredentials from a credentials file that + * has be created with the --impersonated-service-account flag. * - * @param string|string[] $scope the scope of the access request, expressed - * either as an Array or as a space-delimited String. + * @param string|string[] $scope The scope of the access request, expressed either as an + * array or as a space-delimited string. * @param string|array $jsonKey JSON credential file path or JSON credentials - * as an associative array + * as an associative array. */ public function __construct( $scope, @@ -59,24 +59,34 @@ public function __construct( } } if (!array_key_exists('service_account_impersonation_url', $jsonKey)) { - throw new \LogicException('json key is missing the service_account_impersonation_url field'); + throw new \LogicException( + 'json key is missing the service_account_impersonation_url field' + ); } if (!array_key_exists('source_credentials', $jsonKey)) { throw new \LogicException('json key is missing the source_credentials field'); } - $this->impersonatedServiceAccountName = $this->getImpersonatedServiceAccountNameFromUrl($jsonKey['service_account_impersonation_url']); + $this->impersonatedServiceAccountName = $this->getImpersonatedServiceAccountNameFromUrl( + $jsonKey['service_account_impersonation_url'] + ); - $this->sourceCredentials = new UserRefreshCredentials($scope, $jsonKey['source_credentials']); + $this->sourceCredentials = new UserRefreshCredentials( + $scope, + $jsonKey['source_credentials'] + ); } /** - * Helper function for extracting the Server Account Name from the URL saved in the account credentials file - * @param $serviceAccountImpersonationUrl string URL from the 'service_account_impersonation_url' field + * Helper function for extracting the Server Account Name from the URL saved in the account + * credentials file. + * + * @param $serviceAccountImpersonationUrl string URL from "service_account_impersonation_url" * @return string Service account email or ID. */ - private function getImpersonatedServiceAccountNameFromUrl(string $serviceAccountImpersonationUrl) - { + private function getImpersonatedServiceAccountNameFromUrl( + string $serviceAccountImpersonationUrl + ): string { $fields = explode('/', $serviceAccountImpersonationUrl); $lastField = end($fields); $splitter = explode(':', $lastField); diff --git a/lib/Google/vendor/google/auth/src/Credentials/ServiceAccountCredentials.php b/lib/Google/vendor/google/auth/src/Credentials/ServiceAccountCredentials.php index 76aa0fc99..086417c07 100644 --- a/lib/Google/vendor/google/auth/src/Credentials/ServiceAccountCredentials.php +++ b/lib/Google/vendor/google/auth/src/Credentials/ServiceAccountCredentials.php @@ -99,6 +99,11 @@ class ServiceAccountCredentials extends CredentialsLoader implements */ private $jwtAccessCredentials; + /** + * @var string|null + */ + private ?string $universeDomain; + /** * Create a new ServiceAccountCredentials. * @@ -159,6 +164,7 @@ public function __construct( ]); $this->projectId = $jsonKey['project_id'] ?? null; + $this->universeDomain = $jsonKey['universe_domain'] ?? null; } /** @@ -328,6 +334,19 @@ public function getQuotaProject() return $this->quotaProject; } + /** + * Get the universe domain configured in the JSON credential. + * + * @return string + */ + public function getUniverseDomain(): string + { + if (null === $this->universeDomain) { + return self::DEFAULT_UNIVERSE_DOMAIN; + } + return $this->universeDomain; + } + /** * @return bool */ diff --git a/lib/Google/vendor/google/auth/src/CredentialsLoader.php b/lib/Google/vendor/google/auth/src/CredentialsLoader.php index ada8e759c..746b957a9 100644 --- a/lib/Google/vendor/google/auth/src/CredentialsLoader.php +++ b/lib/Google/vendor/google/auth/src/CredentialsLoader.php @@ -17,6 +17,7 @@ namespace Google\Auth; +use Google\Auth\Credentials\ExternalAccountCredentials; use Google\Auth\Credentials\ImpersonatedServiceAccountCredentials; use Google\Auth\Credentials\InsecureCredentials; use Google\Auth\Credentials\ServiceAccountCredentials; @@ -29,9 +30,12 @@ * credentials files on the file system. */ abstract class CredentialsLoader implements + GetUniverseDomainInterface, FetchAuthTokenInterface, UpdateMetadataInterface { + use UpdateMetadataTrait; + const TOKEN_CREDENTIAL_URI = 'https://oauth2.googleapis.com/token'; const ENV_VAR = 'GOOGLE_APPLICATION_CREDENTIALS'; const QUOTA_PROJECT_ENV_VAR = 'GOOGLE_CLOUD_QUOTA_PROJECT'; @@ -122,7 +126,7 @@ public static function fromWellKnownFile() * user-defined scopes exist, expressed either as an Array or as a * space-delimited string. * - * @return ServiceAccountCredentials|UserRefreshCredentials|ImpersonatedServiceAccountCredentials + * @return ServiceAccountCredentials|UserRefreshCredentials|ImpersonatedServiceAccountCredentials|ExternalAccountCredentials */ public static function makeCredentials( $scope, @@ -148,6 +152,11 @@ public static function makeCredentials( return new ImpersonatedServiceAccountCredentials($anyScope, $jsonKey); } + if ($jsonKey['type'] == 'external_account') { + $anyScope = $scope ?: $defaultScope; + return new ExternalAccountCredentials($anyScope, $jsonKey); + } + throw new \InvalidArgumentException('invalid value in the type field'); } @@ -190,44 +199,6 @@ public static function makeInsecureCredentials() return new InsecureCredentials(); } - /** - * export a callback function which updates runtime metadata. - * - * @return callable updateMetadata function - * @deprecated - */ - public function getUpdateMetadataFunc() - { - return [$this, 'updateMetadata']; - } - - /** - * Updates metadata with the authorization token. - * - * @param array $metadata metadata hashmap - * @param string $authUri optional auth uri - * @param callable $httpHandler callback which delivers psr7 request - * @return array updated metadata hashmap - */ - public function updateMetadata( - $metadata, - $authUri = null, - callable $httpHandler = null - ) { - if (isset($metadata[self::AUTH_METADATA_KEY])) { - // Auth metadata has already been set - return $metadata; - } - $result = $this->fetchAuthToken($httpHandler); - $metadata_copy = $metadata; - if (isset($result['access_token'])) { - $metadata_copy[self::AUTH_METADATA_KEY] = ['Bearer ' . $result['access_token']]; - } elseif (isset($result['id_token'])) { - $metadata_copy[self::AUTH_METADATA_KEY] = ['Bearer ' . $result['id_token']]; - } - return $metadata_copy; - } - /** * Fetch a quota project from the environment variable * GOOGLE_CLOUD_QUOTA_PROJECT. Return null if @@ -303,4 +274,15 @@ private static function loadDefaultClientCertSourceFile() } return $clientCertSourceJson; } + + /** + * Get the universe domain from the credential. Defaults to "googleapis.com" + * for all credential types which do not support universe domain. + * + * @return string + */ + public function getUniverseDomain(): string + { + return self::DEFAULT_UNIVERSE_DOMAIN; + } } diff --git a/lib/Google/vendor/google/auth/src/ExternalAccountCredentialSourceInterface.php b/lib/Google/vendor/google/auth/src/ExternalAccountCredentialSourceInterface.php new file mode 100644 index 000000000..b4d00f8b4 --- /dev/null +++ b/lib/Google/vendor/google/auth/src/ExternalAccountCredentialSourceInterface.php @@ -0,0 +1,23 @@ +fetcher->getProjectId($httpHandler); } + /* + * Get the Universe Domain from the fetcher. + * + * @return string + */ + public function getUniverseDomain(): string + { + if ($this->fetcher instanceof GetUniverseDomainInterface) { + return $this->fetcher->getUniverseDomain(); + } + + return GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN; + } + /** * Updates metadata with the authorization token. * diff --git a/lib/Google/vendor/google/auth/src/GetUniverseDomainInterface.php b/lib/Google/vendor/google/auth/src/GetUniverseDomainInterface.php new file mode 100644 index 000000000..1656ddc2e --- /dev/null +++ b/lib/Google/vendor/google/auth/src/GetUniverseDomainInterface.php @@ -0,0 +1,35 @@ +withHeader('authorization', 'Bearer ' . $this->fetchToken()); + $request = $this->addAuthHeaders($request); if ($quotaProject = $this->getQuotaProject()) { $request = $request->withHeader( @@ -113,32 +119,33 @@ public function __invoke(callable $handler) } /** - * Call fetcher to fetch the token. + * Adds auth related headers to the request. * - * @return string|null + * @param RequestInterface $request + * @return RequestInterface */ - private function fetchToken() + private function addAuthHeaders(RequestInterface $request) { - $auth_tokens = (array) $this->fetcher->fetchAuthToken($this->httpHandler); - - if (array_key_exists('access_token', $auth_tokens)) { - // notify the callback if applicable - if ($this->tokenCallback) { - call_user_func( - $this->tokenCallback, - $this->fetcher->getCacheKey(), - $auth_tokens['access_token'] - ); - } - - return $auth_tokens['access_token']; + if (!$this->fetcher instanceof UpdateMetadataInterface || + ($this->fetcher instanceof FetchAuthTokenCache && + !$this->fetcher->getFetcher() instanceof UpdateMetadataInterface) + ) { + $token = $this->fetcher->fetchAuthToken(); + $request = $request->withHeader( + 'authorization', 'Bearer ' . ($token['access_token'] ?? $token['id_token']) + ); + } else { + $headers = $this->fetcher->updateMetadata($request->getHeaders(), null, $this->httpHandler); + $request = Utils::modifyRequest($request, ['set_headers' => $headers]); } - if (array_key_exists('id_token', $auth_tokens)) { - return $auth_tokens['id_token']; + if ($this->tokenCallback && ($token = $this->fetcher->getLastReceivedToken())) { + if (array_key_exists('access_token', $token)) { + call_user_func($this->tokenCallback, $this->fetcher->getCacheKey(), $token['access_token']); + } } - return null; + return $request; } /** diff --git a/lib/Google/vendor/google/auth/src/OAuth2.php b/lib/Google/vendor/google/auth/src/OAuth2.php index d2da748de..2e5adcdcf 100644 --- a/lib/Google/vendor/google/auth/src/OAuth2.php +++ b/lib/Google/vendor/google/auth/src/OAuth2.php @@ -41,6 +41,8 @@ class OAuth2 implements FetchAuthTokenInterface const DEFAULT_EXPIRY_SECONDS = 3600; // 1 hour const DEFAULT_SKEW_SECONDS = 60; // 1 minute const JWT_URN = 'urn:ietf:params:oauth:grant-type:jwt-bearer'; + const STS_URN = 'urn:ietf:params:oauth:grant-type:token-exchange'; + private const STS_REQUESTED_TOKEN_TYPE = 'urn:ietf:params:oauth:token-type:access_token'; /** * TODO: determine known methods from the keys of JWT::methods. @@ -278,6 +280,47 @@ class OAuth2 implements FetchAuthTokenInterface */ private $codeVerifier; + /** + * For STS requests. + * A URI that indicates the target service or resource where the client + * intends to use the requested security token. + */ + private ?string $resource; + + /** + * For STS requests. + * A fetcher for the "subject_token", which is a security token that + * represents the identity of the party on behalf of whom the request is + * being made. + */ + private ?ExternalAccountCredentialSourceInterface $subjectTokenFetcher; + + /** + * For STS requests. + * An identifier, that indicates the type of the security token in the + * subjectToken parameter. + */ + private ?string $subjectTokenType; + + /** + * For STS requests. + * A security token that represents the identity of the acting party. + */ + private ?string $actorToken; + + /** + * For STS requests. + * An identifier that indicates the type of the security token in the + * actorToken parameter. + */ + private ?string $actorTokenType; + + /** + * From STS response. + * An identifier for the representation of the issued security token. + */ + private ?string $issuedTokenType = null; + /** * Create a new OAuthCredentials. * @@ -344,6 +387,28 @@ class OAuth2 implements FetchAuthTokenInterface * When using an extension grant type, this is the set of parameters used * by that extension. * + * - codeVerifier + * The code verifier for PKCE for OAuth 2.0. + * + * - resource + * The target service or resource where the client ntends to use the + * requested security token. + * + * - subjectTokenFetcher + * A fetcher for the "subject_token", which is a security token that + * represents the identity of the party on behalf of whom the request is + * being made. + * + * - subjectTokenType + * An identifier that indicates the type of the security token in the + * subjectToken parameter. + * + * - actorToken + * A security token that represents the identity of the acting party. + * + * - actorTokenType + * An identifier for the representation of the issued security token. + * * @param array $config Configuration array */ public function __construct(array $config) @@ -368,6 +433,11 @@ public function __construct(array $config) 'scope' => null, 'additionalClaims' => [], 'codeVerifier' => null, + 'resource' => null, + 'subjectTokenFetcher' => null, + 'subjectTokenType' => null, + 'actorToken' => null, + 'actorTokenType' => null, ], $config); $this->setAuthorizationUri($opts['authorizationUri']); @@ -389,6 +459,14 @@ public function __construct(array $config) $this->setExtensionParams($opts['extensionParams']); $this->setAdditionalClaims($opts['additionalClaims']); $this->setCodeVerifier($opts['codeVerifier']); + + // for STS + $this->resource = $opts['resource']; + $this->subjectTokenFetcher = $opts['subjectTokenFetcher']; + $this->subjectTokenType = $opts['subjectTokenType']; + $this->actorToken = $opts['actorToken']; + $this->actorTokenType = $opts['actorTokenType']; + $this->updateToken($opts); } @@ -493,9 +571,10 @@ public function toJwt(array $config = []) /** * Generates a request for token credentials. * + * @param callable $httpHandler callback which delivers psr7 request * @return RequestInterface the authorization Url. */ - public function generateCredentialsRequest() + public function generateCredentialsRequest(callable $httpHandler = null) { $uri = $this->getTokenCredentialUri(); if (is_null($uri)) { @@ -525,6 +604,19 @@ public function generateCredentialsRequest() case self::JWT_URN: $params['assertion'] = $this->toJwt(); break; + case self::STS_URN: + $token = $this->subjectTokenFetcher->fetchSubjectToken($httpHandler); + $params['subject_token'] = $token; + $params['subject_token_type'] = $this->subjectTokenType; + $params += array_filter([ + 'resource' => $this->resource, + 'audience' => $this->audience, + 'scope' => $this->getScope(), + 'requested_token_type' => self::STS_REQUESTED_TOKEN_TYPE, + 'actor_token' => $this->actorToken, + 'actor_token_type' => $this->actorTokenType, + ]); + break; default: if (!is_null($this->getRedirectUri())) { # Grant type was supposed to be 'authorization_code', as there @@ -563,7 +655,7 @@ public function fetchAuthToken(callable $httpHandler = null) $httpHandler = HttpHandlerFactory::build(HttpClientCache::getHttpClient()); } - $response = $httpHandler($this->generateCredentialsRequest()); + $response = $httpHandler($this->generateCredentialsRequest($httpHandler)); $credentials = $this->parseTokenResponse($response); $this->updateToken($credentials); if (isset($credentials['scope'])) { @@ -685,6 +777,12 @@ public function updateToken(array $config) if (array_key_exists('refresh_token', $opts)) { $this->setRefreshToken($opts['refresh_token']); } + + // Required for STS response. An identifier for the representation of + // the issued security token. + if (array_key_exists('issued_token_type', $opts)) { + $this->issuedTokenType = $opts['issued_token_type']; + } } /** @@ -965,6 +1063,10 @@ public function getGrantType() return self::JWT_URN; } + if (!is_null($this->subjectTokenFetcher) && !is_null($this->subjectTokenType)) { + return self::STS_URN; + } + return null; } @@ -1492,6 +1594,16 @@ public function getAdditionalClaims() return $this->additionalClaims; } + /** + * Gets the additional claims to be included in the JWT token. + * + * @return ?string + */ + public function getIssuedTokenType() + { + return $this->issuedTokenType; + } + /** * The expiration of the last received token. * @@ -1611,7 +1723,7 @@ private function getFirebaseJwtKeys($publicKey, $allowedAlgs) $allowedAlg = null; if (is_string($allowedAlgs)) { - $allowedAlg = $allowedAlg; + $allowedAlg = $allowedAlgs; } elseif (is_array($allowedAlgs)) { if (count($allowedAlgs) > 1) { throw new \InvalidArgumentException( diff --git a/lib/Google/vendor/google/auth/src/UpdateMetadataTrait.php b/lib/Google/vendor/google/auth/src/UpdateMetadataTrait.php new file mode 100644 index 000000000..fd33e0dca --- /dev/null +++ b/lib/Google/vendor/google/auth/src/UpdateMetadataTrait.php @@ -0,0 +1,66 @@ + $metadata metadata hashmap + * @param string $authUri optional auth uri + * @param callable $httpHandler callback which delivers psr7 request + * @return array updated metadata hashmap + */ + public function updateMetadata( + $metadata, + $authUri = null, + callable $httpHandler = null + ) { + if (isset($metadata[self::AUTH_METADATA_KEY])) { + // Auth metadata has already been set + return $metadata; + } + $result = $this->fetchAuthToken($httpHandler); + $metadata_copy = $metadata; + if (isset($result['access_token'])) { + $metadata_copy[self::AUTH_METADATA_KEY] = ['Bearer ' . $result['access_token']]; + } elseif (isset($result['id_token'])) { + $metadata_copy[self::AUTH_METADATA_KEY] = ['Bearer ' . $result['id_token']]; + } + return $metadata_copy; + } +} diff --git a/lib/Google/vendor/google/cloud-core/.repo-metadata.json b/lib/Google/vendor/google/cloud-core/.repo-metadata.json index 477240ca5..9f0a1e0ee 100644 --- a/lib/Google/vendor/google/cloud-core/.repo-metadata.json +++ b/lib/Google/vendor/google/cloud-core/.repo-metadata.json @@ -1,4 +1,5 @@ { + "language": "php", "distribution_name": "google/cloud-core", "release_level": "stable", "client_documentation": "https://cloud.google.com/php/docs/reference/cloud-core/latest", diff --git a/lib/Google/vendor/google/cloud-core/VERSION b/lib/Google/vendor/google/cloud-core/VERSION index aa618f0d5..a91664e0a 100644 --- a/lib/Google/vendor/google/cloud-core/VERSION +++ b/lib/Google/vendor/google/cloud-core/VERSION @@ -1 +1 @@ -1.51.2 +1.52.10 diff --git a/lib/Google/vendor/google/cloud-core/composer.json b/lib/Google/vendor/google/cloud-core/composer.json index 1b1315be6..63aff87d1 100644 --- a/lib/Google/vendor/google/cloud-core/composer.json +++ b/lib/Google/vendor/google/cloud-core/composer.json @@ -7,11 +7,11 @@ "php": ">=7.4", "rize/uri-template": "~0.3", "google/auth": "^1.18", - "guzzlehttp/guzzle": "^5.3|^6.5.7|^7.4.4", - "guzzlehttp/promises": "^1.3", + "guzzlehttp/guzzle": "^6.5.8|^7.4.4", + "guzzlehttp/promises": "^1.4||^2.0", "guzzlehttp/psr7": "^1.7|^2.0", "monolog/monolog": "^1.1|^2.0|^3.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.0|^2.0" }, "require-dev": { "phpunit/phpunit": "^9.0", @@ -19,7 +19,7 @@ "squizlabs/php_codesniffer": "2.*", "phpdocumentor/reflection": "^5.0", "erusev/parsedown": "^1.6", - "google/gax": "^1.9", + "google/gax": "^1.24.0", "opis/closure": "^3", "google/cloud-common-protos": "^0.4" }, diff --git a/lib/Google/vendor/google/cloud-core/src/Batch/BatchTrait.php b/lib/Google/vendor/google/cloud-core/src/Batch/BatchTrait.php index 2ba2d4208..3ac284cf1 100644 --- a/lib/Google/vendor/google/cloud-core/src/Batch/BatchTrait.php +++ b/lib/Google/vendor/google/cloud-core/src/Batch/BatchTrait.php @@ -161,7 +161,7 @@ abstract protected function getCallback(); * responsible for serializing closures used in the * `$clientConfig`. This is especially important when using the * batch daemon. **Defaults to** - * {@see Google\Cloud\Core\Batch\OpisClosureSerializer} if the + * {@see \Google\Cloud\Core\Batch\OpisClosureSerializer} if the * `opis/closure` library is installed. * } * @throws \InvalidArgumentException diff --git a/lib/Google/vendor/google/cloud-core/src/Batch/HandleFailureTrait.php b/lib/Google/vendor/google/cloud-core/src/Batch/HandleFailureTrait.php index 543bff705..32b467efd 100644 --- a/lib/Google/vendor/google/cloud-core/src/Batch/HandleFailureTrait.php +++ b/lib/Google/vendor/google/cloud-core/src/Batch/HandleFailureTrait.php @@ -88,7 +88,7 @@ public function handleFailure($idNum, array $items) if ($this->failureFile) { $fp = @fopen($this->failureFile, 'a'); - @fwrite($fp, serialize([$idNum => $items]) . PHP_EOL); + @fwrite($fp, json_encode(serialize([$idNum => $items])) . PHP_EOL); @fclose($fp); } } diff --git a/lib/Google/vendor/google/cloud-core/src/Batch/InMemoryConfigStorage.php b/lib/Google/vendor/google/cloud-core/src/Batch/InMemoryConfigStorage.php index 941208c31..aa4a1b118 100644 --- a/lib/Google/vendor/google/cloud-core/src/Batch/InMemoryConfigStorage.php +++ b/lib/Google/vendor/google/cloud-core/src/Batch/InMemoryConfigStorage.php @@ -154,8 +154,9 @@ public function clear() * * We want to delay registering the shutdown function. The error * reporter also registers a shutdown function and the order matters. - * {@see Google\ErrorReporting\Bootstrap::init()} - * {@see http://php.net/manual/en/function.register-shutdown-function.php} + * + * @see \Google\Cloud\ErrorReporting\Bootstrap::init() + * @see http://php.net/manual/en/function.register-shutdown-function.php * * @param mixed $item An item to submit. * @param int $idNum A numeric id for the job. diff --git a/lib/Google/vendor/google/cloud-core/src/Batch/InterruptTrait.php b/lib/Google/vendor/google/cloud-core/src/Batch/InterruptTrait.php index ecc163492..dae64456f 100644 --- a/lib/Google/vendor/google/cloud-core/src/Batch/InterruptTrait.php +++ b/lib/Google/vendor/google/cloud-core/src/Batch/InterruptTrait.php @@ -40,7 +40,8 @@ private function setupSignalHandlers() /** * A signal handler for setting the terminate switch. - * {@see http://php.net/manual/en/function.pcntl-signal.php} + * + * @see http://php.net/manual/en/function.pcntl-signal.php * * @param int $signo The received signal. * @param mixed $siginfo [optional] An array representing the signal diff --git a/lib/Google/vendor/google/cloud-core/src/Batch/QueueOverflowException.php b/lib/Google/vendor/google/cloud-core/src/Batch/QueueOverflowException.php index 8359b0234..8424daa53 100644 --- a/lib/Google/vendor/google/cloud-core/src/Batch/QueueOverflowException.php +++ b/lib/Google/vendor/google/cloud-core/src/Batch/QueueOverflowException.php @@ -18,7 +18,7 @@ namespace Google\Cloud\Core\Batch; /** - * Exception thrown in {@see Google\Cloud\Core\Batch\SysvProcessor::submit()} + * Exception thrown in {@see \Google\Cloud\Core\Batch\SysvProcessor::submit()} * method when it cannot add an item to the message queue. * Possible causes include: * diff --git a/lib/Google/vendor/google/cloud-core/src/Batch/Retry.php b/lib/Google/vendor/google/cloud-core/src/Batch/Retry.php index 4b0941fcb..483c7eb3d 100644 --- a/lib/Google/vendor/google/cloud-core/src/Batch/Retry.php +++ b/lib/Google/vendor/google/cloud-core/src/Batch/Retry.php @@ -62,6 +62,11 @@ public function retryAll() continue; } while ($line = fgets($fp)) { + $jsonDecodedValue = json_decode($line); + // Check if data json_encoded after serialization + if ($jsonDecodedValue !== null || $jsonDecodedValue !== false) { + $line = $jsonDecodedValue; + } $a = unserialize($line); $idNum = key($a); $job = $this->runner->getJobFromIdNum($idNum); diff --git a/lib/Google/vendor/google/cloud-core/src/Batch/SerializableClientTrait.php b/lib/Google/vendor/google/cloud-core/src/Batch/SerializableClientTrait.php index fc2ca6017..60cd825be 100644 --- a/lib/Google/vendor/google/cloud-core/src/Batch/SerializableClientTrait.php +++ b/lib/Google/vendor/google/cloud-core/src/Batch/SerializableClientTrait.php @@ -48,7 +48,7 @@ trait SerializableClientTrait * responsible for serializing closures used in the * `$clientConfig`. This is especially important when using the * batch daemon. **Defaults to** - * {@see Google\Cloud\Core\Batch\OpisClosureSerializer} if the + * {@see \Google\Cloud\Core\Batch\OpisClosureSerializer} if the * `opis/closure` library is installed. * @type array $clientConfig A config used to construct the client upon * which requests will be made. diff --git a/lib/Google/vendor/google/cloud-core/src/Batch/SimpleJobTrait.php b/lib/Google/vendor/google/cloud-core/src/Batch/SimpleJobTrait.php index 196e38fa2..bdf08669f 100644 --- a/lib/Google/vendor/google/cloud-core/src/Batch/SimpleJobTrait.php +++ b/lib/Google/vendor/google/cloud-core/src/Batch/SimpleJobTrait.php @@ -55,7 +55,7 @@ abstract public function run(); * responsible for serializing closures used in the * `$clientConfig`. This is especially important when using the * batch daemon. **Defaults to** - * {@see Google\Cloud\Core\Batch\OpisClosureSerializer} if the + * {@see \Google\Cloud\Core\Batch\OpisClosureSerializer} if the * `opis/closure` library is installed. * } */ diff --git a/lib/Google/vendor/google/cloud-core/src/ExponentialBackoff.php b/lib/Google/vendor/google/cloud-core/src/ExponentialBackoff.php index ab3a4116e..e5a041311 100644 --- a/lib/Google/vendor/google/cloud-core/src/ExponentialBackoff.php +++ b/lib/Google/vendor/google/cloud-core/src/ExponentialBackoff.php @@ -135,7 +135,7 @@ public function setDelayFunction(callable $delayFunction) /** * If not set, defaults to using - * {@see Google\Cloud\Core\ExponentialBackoff::calculateDelay()}. + * {@see \Google\Cloud\Core\ExponentialBackoff::calculateDelay()}. * * @param callable $calcDelayFunction * @return void diff --git a/lib/Google/vendor/google/cloud-core/src/GrpcRequestWrapper.php b/lib/Google/vendor/google/cloud-core/src/GrpcRequestWrapper.php index 847e43e7a..5a2735361 100644 --- a/lib/Google/vendor/google/cloud-core/src/GrpcRequestWrapper.php +++ b/lib/Google/vendor/google/cloud-core/src/GrpcRequestWrapper.php @@ -74,7 +74,7 @@ class GrpcRequestWrapper /** * @param array $config [optional] { * Configuration options. Please see - * {@see Google\Cloud\Core\RequestWrapperTrait::setCommonDefaults()} for + * {@see \Google\Cloud\Core\RequestWrapperTrait::setCommonDefaults()} for * the other available options. * * @type callable $authHttpHandler A handler used to deliver Psr7 diff --git a/lib/Google/vendor/google/cloud-core/src/Iam/Iam.php b/lib/Google/vendor/google/cloud-core/src/Iam/Iam.php index b83e747dc..1f8c08d53 100644 --- a/lib/Google/vendor/google/cloud-core/src/Iam/Iam.php +++ b/lib/Google/vendor/google/cloud-core/src/Iam/Iam.php @@ -23,7 +23,7 @@ * This class is not meant to be used directly. It should be accessed * through other objects which support IAM. * - * Policies can be created using the {@see Google\Cloud\Core\Iam\PolicyBuilder} + * Policies can be created using the {@see \Google\Cloud\Core\Iam\PolicyBuilder} * to help ensure their validity. * * Example: @@ -98,7 +98,7 @@ public function __construct(IamConnectionInterface $connection, $resource, array * * If a policy has already been retrieved from the API, it will be returned. * To fetch a fresh copy of the policy, use - * {@see Google\Cloud\Core\Iam\Iam::reload()}. + * {@see \Google\Cloud\Core\Iam\Iam::reload()}. * * Example: * ``` @@ -136,7 +136,7 @@ public function policy(array $options = []) * ``` * * @param array|PolicyBuilder $policy The new policy, as an array or an - * instance of {@see Google\Cloud\Core\Iam\PolicyBuilder}. + * instance of {@see \Google\Cloud\Core\Iam\PolicyBuilder}. * @param array $options Configuration Options * @return array An array of policy data * @throws \InvalidArgumentException If the given policy is not an array or PolicyBuilder. diff --git a/lib/Google/vendor/google/cloud-core/src/LongRunning/LROTrait.php b/lib/Google/vendor/google/cloud-core/src/LongRunning/LROTrait.php index d345699eb..477d5f3ea 100644 --- a/lib/Google/vendor/google/cloud-core/src/LongRunning/LROTrait.php +++ b/lib/Google/vendor/google/cloud-core/src/LongRunning/LROTrait.php @@ -30,6 +30,7 @@ trait LROTrait { /** * @var LongRunningConnectionInterface + * @internal */ private $lroConnection; @@ -47,6 +48,8 @@ trait LROTrait * Populate required LRO properties. * * @param LongRunningConnectionInterface $lroConnection The LRO Connection. + * This object is created by internal classes, + * and should not be instantiated outside of this context. * @param array $callablesMap An collection of form [(string) typeUrl, (callable) callable] * providing a function to invoke when an operation completes. The * callable Type should correspond to an expected value of diff --git a/lib/Google/vendor/google/cloud-core/src/LongRunning/LongRunningConnectionInterface.php b/lib/Google/vendor/google/cloud-core/src/LongRunning/LongRunningConnectionInterface.php index 9b35a5cce..df8c27b6e 100644 --- a/lib/Google/vendor/google/cloud-core/src/LongRunning/LongRunningConnectionInterface.php +++ b/lib/Google/vendor/google/cloud-core/src/LongRunning/LongRunningConnectionInterface.php @@ -21,6 +21,7 @@ * Defines the calls required to manage Long Running Operations. * * This interface should be implemented in a service's Connection namespace. + * @internal */ interface LongRunningConnectionInterface { diff --git a/lib/Google/vendor/google/cloud-core/src/LongRunning/LongRunningOperation.php b/lib/Google/vendor/google/cloud-core/src/LongRunning/LongRunningOperation.php index 63732d91b..d0decd596 100644 --- a/lib/Google/vendor/google/cloud-core/src/LongRunning/LongRunningOperation.php +++ b/lib/Google/vendor/google/cloud-core/src/LongRunning/LongRunningOperation.php @@ -30,6 +30,7 @@ class LongRunningOperation /** * @var LongRunningConnectionInterface + * @internal */ private $connection; @@ -61,6 +62,8 @@ class LongRunningOperation /** * @param LongRunningConnectionInterface $connection An implementation * mapping to methods which handle LRO resolution in the service. + * This object is created by internal classes, + * and should not be instantiated outside of this context. * @param string $name The Operation name. * @param array $callablesMap An collection of form [(string) typeUrl, (callable) callable] * providing a function to invoke when an operation completes. The diff --git a/lib/Google/vendor/google/cloud-core/src/Report/EmptyMetadataProvider.php b/lib/Google/vendor/google/cloud-core/src/Report/EmptyMetadataProvider.php index 50c07e92e..32ed9a859 100644 --- a/lib/Google/vendor/google/cloud-core/src/Report/EmptyMetadataProvider.php +++ b/lib/Google/vendor/google/cloud-core/src/Report/EmptyMetadataProvider.php @@ -25,7 +25,8 @@ class EmptyMetadataProvider implements MetadataProviderInterface { /** * Return an array representing MonitoredResource. - * {@see https://cloud.google.com/logging/docs/reference/v2/rest/v2/MonitoredResource} + * + * @see https://cloud.google.com/logging/docs/reference/v2/rest/v2/MonitoredResource * * @return array */ diff --git a/lib/Google/vendor/google/cloud-core/src/Report/GAEMetadataProvider.php b/lib/Google/vendor/google/cloud-core/src/Report/GAEMetadataProvider.php index 3493f8b98..75caef7a5 100644 --- a/lib/Google/vendor/google/cloud-core/src/Report/GAEMetadataProvider.php +++ b/lib/Google/vendor/google/cloud-core/src/Report/GAEMetadataProvider.php @@ -59,7 +59,8 @@ public function __construct(array $server) /** * Return an array representing MonitoredResource. - * {@see https://cloud.google.com/logging/docs/reference/v2/rest/v2/MonitoredResource} + * + * @see https://cloud.google.com/logging/docs/reference/v2/rest/v2/MonitoredResource * * @return array */ diff --git a/lib/Google/vendor/google/cloud-core/src/Report/MetadataProviderInterface.php b/lib/Google/vendor/google/cloud-core/src/Report/MetadataProviderInterface.php index 9834fda0d..a1cb5f3b2 100644 --- a/lib/Google/vendor/google/cloud-core/src/Report/MetadataProviderInterface.php +++ b/lib/Google/vendor/google/cloud-core/src/Report/MetadataProviderInterface.php @@ -24,7 +24,8 @@ interface MetadataProviderInterface { /** * Return an array representing MonitoredResource. - * {@see https://cloud.google.com/logging/docs/reference/v2/rest/v2/MonitoredResource} + * + * @see https://cloud.google.com/logging/docs/reference/v2/rest/v2/MonitoredResource * * @return array */ diff --git a/lib/Google/vendor/google/cloud-core/src/Report/SimpleMetadataProvider.php b/lib/Google/vendor/google/cloud-core/src/Report/SimpleMetadataProvider.php index 12b04679d..288c6886f 100644 --- a/lib/Google/vendor/google/cloud-core/src/Report/SimpleMetadataProvider.php +++ b/lib/Google/vendor/google/cloud-core/src/Report/SimpleMetadataProvider.php @@ -49,7 +49,8 @@ public function __construct( /** * Return an array representing MonitoredResource. - * {@see https://cloud.google.com/logging/docs/reference/v2/rest/v2/MonitoredResource} + * + * @see https://cloud.google.com/logging/docs/reference/v2/rest/v2/MonitoredResource * * @return array */ diff --git a/lib/Google/vendor/google/cloud-core/src/RequestWrapper.php b/lib/Google/vendor/google/cloud-core/src/RequestWrapper.php index 4b28b58e8..79c2f142e 100644 --- a/lib/Google/vendor/google/cloud-core/src/RequestWrapper.php +++ b/lib/Google/vendor/google/cloud-core/src/RequestWrapper.php @@ -17,10 +17,12 @@ namespace Google\Cloud\Core; +use Google\Auth\FetchAuthTokenCache; use Google\Auth\FetchAuthTokenInterface; use Google\Auth\GetQuotaProjectInterface; use Google\Auth\HttpHandler\Guzzle6HttpHandler; use Google\Auth\HttpHandler\HttpHandlerFactory; +use Google\Auth\UpdateMetadataInterface; use Google\Cloud\Core\Exception\ServiceException; use Google\Cloud\Core\RequestWrapperTrait; use GuzzleHttp\Exception\RequestException; @@ -95,12 +97,13 @@ class RequestWrapper /** * @param array $config [optional] { * Configuration options. Please see - * {@see Google\Cloud\Core\RequestWrapperTrait::setCommonDefaults()} for + * {@see \Google\Cloud\Core\RequestWrapperTrait::setCommonDefaults()} for * the other available options. * * @type string $componentVersion The current version of the component from * which the request originated. * @type string $accessToken Access token used to sign requests. + * Deprecated: This option is no longer supported. Use the `$credentialsFetcher` option instead. * @type callable $asyncHttpHandler *Experimental* A handler used to * deliver PSR-7 requests asynchronously. Function signature should match: * `function (RequestInterface $request, array $options = []) : PromiseInterface`. @@ -304,48 +307,60 @@ private function applyHeaders(RequestInterface $request, array $options = []) unset($options['retryHeaders']); } + $request = Utils::modifyRequest($request, ['set_headers' => $headers]); + if ($this->shouldSignRequest) { $quotaProject = $this->quotaProject; - $token = null; if ($this->accessToken) { - $token = $this->accessToken; + $request = $request->withHeader('authorization', 'Bearer ' . $this->accessToken); } else { $credentialsFetcher = $this->getCredentialsFetcher(); - $token = $this->fetchCredentials($credentialsFetcher)['access_token']; + $request = $this->addAuthHeaders($request, $credentialsFetcher); if ($credentialsFetcher instanceof GetQuotaProjectInterface) { $quotaProject = $credentialsFetcher->getQuotaProject(); } } - $headers['Authorization'] = 'Bearer ' . $token; - if ($quotaProject) { - $headers['X-Goog-User-Project'] = [$quotaProject]; + $request = $request->withHeader('X-Goog-User-Project', $quotaProject); } } - return Utils::modifyRequest($request, ['set_headers' => $headers]); + return $request; } /** - * Fetches credentials. + * Adds auth headers to the request. * - * @param FetchAuthTokenInterface $credentialsFetcher + * @param RequestInterface $request + * @param FetchAuthTokenInterface $fetcher * @return array * @throws ServiceException */ - private function fetchCredentials(FetchAuthTokenInterface $credentialsFetcher) + private function addAuthHeaders(RequestInterface $request, FetchAuthTokenInterface $fetcher) { $backoff = new ExponentialBackoff($this->retries, $this->getRetryFunction()); try { return $backoff->execute( - function () use ($credentialsFetcher) { - if ($token = $credentialsFetcher->fetchAuthToken($this->authHttpHandler)) { - return $token; + function () use ($request, $fetcher) { + if (!$fetcher instanceof UpdateMetadataInterface || + ($fetcher instanceof FetchAuthTokenCache && + !$fetcher->getFetcher() instanceof UpdateMetadataInterface + ) + ) { + // This covers an edge case where the token fetcher does not implement UpdateMetadataInterface, + // which only would happen if a user implemented a custom fetcher + if ($token = $fetcher->fetchAuthToken($this->authHttpHandler)) { + return $request->withHeader('authorization', 'Bearer ' . $token['access_token']); + } + } else { + $headers = $fetcher->updateMetadata($request->getHeaders(), null, $this->authHttpHandler); + return Utils::modifyRequest($request, ['set_headers' => $headers]); } + // As we do not know the reason the credentials fetcher could not fetch the // token, we should not retry. throw new \RuntimeException('Unable to fetch token'); diff --git a/lib/Google/vendor/google/cloud-core/src/Retry.php b/lib/Google/vendor/google/cloud-core/src/Retry.php index c2fd34fea..67b6000b4 100644 --- a/lib/Google/vendor/google/cloud-core/src/Retry.php +++ b/lib/Google/vendor/google/cloud-core/src/Retry.php @@ -20,7 +20,7 @@ /** * Retry implementation. * - * Unlike {@see Google\Cloud\Core\ExponentialBackoff}, Retry requires an implementor + * Unlike {@see \Google\Cloud\Core\ExponentialBackoff}, Retry requires an implementor * to supply wait times for each iteration. */ class Retry diff --git a/lib/Google/vendor/google/cloud-core/src/ServiceBuilder.php b/lib/Google/vendor/google/cloud-core/src/ServiceBuilder.php index 3214c5e24..b174df812 100644 --- a/lib/Google/vendor/google/cloud-core/src/ServiceBuilder.php +++ b/lib/Google/vendor/google/cloud-core/src/ServiceBuilder.php @@ -110,10 +110,10 @@ public function __construct(array $config = []) * * @param array $config [optional] { * Configuration options. See - * {@see Google\Cloud\Core\ServiceBuilder::__construct()} for the other available options. + * {@see \Google\Cloud\Core\ServiceBuilder::__construct()} for the other available options. * * @type bool $returnInt64AsObject If true, 64 bit integers will be - * returned as a {@see Google\Cloud\Core\Int64} object for 32 bit + * returned as a {@see \Google\Cloud\Core\Int64} object for 32 bit * platform compatibility. **Defaults to** false. * @type string $location If provided, determines the default geographic * location used when creating datasets and managing jobs. Please @@ -141,10 +141,10 @@ public function bigQuery(array $config = []) * * @param array $config [optional] { * Configuration options. See - * {@see Google\Cloud\Core\ServiceBuilder::__construct()} for the other available options. + * {@see \Google\Cloud\Core\ServiceBuilder::__construct()} for the other available options. * * @type bool $returnInt64AsObject If true, 64 bit integers will be - * returned as a {@see Google\Cloud\Core\Int64} object for 32 bit + * returned as a {@see \Google\Cloud\Core\Int64} object for 32 bit * platform compatibility. **Defaults to** false. * @return DatastoreClient */ @@ -165,10 +165,10 @@ public function datastore(array $config = []) * * @param array $config [optional] { * Configuration options. See - * {@see Google\Cloud\Core\ServiceBuilder::__construct()} for the other available options. + * {@see \Google\Cloud\Core\ServiceBuilder::__construct()} for the other available options. * * @type bool $returnInt64AsObject If true, 64 bit integers will be - * returned as a {@see Google\Cloud\Core\Int64} object for 32 bit + * returned as a {@see \Google\Cloud\Core\Int64} object for 32 bit * platform compatibility. **Defaults to** false. * @return FirestoreClient */ @@ -189,7 +189,7 @@ public function firestore(array $config = []) * ``` * * @param array $config [optional] Configuration options. See - * {@see Google\Cloud\Core\ServiceBuilder::__construct()} for the available options. + * {@see \Google\Cloud\Core\ServiceBuilder::__construct()} for the available options. * @return LoggingClient */ public function logging(array $config = []) @@ -210,7 +210,7 @@ public function logging(array $config = []) * ``` * * @param array $config [optional] Configuration options. See - * {@see Google\Cloud\Core\ServiceBuilder::__construct()} for the available options. + * {@see \Google\Cloud\Core\ServiceBuilder::__construct()} for the available options. * @return LanguageClient */ public function language(array $config = []) @@ -230,7 +230,7 @@ public function language(array $config = []) * * @param array $config [optional] { * Configuration options. See - * {@see Google\Cloud\Core\ServiceBuilder::__construct()} for the other available options. + * {@see \Google\Cloud\Core\ServiceBuilder::__construct()} for the other available options. * * @type string $transport The transport type used for requests. May be * either `grpc` or `rest`. **Defaults to** `grpc` if gRPC support @@ -254,10 +254,10 @@ public function pubsub(array $config = []) * * @param array $config [optional] { * Configuration options. See - * {@see Google\Cloud\Core\ServiceBuilder::__construct()} for the other available options. + * {@see \Google\Cloud\Core\ServiceBuilder::__construct()} for the other available options. * * @type bool $returnInt64AsObject If true, 64 bit integers will be - * returned as a {@see Google\Cloud\Core\Int64} object for 32 bit + * returned as a {@see \Google\Cloud\Core\Int64} object for 32 bit * platform compatibility. **Defaults to** false. * } * @return SpannerClient @@ -282,7 +282,7 @@ public function spanner(array $config = []) * * @param array $config [optional] { * Configuration options. See - * {@see Google\Cloud\Core\ServiceBuilder::__construct()} for the other available options. + * {@see \Google\Cloud\Core\ServiceBuilder::__construct()} for the other available options. * * @type string $languageCode The language of the content to * be recognized. Only BCP-47 (e.g., `"en-US"`, `"es-ES"`) @@ -307,7 +307,7 @@ public function speech(array $config = []) * ``` * * @param array $config [optional] Configuration options. See - * {@see Google\Cloud\Core\ServiceBuilder::__construct()} for the available options. + * {@see \Google\Cloud\Core\ServiceBuilder::__construct()} for the available options. * @return StorageClient */ public function storage(array $config = []) @@ -327,7 +327,7 @@ public function storage(array $config = []) * ``` * * @param array $config [optional] Configuration options. See - * {@see Google\Cloud\Core\ServiceBuilder::__construct()} for the available options. + * {@see \Google\Cloud\Core\ServiceBuilder::__construct()} for the available options. * @return TraceClient */ public function trace(array $config = []) @@ -347,7 +347,7 @@ public function trace(array $config = []) * ``` * * @param array $config [optional] Configuration options. See - * {@see Google\Cloud\Core\ServiceBuilder::__construct()} for the available options. + * {@see \Google\Cloud\Core\ServiceBuilder::__construct()} for the available options. * @return VisionClient */ public function vision(array $config = []) diff --git a/lib/Google/vendor/google/cloud-core/src/Testing/TestHelpers.php b/lib/Google/vendor/google/cloud-core/src/Testing/TestHelpers.php index c8e20d45f..2e832559b 100644 --- a/lib/Google/vendor/google/cloud-core/src/Testing/TestHelpers.php +++ b/lib/Google/vendor/google/cloud-core/src/Testing/TestHelpers.php @@ -131,7 +131,7 @@ public static function snippetBootstrap() */ public static function perfBootstrap() { - $bootstraps = glob(self::projectRoot() .'/*/tests/Perf/bootstrap.php'); + $bootstraps = glob(self::projectRoot() .'/*tests/Perf/bootstrap.php'); foreach ($bootstraps as $bootstrap) { require_once $bootstrap; } @@ -186,7 +186,9 @@ public static function systemBootstrap() SystemTestCase::setupQueue(); - $bootstraps = glob(self::projectRoot() .'/*/tests/System/bootstrap.php'); + // also set up the generated system tests + self::generatedSystemTestBootstrap(); + $bootstraps = glob(self::projectRoot() .'/*tests/System/bootstrap.php'); foreach ($bootstraps as $bootstrap) { require_once $bootstrap; } @@ -212,7 +214,7 @@ public static function generatedSystemTestBootstrap() putenv("GOOGLE_APPLICATION_CREDENTIALS=$keyFilePath"); $keyFileData = json_decode(file_get_contents($keyFilePath), true); putenv('PROJECT_ID=' . $keyFileData['project_id']); - + putenv('GOOGLE_PROJECT_ID=' . $keyFileData['project_id']); } /** diff --git a/lib/Google/vendor/google/cloud-core/src/Upload/ResumableUploader.php b/lib/Google/vendor/google/cloud-core/src/Upload/ResumableUploader.php index b47fbc2bb..6e61546fe 100644 --- a/lib/Google/vendor/google/cloud-core/src/Upload/ResumableUploader.php +++ b/lib/Google/vendor/google/cloud-core/src/Upload/ResumableUploader.php @@ -52,8 +52,8 @@ class ResumableUploader extends AbstractUploader /** * Classes extending ResumableUploader may provide request headers to be - * included in {@see Google\Cloud\Core\Upload\ResumableUploader::upload()} - * and {@see Google\Cloud\Core\Upload\ResumableUploader::createResumeUri{}}. + * included in {@see \Google\Cloud\Core\Upload\ResumableUploader::upload()} + * and {@see \Google\Cloud\Core\Upload\ResumableUploader::createResumeUri{}}. * * @var array */ @@ -142,7 +142,7 @@ public function resume($resumeUri) * Triggers the upload process. * * Errors are of form [`google.rpc.Status`](https://cloud.google.com/apis/design/errors#error_model), - * and may be obtained via {@see Google\Cloud\Core\Exception\ServiceException::getMetadata()}. + * and may be obtained via {@see \Google\Cloud\Core\Exception\ServiceException::getMetadata()}. * * @return array * @throws ServiceException diff --git a/lib/Google/vendor/google/cloud-storage/.repo-metadata.json b/lib/Google/vendor/google/cloud-storage/.repo-metadata.json index cfa4cf227..cec1634b2 100644 --- a/lib/Google/vendor/google/cloud-storage/.repo-metadata.json +++ b/lib/Google/vendor/google/cloud-storage/.repo-metadata.json @@ -1,4 +1,5 @@ { + "language": "php", "distribution_name": "google/cloud-storage", "release_level": "stable", "client_documentation": "https://cloud.google.com/php/docs/reference/cloud-storage/latest", diff --git a/lib/Google/vendor/google/cloud-storage/VERSION b/lib/Google/vendor/google/cloud-storage/VERSION index 3492b09b4..39fc130ef 100644 --- a/lib/Google/vendor/google/cloud-storage/VERSION +++ b/lib/Google/vendor/google/cloud-storage/VERSION @@ -1 +1 @@ -1.31.2 +1.36.0 diff --git a/lib/Google/vendor/google/cloud-storage/composer.json b/lib/Google/vendor/google/cloud-storage/composer.json index 703df7e52..a5d1195db 100644 --- a/lib/Google/vendor/google/cloud-storage/composer.json +++ b/lib/Google/vendor/google/cloud-storage/composer.json @@ -5,8 +5,7 @@ "minimum-stability": "stable", "require": { "php": ">=7.4", - "google/cloud-core": "^1.51.1", - "google/crc32": "^0.2.0", + "google/cloud-core": "^1.52.7", "ramsey/uuid": "^4.2.3" }, "require-dev": { diff --git a/lib/Google/vendor/google/cloud-storage/src/Acl.php b/lib/Google/vendor/google/cloud-storage/src/Acl.php index 8cfae7213..c7f19f6d8 100644 --- a/lib/Google/vendor/google/cloud-storage/src/Acl.php +++ b/lib/Google/vendor/google/cloud-storage/src/Acl.php @@ -45,6 +45,7 @@ class Acl /** * @var ConnectionInterface Represents a connection to Cloud Storage. + * @internal */ protected $connection; @@ -55,7 +56,8 @@ class Acl /** * @param ConnectionInterface $connection Represents a connection to - * Cloud Storage. + * Cloud Storage. This object is created by StorageClient, + * and should not be instantiated outside of this client. * @param string $type The type of access control this instance applies to. * @param array $identity Represents which bucket, file, or generation this * instance applies to. @@ -78,8 +80,10 @@ public function __construct(ConnectionInterface $connection, $type, array $ident } /** - * Delete access controls on a {@see Google\Cloud\Storage\Bucket} or - * {@see Google\Cloud\Storage\StorageObject} for a specified entity. + * Delete access controls. + * + * Delete access controls on a {@see Bucket} or + * {@see StorageObject} for a specified entity. * * Example: * ``` @@ -104,8 +108,10 @@ public function delete($entity, array $options = []) } /** - * Get access controls on a {@see Google\Cloud\Storage\Bucket} or - * {@see Google\Cloud\Storage\StorageObject}. By default this will return all available + * Get access controls. + * + * Get access controls on a {@see Bucket} or + * {@see StorageObject}. By default this will return all available * access controls. You may optionally specify a single entity to return * details for as well. * @@ -139,8 +145,10 @@ public function get(array $options = []) } /** - * Add access controls on a {@see Google\Cloud\Storage\Bucket} or - * {@see Google\Cloud\Storage\StorageObject}. + * Add access controls. + * + * Add access controls on a {@see Bucket} or + * {@see StorageObject}. * * Example: * ``` @@ -171,8 +179,9 @@ public function add($entity, $role, array $options = []) } /** - * Update access controls on a {@see Google\Cloud\Storage\Bucket} or - * {@see Google\Cloud\Storage\StorageObject}. + * Update access controls. + * + * Update access controls on a {@see Bucket} or {@see StorageObject}. * * Example: * ``` diff --git a/lib/Google/vendor/google/cloud-storage/src/Bucket.php b/lib/Google/vendor/google/cloud-storage/src/Bucket.php index abad33b77..cc215b1db 100644 --- a/lib/Google/vendor/google/cloud-storage/src/Bucket.php +++ b/lib/Google/vendor/google/cloud-storage/src/Bucket.php @@ -65,6 +65,7 @@ class Bucket /** * @var ConnectionInterface Represents a connection to Cloud Storage. + * @internal */ private $connection; @@ -95,7 +96,8 @@ class Bucket /** * @param ConnectionInterface $connection Represents a connection to Cloud - * Storage. + * Storage. This object is created by StorageClient, + * and should not be instantiated outside of this client. * @param string $name The bucket's name. * @param array $info [optional] The bucket's metadata. */ @@ -265,6 +267,13 @@ public function exists(array $options = []) * Acceptable values include, `"authenticatedRead"`, * `"bucketOwnerFullControl"`, `"bucketOwnerRead"`, `"private"`, * `"projectPrivate"`, and `"publicRead"`. + * @type array $retention The full list of available options are outlined + * at the [JSON API docs](https://cloud.google.com/storage/docs/json_api/v1/objects/insert#request-body). + * @type string $retention.retainUntilTime The earliest time in RFC 3339 + * UTC "Zulu" format that the object can be deleted or replaced. + * This is the retention configuration set for this object. + * @type string $retention.mode The mode of the retention configuration, + * which can be either `"Unlocked"` or `"Locked"`. * @type array $metadata The full list of available options are outlined * at the [JSON API docs](https://cloud.google.com/storage/docs/json_api/v1/objects/insert#request-body). * @type array $metadata.metadata User-provided metadata, in key/value pairs. @@ -564,8 +573,10 @@ public function getStreamableUploader($data, array $options = []) /** * Lazily instantiates an object. There are no network requests made at this - * point. To see the operations that can be performed on an object please - * see {@see Google\Cloud\Storage\StorageObject}. + * point. + * + * To see the operations that can be performed on an object please + * see {@see StorageObject}. * * Example: * ``` @@ -647,6 +658,9 @@ public function object($name, array $options = []) * distinct results. **Defaults to** `false`. * @type string $fields Selector which will cause the response to only * return the specified fields. + * @type string $matchGlob A glob pattern to filter results. The string + * value must be UTF-8 encoded. See: + * https://cloud.google.com/storage/docs/json_api/v1/objects/list#list-object-glob * } * @return ObjectIterator */ @@ -756,7 +770,7 @@ function (array $object) { * } * @return Notification * @throws \InvalidArgumentException When providing a type other than string - * or {@see Google\Cloud\PubSub\Topic} as $topic. + * or {@see \Google\Cloud\PubSub\Topic} as $topic. * @throws GoogleException When a project ID has not been detected. * @experimental The experimental flag means that while we believe this * method or class is ready for use, it may change before release in @@ -782,8 +796,10 @@ public function createNotification($topic, array $options = []) /** * Lazily instantiates a notification. There are no network requests made at - * this point. To see the operations that can be performed on a notification - * please see {@see Google\Cloud\Storage\Notification}. + * this point. + * + * To see the operations that can be performed on a notification + * please see {@see Notification}. * * Example: * ``` @@ -948,6 +964,8 @@ public function delete(array $options = []) * Buckets can have either StorageClass OLM rules or Autoclass, * but not both. When Autoclass is enabled on a bucket, adding * StorageClass OLM rules will result in failure. + * For more information, refer to + * [Storage Autoclass](https://cloud.google.com/storage/docs/autoclass) * @type array $versioning The bucket's versioning configuration. * @type array $website The bucket's website configuration. * @type array $billing The bucket's billing configuration. @@ -970,7 +988,7 @@ public function delete(array $options = []) * occurs, signified by the hold's release. * @type array $retentionPolicy Defines the retention policy for a * bucket. In order to lock a retention policy, please see - * {@see Google\Cloud\Storage\Bucket::lockRetentionPolicy()}. + * {@see Bucket::lockRetentionPolicy()}. * @type int $retentionPolicy.retentionPeriod Specifies the duration * that objects need to be retained, in seconds. Retention * duration must be greater than zero and less than 100 years. @@ -1182,8 +1200,8 @@ public function name() * replace the configuration with the rules provided by this builder. * * This builder is intended to be used in tandem with - * {@see Google\Cloud\Storage\StorageClient::createBucket()} and - * {@see Google\Cloud\Storage\Bucket::update()}. + * {@see StorageClient::createBucket()} and + * {@see Bucket::update()}. * * Example: * ``` @@ -1213,13 +1231,15 @@ public static function lifecycle(array $lifecycle = []) /** * Retrieves a lifecycle builder preconfigured with the lifecycle rules that - * already exists on the bucket. Use this if you want to make updates to an + * already exists on the bucket. + * + * Use this if you want to make updates to an * existing configuration without removing existing rules, as would be the - * case when using {@see Google\Cloud\Storage\Bucket::lifecycle()}. + * case when using {@see Bucket::lifecycle()}. * * This builder is intended to be used in tandem with - * {@see Google\Cloud\Storage\StorageClient::createBucket()} and - * {@see Google\Cloud\Storage\Bucket::update()}. + * {@see StorageClient::createBucket()} and + * {@see Bucket::update()}. * * Please note, this method may trigger a network request in order to fetch * the existing lifecycle rules from the server. @@ -1341,8 +1361,8 @@ public function iam() * metageneration value will need to be available. It can either be supplied * explicitly through the `ifMetagenerationMatch` option or detected for you * by ensuring a value is cached locally (by calling - * {@see Google\Cloud\Storage\Bucket::reload()} or - * {@see Google\Cloud\Storage\Bucket::info()}, for example). + * {@see Bucket::reload()} or + * {@see Bucket::info()}, for example). * * Example: * ``` @@ -1414,7 +1434,7 @@ public function lockRetentionPolicy(array $options = []) * @see https://cloud.google.com/storage/docs/access-control/signed-urls Signed URLs * * @param Timestamp|\DateTimeInterface|int $expires Specifies when the URL - * will expire. May provide an instance of {@see Google\Cloud\Core\Timestamp}, + * will expire. May provide an instance of {@see \Google\Cloud\Core\Timestamp}, * [http://php.net/datetimeimmutable](`\DateTimeImmutable`), or a * UNIX timestamp as an integer. * @param array $options { @@ -1520,7 +1540,7 @@ public function signedUrl($expires, array $options = []) * @param string $objectName The path to the file in Google Cloud Storage, * relative to the bucket. * @param Timestamp|\DateTimeInterface|int $expires Specifies when the URL - * will expire. May provide an instance of {@see Google\Cloud\Core\Timestamp}, + * will expire. May provide an instance of {@see \Google\Cloud\Core\Timestamp}, * [http://php.net/datetimeimmutable](`\DateTimeImmutable`), or a * UNIX timestamp as an integer. * @param array $options [optional] { diff --git a/lib/Google/vendor/google/cloud-storage/src/Connection/ConnectionInterface.php b/lib/Google/vendor/google/cloud-storage/src/Connection/ConnectionInterface.php index 819597029..71df234e5 100644 --- a/lib/Google/vendor/google/cloud-storage/src/Connection/ConnectionInterface.php +++ b/lib/Google/vendor/google/cloud-storage/src/Connection/ConnectionInterface.php @@ -20,6 +20,8 @@ /** * Represents a connection to * [Cloud Storage](https://cloud.google.com/storage/). + * + * @internal */ interface ConnectionInterface { diff --git a/lib/Google/vendor/google/cloud-storage/src/Connection/IamBucket.php b/lib/Google/vendor/google/cloud-storage/src/Connection/IamBucket.php index 4a1d2511c..084ced8f6 100644 --- a/lib/Google/vendor/google/cloud-storage/src/Connection/IamBucket.php +++ b/lib/Google/vendor/google/cloud-storage/src/Connection/IamBucket.php @@ -21,6 +21,8 @@ /** * IAM Implementation for GCS Buckets + * + * @internal */ class IamBucket implements IamConnectionInterface { diff --git a/lib/Google/vendor/google/cloud-storage/src/Connection/Rest.php b/lib/Google/vendor/google/cloud-storage/src/Connection/Rest.php index 4cab69fc6..2b37bb283 100644 --- a/lib/Google/vendor/google/cloud-storage/src/Connection/Rest.php +++ b/lib/Google/vendor/google/cloud-storage/src/Connection/Rest.php @@ -29,8 +29,6 @@ use Google\Cloud\Core\UriTrait; use Google\Cloud\Storage\Connection\ConnectionInterface; use Google\Cloud\Storage\StorageClient; -use Google\CRC32\Builtin; -use Google\CRC32\CRC32; use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Psr7\MimeType; use GuzzleHttp\Psr7\Request; @@ -43,6 +41,8 @@ /** * Implementation of the * [Google Cloud Storage JSON API](https://cloud.google.com/storage/docs/json_api/). + * + * @internal */ class Rest implements ConnectionInterface { @@ -431,6 +431,12 @@ private function resolveUploadOptions(array $args) } $args['metadata']['name'] = $args['name']; + if (isset($args['retention'])) { + // during object creation retention properties go into metadata + // but not into request body + $args['metadata']['retention'] = $args['retention']; + unset($args['retention']); + } unset($args['name']); $args['contentType'] = $args['metadata']['contentType'] ?? MimeType::fromFilename($args['metadata']['name']); @@ -660,21 +666,15 @@ private function chooseValidationMethod(array $args) private function crcFromStream(StreamInterface $data) { $pos = $data->tell(); - - if ($pos > 0) { - $data->rewind(); - } - - $crc32c = CRC32::create(CRC32::CASTAGNOLI); - $data->rewind(); + $crc32c = hash_init('crc32c'); while (!$data->eof()) { - $crc32c->update($data->read(1048576)); + $buffer = $data->read(1048576); + hash_update($crc32c, $buffer); } - $data->seek($pos); - - return base64_encode($crc32c->hash(true)); + $hash = hash_final($crc32c, true); + return base64_encode($hash); } /** @@ -692,13 +692,12 @@ protected function crc32cExtensionLoaded() /** * Check if hash() supports crc32c. * - * Protected access for unit testing. - * + * @deprecated * @return bool */ protected function supportsBuiltinCrc32c() { - return Builtin::supports(CRC32::CASTAGNOLI); + return extension_loaded('hash') && in_array('crc32c', hash_algos()); } /** diff --git a/lib/Google/vendor/google/cloud-storage/src/Connection/ServiceDefinition/storage-v1.json b/lib/Google/vendor/google/cloud-storage/src/Connection/ServiceDefinition/storage-v1.json index f503978ce..25303d3bf 100644 --- a/lib/Google/vendor/google/cloud-storage/src/Connection/ServiceDefinition/storage-v1.json +++ b/lib/Google/vendor/google/cloud-storage/src/Connection/ServiceDefinition/storage-v1.json @@ -1,4278 +1,5391 @@ { - "kind": "discovery#restDescription", - "version": "v1", - "id": "storage:v1", - "rootUrl": "https://storage.googleapis.com/", - "mtlsRootUrl": "https://storage.mtls.googleapis.com/", - "baseUrl": "https://storage.googleapis.com/storage/v1/", - "basePath": "/storage/v1/", - "servicePath": "storage/v1/", - "batchPath": "batch/storage/v1", - "discoveryVersion": "v1", - "name": "storage", - "title": "Cloud Storage JSON API", - "description": "Stores and retrieves potentially large, immutable data objects.", - "ownerDomain": "google.com", - "ownerName": "Google", - "icons": { - "x16": "https://www.google.com/images/icons/product/cloud_storage-16.png", - "x32": "https://www.google.com/images/icons/product/cloud_storage-32.png" + "kind": "discovery#restDescription", + "version": "v1", + "id": "storage:v1", + "rootUrl": "https://storage.googleapis.com/", + "mtlsRootUrl": "https://storage.mtls.googleapis.com/", + "baseUrl": "https://storage.googleapis.com/storage/v1/", + "basePath": "/storage/v1/", + "servicePath": "storage/v1/", + "batchPath": "batch/storage/v1", + "discoveryVersion": "v1", + "name": "storage", + "title": "Cloud Storage JSON API", + "description": "Stores and retrieves potentially large, immutable data objects.", + "ownerDomain": "google.com", + "ownerName": "Google", + "icons": { + "x16": "https://www.google.com/images/icons/product/cloud_storage-16.png", + "x32": "https://www.google.com/images/icons/product/cloud_storage-32.png" + }, + "documentationLink": "https://developers.google.com/storage/docs/json_api/", + "labels": [ + "labs" + ], + "protocol": "rest", + "parameters": { + "alt": { + "type": "string", + "description": "Data format for the response.", + "default": "json", + "enum": [ + "json" + ], + "enumDescriptions": [ + "Responses with Content-Type of application/json" + ], + "location": "query" }, - "documentationLink": "https://developers.google.com/storage/docs/json_api/", - "labels": [ - "labs" - ], - "protocol": "rest", - "parameters": { - "alt": { - "type": "string", - "description": "Data format for the response.", - "default": "json", - "enum": [ - "json" - ], - "enumDescriptions": [ - "Responses with Content-Type of application/json" - ], - "location": "query" - }, - "fields": { - "type": "string", - "description": "Selector specifying which fields to include in a partial response.", - "location": "query" - }, - "key": { - "type": "string", - "description": "API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.", - "location": "query" - }, - "oauth_token": { - "type": "string", - "description": "OAuth 2.0 token for the current user.", - "location": "query" - }, - "prettyPrint": { - "type": "boolean", - "description": "Returns response with indentations and line breaks.", - "default": "true", - "location": "query" - }, - "quotaUser": { - "type": "string", - "description": "An opaque string that represents a user for quota purposes. Must not exceed 40 characters.", - "location": "query" - }, - "userIp": { - "type": "string", - "description": "Deprecated. Please use quotaUser instead.", - "location": "query" + "fields": { + "type": "string", + "description": "Selector specifying which fields to include in a partial response.", + "location": "query" + }, + "key": { + "type": "string", + "description": "API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.", + "location": "query" + }, + "oauth_token": { + "type": "string", + "description": "OAuth 2.0 token for the current user.", + "location": "query" + }, + "prettyPrint": { + "type": "boolean", + "description": "Returns response with indentations and line breaks.", + "default": "true", + "location": "query" + }, + "quotaUser": { + "type": "string", + "description": "An opaque string that represents a user for quota purposes. Must not exceed 40 characters.", + "location": "query" + }, + "userIp": { + "type": "string", + "description": "Deprecated. Please use quotaUser instead.", + "location": "query" }, "uploadType": { - "type": "string", - "description": "Upload protocol for media (e.g. \"media\", \"multipart\", \"resumable\").", - "location": "query" + "type": "string", + "description": "Upload protocol for media (e.g. \"media\", \"multipart\", \"resumable\").", + "location": "query" + } + }, + "auth": { + "oauth2": { + "scopes": { + "https://www.googleapis.com/auth/cloud-platform": { + "description": "View and manage your data across Google Cloud Platform services" + }, + "https://www.googleapis.com/auth/cloud-platform.read-only": { + "description": "View your data across Google Cloud Platform services" + }, + "https://www.googleapis.com/auth/devstorage.full_control": { + "description": "Manage your data and permissions in Google Cloud Storage" + }, + "https://www.googleapis.com/auth/devstorage.read_only": { + "description": "View your data in Google Cloud Storage" + }, + "https://www.googleapis.com/auth/devstorage.read_write": { + "description": "Manage your data in Google Cloud Storage" + } } - }, - "auth": { - "oauth2": { - "scopes": { - "https://www.googleapis.com/auth/cloud-platform": { - "description": "View and manage your data across Google Cloud Platform services" - }, - "https://www.googleapis.com/auth/cloud-platform.read-only": { - "description": "View your data across Google Cloud Platform services" - }, - "https://www.googleapis.com/auth/devstorage.full_control": { - "description": "Manage your data and permissions in Google Cloud Storage" - }, - "https://www.googleapis.com/auth/devstorage.read_only": { - "description": "View your data in Google Cloud Storage" + } + }, + "schemas": { + "Bucket": { + "id": "Bucket", + "type": "object", + "description": "A bucket.", + "properties": { + "acl": { + "type": "array", + "description": "Access controls on the bucket.", + "items": { + "$ref": "BucketAccessControl" }, - "https://www.googleapis.com/auth/devstorage.read_write": { - "description": "Manage your data in Google Cloud Storage" + "annotations": { + "required": [ + "storage.buckets.update" + ] } - } - } - }, - "schemas": { - "Bucket": { - "id": "Bucket", - "type": "object", - "description": "A bucket.", - "properties": { - "acl": { - "type": "array", - "description": "Access controls on the bucket.", - "items": { - "$ref": "BucketAccessControl" - }, - "annotations": { - "required": [ - "storage.buckets.update" - ] + }, + "billing": { + "type": "object", + "description": "The bucket's billing configuration.", + "properties": { + "requesterPays": { + "type": "boolean", + "description": "When set to true, Requester Pays is enabled for this bucket." } - }, - "billing": { + } + }, + "cors": { + "type": "array", + "description": "The bucket's Cross-Origin Resource Sharing (CORS) configuration.", + "items": { "type": "object", - "description": "The bucket's billing configuration.", "properties": { - "requesterPays": { - "type": "boolean", - "description": "When set to true, Requester Pays is enabled for this bucket." + "maxAgeSeconds": { + "type": "integer", + "description": "The value, in seconds, to return in the Access-Control-Max-Age header used in preflight responses.", + "format": "int32" + }, + "method": { + "type": "array", + "description": "The list of HTTP methods on which to include CORS response headers, (GET, OPTIONS, POST, etc) Note: \"*\" is permitted in the list of methods, and means \"any method\".", + "items": { + "type": "string" + } + }, + "origin": { + "type": "array", + "description": "The list of Origins eligible to receive CORS response headers. Note: \"*\" is permitted in the list of origins, and means \"any Origin\".", + "items": { + "type": "string" + } + }, + "responseHeader": { + "type": "array", + "description": "The list of HTTP headers other than the simple response headers to give permission for the user-agent to share across domains.", + "items": { + "type": "string" + } } } - }, - "cors": { - "type": "array", - "description": "The bucket's Cross-Origin Resource Sharing (CORS) configuration.", - "items": { + } + }, + "customPlacementConfig": { + "type": "object", + "description": "The bucket's custom placement configuration for Custom Dual Regions.", + "properties": { + "dataLocations": { + "type": "array", + "description": "The list of regional locations in which data is placed.", + "items": { + "type": "string" + } + } + } + }, + "defaultEventBasedHold": { + "type": "boolean", + "description": "The default value for event-based hold on newly created objects in this bucket. Event-based hold is a way to retain objects indefinitely until an event occurs, signified by the hold's release. After being released, such objects will be subject to bucket-level retention (if any). One sample use case of this flag is for banks to hold loan documents for at least 3 years after loan is paid in full. Here, bucket-level retention is 3 years and the event is loan being paid in full. In this example, these objects will be held intact for any number of years until the event has occurred (event-based hold on the object is released) and then 3 more years after that. That means retention duration of the objects begins from the moment event-based hold transitioned from true to false. Objects under event-based hold cannot be deleted, overwritten or archived until the hold is removed." + }, + "defaultObjectAcl": { + "type": "array", + "description": "Default access controls to apply to new objects when no ACL is provided.", + "items": { + "$ref": "ObjectAccessControl" + } + }, + "encryption": { + "type": "object", + "description": "Encryption configuration for a bucket.", + "properties": { + "defaultKmsKeyName": { + "type": "string", + "description": "A Cloud KMS key that will be used to encrypt objects inserted into this bucket, if no encryption method is specified." + } + } + }, + "etag": { + "type": "string", + "description": "HTTP 1.1 Entity tag for the bucket." + }, + "iamConfiguration": { + "type": "object", + "description": "The bucket's IAM configuration.", + "properties": { + "bucketPolicyOnly": { "type": "object", + "description": "The bucket's uniform bucket-level access configuration. The feature was formerly known as Bucket Policy Only. For backward compatibility, this field will be populated with identical information as the uniformBucketLevelAccess field. We recommend using the uniformBucketLevelAccess field to enable and disable the feature.", "properties": { - "maxAgeSeconds": { - "type": "integer", - "description": "The value, in seconds, to return in the Access-Control-Max-Age header used in preflight responses.", - "format": "int32" - }, - "method": { - "type": "array", - "description": "The list of HTTP methods on which to include CORS response headers, (GET, OPTIONS, POST, etc) Note: \"*\" is permitted in the list of methods, and means \"any method\".", - "items": { - "type": "string" - } - }, - "origin": { - "type": "array", - "description": "The list of Origins eligible to receive CORS response headers. Note: \"*\" is permitted in the list of origins, and means \"any Origin\".", - "items": { - "type": "string" - } + "enabled": { + "type": "boolean", + "description": "If set, access is controlled only by bucket-level or above IAM policies." }, - "responseHeader": { - "type": "array", - "description": "The list of HTTP headers other than the simple response headers to give permission for the user-agent to share across domains.", - "items": { - "type": "string" - } + "lockedTime": { + "type": "string", + "description": "The deadline for changing iamConfiguration.bucketPolicyOnly.enabled from true to false in RFC 3339 format. iamConfiguration.bucketPolicyOnly.enabled may be changed from true to false until the locked time, after which the field is immutable.", + "format": "date-time" } } - } - }, - "customPlacementConfig": { - "type": "object", - "description": "The bucket's custom placement configuration for Custom Dual Regions.", - "properties": { - "dataLocations": { - "type": "array", - "description": "The list of regional locations in which data is placed.", - "items": { - "type": "string" - } + }, + "uniformBucketLevelAccess": { + "type": "object", + "description": "The bucket's uniform bucket-level access configuration.", + "properties": { + "enabled": { + "type": "boolean", + "description": "If set, access is controlled only by bucket-level or above IAM policies." + }, + "lockedTime": { + "type": "string", + "description": "The deadline for changing iamConfiguration.uniformBucketLevelAccess.enabled from true to false in RFC 3339 format. iamConfiguration.uniformBucketLevelAccess.enabled may be changed from true to false until the locked time, after which the field is immutable.", + "format": "date-time" } - } - }, - "defaultEventBasedHold": { - "type": "boolean", - "description": "The default value for event-based hold on newly created objects in this bucket. Event-based hold is a way to retain objects indefinitely until an event occurs, signified by the hold's release. After being released, such objects will be subject to bucket-level retention (if any). One sample use case of this flag is for banks to hold loan documents for at least 3 years after loan is paid in full. Here, bucket-level retention is 3 years and the event is loan being paid in full. In this example, these objects will be held intact for any number of years until the event has occurred (event-based hold on the object is released) and then 3 more years after that. That means retention duration of the objects begins from the moment event-based hold transitioned from true to false. Objects under event-based hold cannot be deleted, overwritten or archived until the hold is removed." - }, - "defaultObjectAcl": { - "type": "array", - "description": "Default access controls to apply to new objects when no ACL is provided.", - "items": { - "$ref": "ObjectAccessControl" - } - }, - "encryption": { - "type": "object", - "description": "Encryption configuration for a bucket.", - "properties": { - "defaultKmsKeyName": { - "type": "string", - "description": "A Cloud KMS key that will be used to encrypt objects inserted into this bucket, if no encryption method is specified." } + }, + "publicAccessPrevention": { + "type": "string", + "description": "The bucket's Public Access Prevention configuration. Currently, 'inherited' and 'enforced' are supported." } - }, - "etag": { + } + }, + "id": { + "type": "string", + "description": "The ID of the bucket. For buckets, the id and name properties are the same." + }, + "kind": { + "type": "string", + "description": "The kind of item this is. For buckets, this is always storage#bucket.", + "default": "storage#bucket" + }, + "labels": { + "type": "object", + "description": "User-provided labels, in key/value pairs.", + "additionalProperties": { "type": "string", - "description": "HTTP 1.1 Entity tag for the bucket." - }, - "iamConfiguration": { - "type": "object", - "description": "The bucket's IAM configuration.", - "properties": { - "bucketPolicyOnly": { - "type": "object", - "description": "The bucket's uniform bucket-level access configuration. The feature was formerly known as Bucket Policy Only. For backward compatibility, this field will be populated with identical information as the uniformBucketLevelAccess field. We recommend using the uniformBucketLevelAccess field to enable and disable the feature.", - "properties": { - "enabled": { - "type": "boolean", - "description": "If set, access is controlled only by bucket-level or above IAM policies." - }, - "lockedTime": { - "type": "string", - "description": "The deadline for changing iamConfiguration.bucketPolicyOnly.enabled from true to false in RFC 3339 format. iamConfiguration.bucketPolicyOnly.enabled may be changed from true to false until the locked time, after which the field is immutable.", - "format": "date-time" - } - } - }, - "uniformBucketLevelAccess": { + "description": "An individual label entry." + } + }, + "lifecycle": { + "type": "object", + "description": "The bucket's lifecycle configuration. See lifecycle management for more information.", + "properties": { + "rule": { + "type": "array", + "description": "A lifecycle management rule, which is made of an action to take and the condition(s) under which the action will be taken.", + "items": { "type": "object", - "description": "The bucket's uniform bucket-level access configuration.", "properties": { - "enabled": { - "type": "boolean", - "description": "If set, access is controlled only by bucket-level or above IAM policies." - }, - "lockedTime": { - "type": "string", - "description": "The deadline for changing iamConfiguration.uniformBucketLevelAccess.enabled from true to false in RFC 3339 format. iamConfiguration.uniformBucketLevelAccess.enabled may be changed from true to false until the locked time, after which the field is immutable.", - "format": "date-time" - } - } - }, - "publicAccessPrevention": { - "type": "string", - "description": "The bucket's Public Access Prevention configuration. Currently, 'inherited' and 'enforced' are supported." - } - } - }, - "id": { - "type": "string", - "description": "The ID of the bucket. For buckets, the id and name properties are the same." - }, - "kind": { - "type": "string", - "description": "The kind of item this is. For buckets, this is always storage#bucket.", - "default": "storage#bucket" - }, - "labels": { - "type": "object", - "description": "User-provided labels, in key/value pairs.", - "additionalProperties": { - "type": "string", - "description": "An individual label entry." - } - }, - "lifecycle": { - "type": "object", - "description": "The bucket's lifecycle configuration. See lifecycle management for more information.", - "properties": { - "rule": { - "type": "array", - "description": "A lifecycle management rule, which is made of an action to take and the condition(s) under which the action will be taken.", - "items": { - "type": "object", - "properties": { - "action": { - "type": "object", - "description": "The action to take.", - "properties": { - "storageClass": { - "type": "string", - "description": "Target storage class. Required iff the type of the action is SetStorageClass." - }, - "type": { - "type": "string", + "action": { + "type": "object", + "description": "The action to take.", + "properties": { + "storageClass": { + "type": "string", + "description": "Target storage class. Required iff the type of the action is SetStorageClass." + }, + "type": { + "type": "string", "description": "Type of the action. Currently, only Delete, SetStorageClass, and AbortIncompleteMultipartUpload are supported." - } } - }, - "condition": { - "type": "object", - "description": "The condition(s) under which the action will be taken.", - "properties": { - "age": { - "type": "integer", - "description": "Age of an object (in days). This condition is satisfied when an object reaches the specified age.", - "format": "int32" - }, - "createdBefore": { - "type": "string", - "description": "A date in RFC 3339 format with only the date part (for instance, \"2013-01-15\"). This condition is satisfied when an object is created before midnight of the specified date in UTC.", - "format": "date" - }, - "customTimeBefore": { - "type": "string", - "description": "A date in RFC 3339 format with only the date part (for instance, \"2013-01-15\"). This condition is satisfied when the custom time on an object is before this date in UTC.", - "format": "date" - }, - "daysSinceCustomTime": { - "type": "integer", - "description": "Number of days elapsed since the user-specified timestamp set on an object. The condition is satisfied if the days elapsed is at least this number. If no custom timestamp is specified on an object, the condition does not apply.", - "format": "int32" - }, - "daysSinceNoncurrentTime": { - "type": "integer", - "description": "Number of days elapsed since the noncurrent timestamp of an object. The condition is satisfied if the days elapsed is at least this number. This condition is relevant only for versioned objects. The value of the field must be a nonnegative integer. If it's zero, the object version will become eligible for Lifecycle action as soon as it becomes noncurrent.", - "format": "int32" - }, - "isLive": { - "type": "boolean", - "description": "Relevant only for versioned objects. If the value is true, this condition matches live objects; if the value is false, it matches archived objects." - }, - "matchesPattern": { - "type": "string", - "description": "A regular expression that satisfies the RE2 syntax. This condition is satisfied when the name of the object matches the RE2 pattern. Note: This feature is currently in the \"Early Access\" launch stage and is only available to a whitelisted set of users; that means that this feature may be changed in backward-incompatible ways and that it is not guaranteed to be released." - }, - "matchesPrefix": { - "type": "array", - "description": "List of object name prefixes. This condition will be satisfied when at least one of the prefixes exactly matches the beginning of the object name.", - "items": { - "type": "string" - } - }, - "matchesSuffix": { - "type": "array", - "description": "List of object name suffixes. This condition will be satisfied when at least one of the suffixes exactly matches the end of the object name.", - "items": { - "type": "string" - } - }, - "matchesStorageClass": { - "type": "array", - "description": "Objects having any of the storage classes specified by this condition will be matched. Values include MULTI_REGIONAL, REGIONAL, NEARLINE, COLDLINE, ARCHIVE, STANDARD, and DURABLE_REDUCED_AVAILABILITY.", - "items": { - "type": "string" - } - }, - "noncurrentTimeBefore": { - "type": "string", - "description": "A date in RFC 3339 format with only the date part (for instance, \"2013-01-15\"). This condition is satisfied when the noncurrent time on an object is before this date in UTC. This condition is relevant only for versioned objects.", - "format": "date" - }, - "numNewerVersions": { - "type": "integer", - "description": "Relevant only for versioned objects. If the value is N, this condition is satisfied when there are at least N versions (including the live version) newer than this version of the object.", - "format": "int32" + } + }, + "condition": { + "type": "object", + "description": "The condition(s) under which the action will be taken.", + "properties": { + "age": { + "type": "integer", + "description": "Age of an object (in days). This condition is satisfied when an object reaches the specified age.", + "format": "int32" + }, + "createdBefore": { + "type": "string", + "description": "A date in RFC 3339 format with only the date part (for instance, \"2013-01-15\"). This condition is satisfied when an object is created before midnight of the specified date in UTC.", + "format": "date" + }, + "customTimeBefore": { + "type": "string", + "description": "A date in RFC 3339 format with only the date part (for instance, \"2013-01-15\"). This condition is satisfied when the custom time on an object is before this date in UTC.", + "format": "date" + }, + "daysSinceCustomTime": { + "type": "integer", + "description": "Number of days elapsed since the user-specified timestamp set on an object. The condition is satisfied if the days elapsed is at least this number. If no custom timestamp is specified on an object, the condition does not apply.", + "format": "int32" + }, + "daysSinceNoncurrentTime": { + "type": "integer", + "description": "Number of days elapsed since the noncurrent timestamp of an object. The condition is satisfied if the days elapsed is at least this number. This condition is relevant only for versioned objects. The value of the field must be a nonnegative integer. If it's zero, the object version will become eligible for Lifecycle action as soon as it becomes noncurrent.", + "format": "int32" + }, + "isLive": { + "type": "boolean", + "description": "Relevant only for versioned objects. If the value is true, this condition matches live objects; if the value is false, it matches archived objects." + }, + "matchesPattern": { + "type": "string", + "description": "A regular expression that satisfies the RE2 syntax. This condition is satisfied when the name of the object matches the RE2 pattern. Note: This feature is currently in the \"Early Access\" launch stage and is only available to a whitelisted set of users; that means that this feature may be changed in backward-incompatible ways and that it is not guaranteed to be released." + }, + "matchesPrefix": { + "type": "array", + "description": "List of object name prefixes. This condition will be satisfied when at least one of the prefixes exactly matches the beginning of the object name.", + "items": { + "type": "string" + } + }, + "matchesSuffix": { + "type": "array", + "description": "List of object name suffixes. This condition will be satisfied when at least one of the suffixes exactly matches the end of the object name.", + "items": { + "type": "string" } + }, + "matchesStorageClass": { + "type": "array", + "description": "Objects having any of the storage classes specified by this condition will be matched. Values include MULTI_REGIONAL, REGIONAL, NEARLINE, COLDLINE, ARCHIVE, STANDARD, and DURABLE_REDUCED_AVAILABILITY.", + "items": { + "type": "string" + } + }, + "noncurrentTimeBefore": { + "type": "string", + "description": "A date in RFC 3339 format with only the date part (for instance, \"2013-01-15\"). This condition is satisfied when the noncurrent time on an object is before this date in UTC. This condition is relevant only for versioned objects.", + "format": "date" + }, + "numNewerVersions": { + "type": "integer", + "description": "Relevant only for versioned objects. If the value is N, this condition is satisfied when there are at least N versions (including the live version) newer than this version of the object.", + "format": "int32" } } } } } } - }, + } + }, "autoclass": { - "type": "object", - "description": "The bucket's Autoclass configuration.", - "properties": { - "enabled": { - "type": "boolean", - "description": "Whether or not Autoclass is enabled on this bucket" - }, - "toggleTime": { - "type": "string", - "description": "A date and time in RFC 3339 format representing the instant at which \"enabled\" was last toggled.", - "format": "date-time" - } + "type": "object", + "description": "The bucket's Autoclass configuration.", + "properties": { + "enabled": { + "type": "boolean", + "description": "Whether or not Autoclass is enabled on this bucket" + }, + "toggleTime": { + "type": "string", + "description": "A date and time in RFC 3339 format representing the instant at which \"enabled\" was last toggled.", + "format": "date-time" + }, + "terminalStorageClass": { + "type": "string", + "description": "The storage class that objects in the bucket eventually transition to if they are not read for a certain length of time. Valid values are NEARLINE and ARCHIVE." + }, + "terminalStorageClassUpdateTime": { + "type": "string", + "description": "A date and time in RFC 3339 format representing the time of the most recent update to \"terminalStorageClass\".", + "format": "date-time" } + } }, - "location": { - "type": "string", - "description": "The location of the bucket. Object data for objects in the bucket resides in physical storage within this region. Defaults to US. See the developer's guide for the authoritative list." - }, - "locationType": { - "type": "string", - "description": "The type of the bucket location." - }, - "logging": { - "type": "object", - "description": "The bucket's logging configuration, which defines the destination bucket and optional name prefix for the current bucket's logs.", - "properties": { - "logBucket": { - "type": "string", - "description": "The destination bucket where the current bucket's logs should be placed." - }, - "logObjectPrefix": { - "type": "string", - "description": "A prefix for log object names." - } + "location": { + "type": "string", + "description": "The location of the bucket. Object data for objects in the bucket resides in physical storage within this region. Defaults to US. See the developer's guide for the authoritative list." + }, + "locationType": { + "type": "string", + "description": "The type of the bucket location." + }, + "logging": { + "type": "object", + "description": "The bucket's logging configuration, which defines the destination bucket and optional name prefix for the current bucket's logs.", + "properties": { + "logBucket": { + "type": "string", + "description": "The destination bucket where the current bucket's logs should be placed." + }, + "logObjectPrefix": { + "type": "string", + "description": "A prefix for log object names." } - }, - "metageneration": { - "type": "string", - "description": "The metadata generation of this bucket.", - "format": "int64" - }, - "name": { - "type": "string", - "description": "The name of the bucket.", - "annotations": { - "required": [ - "storage.buckets.insert" - ] + } + }, + "metageneration": { + "type": "string", + "description": "The metadata generation of this bucket.", + "format": "int64" + }, + "name": { + "type": "string", + "description": "The name of the bucket.", + "annotations": { + "required": [ + "storage.buckets.insert" + ] + } + }, + "owner": { + "type": "object", + "description": "The owner of the bucket. This is always the project team's owner group.", + "properties": { + "entity": { + "type": "string", + "description": "The entity, in the form project-owner-projectId." + }, + "entityId": { + "type": "string", + "description": "The ID for the entity." } - }, - "owner": { - "type": "object", - "description": "The owner of the bucket. This is always the project team's owner group.", - "properties": { - "entity": { - "type": "string", - "description": "The entity, in the form project-owner-projectId." - }, - "entityId": { - "type": "string", - "description": "The ID for the entity." - } + } + }, + "projectNumber": { + "type": "string", + "description": "The project number of the project the bucket belongs to.", + "format": "uint64" + }, + "retentionPolicy": { + "type": "object", + "description": "The bucket's retention policy. The retention policy enforces a minimum retention time for all objects contained in the bucket, based on their creation time. Any attempt to overwrite or delete objects younger than the retention period will result in a PERMISSION_DENIED error. An unlocked retention policy can be modified or removed from the bucket via a storage.buckets.update operation. A locked retention policy cannot be removed or shortened in duration for the lifetime of the bucket. Attempting to remove or decrease period of a locked retention policy will result in a PERMISSION_DENIED error.", + "properties": { + "effectiveTime": { + "type": "string", + "description": "Server-determined value that indicates the time from which policy was enforced and effective. This value is in RFC 3339 format.", + "format": "date-time" + }, + "isLocked": { + "type": "boolean", + "description": "Once locked, an object retention policy cannot be modified." + }, + "retentionPeriod": { + "type": "string", + "description": "The duration in seconds that objects need to be retained. Retention duration must be greater than zero and less than 100 years. Note that enforcement of retention periods less than a day is not guaranteed. Such periods should only be used for testing purposes.", + "format": "int64" } - }, - "projectNumber": { - "type": "string", - "description": "The project number of the project the bucket belongs to.", - "format": "uint64" - }, - "retentionPolicy": { - "type": "object", - "description": "The bucket's retention policy. The retention policy enforces a minimum retention time for all objects contained in the bucket, based on their creation time. Any attempt to overwrite or delete objects younger than the retention period will result in a PERMISSION_DENIED error. An unlocked retention policy can be modified or removed from the bucket via a storage.buckets.update operation. A locked retention policy cannot be removed or shortened in duration for the lifetime of the bucket. Attempting to remove or decrease period of a locked retention policy will result in a PERMISSION_DENIED error.", - "properties": { - "effectiveTime": { - "type": "string", - "description": "Server-determined value that indicates the time from which policy was enforced and effective. This value is in RFC 3339 format.", - "format": "date-time" - }, - "isLocked": { - "type": "boolean", - "description": "Once locked, an object retention policy cannot be modified." - }, - "retentionPeriod": { - "type": "string", - "description": "The duration in seconds that objects need to be retained. Retention duration must be greater than zero and less than 100 years. Note that enforcement of retention periods less than a day is not guaranteed. Such periods should only be used for testing purposes.", - "format": "int64" - } + } + }, + "objectRetention": { + "type": "object", + "description": "The bucket's object retention config.", + "properties": { + "mode": { + "type": "string", + "description": "The bucket's object retention mode. Can be Enabled." } - }, - "rpo": { - "type": "string", - "description": "The Recovery Point Objective (RPO) of this bucket. Set to ASYNC_TURBO to turn on Turbo Replication on a bucket." - }, - "selfLink": { - "type": "string", - "description": "The URI of this bucket." - }, - "storageClass": { - "type": "string", - "description": "The bucket's default storage class, used whenever no storageClass is specified for a newly-created object. This defines how objects in the bucket are stored and determines the SLA and the cost of storage. Values include MULTI_REGIONAL, REGIONAL, STANDARD, NEARLINE, COLDLINE, ARCHIVE, and DURABLE_REDUCED_AVAILABILITY. If this value is not specified when the bucket is created, it will default to STANDARD. For more information, see storage classes." - }, - "timeCreated": { - "type": "string", - "description": "The creation time of the bucket in RFC 3339 format.", - "format": "date-time" - }, - "updated": { - "type": "string", - "description": "The modification time of the bucket in RFC 3339 format.", - "format": "date-time" - }, - "versioning": { - "type": "object", - "description": "The bucket's versioning configuration.", - "properties": { - "enabled": { - "type": "boolean", - "description": "While set to true, versioning is fully enabled for this bucket." - } + } + }, + "rpo": { + "type": "string", + "description": "The Recovery Point Objective (RPO) of this bucket. Set to ASYNC_TURBO to turn on Turbo Replication on a bucket." + }, + "selfLink": { + "type": "string", + "description": "The URI of this bucket." + }, + "softDeletePolicy": { + "type": "object", + "description": "The bucket's soft delete policy, which defines the period of time that soft-deleted objects will be retained, and cannot be permanently deleted.", + "properties": { + "retentionDurationSeconds": { + "type": "string", + "description": "The duration in seconds that soft-deleted objects in the bucket will be retained and cannot be permanently deleted.", + "format": "int64" + }, + "effectiveTime": { + "type": "string", + "description": "Server-determined value that indicates the time from which the policy, or one with a greater retention, was effective. This value is in RFC 3339 format.", + "format": "date-time" } - }, - "website": { - "type": "object", - "description": "The bucket's website configuration, controlling how the service behaves when accessing bucket contents as a web site. See the Static Website Examples for more information.", - "properties": { - "mainPageSuffix": { - "type": "string", - "description": "If the requested object path is missing, the service will ensure the path has a trailing '/', append this suffix, and attempt to retrieve the resulting object. This allows the creation of index.html objects to represent directory pages." - }, - "notFoundPage": { - "type": "string", - "description": "If the requested object path is missing, and any mainPageSuffix object is missing, if applicable, the service will return the named object from this bucket as the content for a 404 Not Found result." - } + } + }, + "storageClass": { + "type": "string", + "description": "The bucket's default storage class, used whenever no storageClass is specified for a newly-created object. This defines how objects in the bucket are stored and determines the SLA and the cost of storage. Values include MULTI_REGIONAL, REGIONAL, STANDARD, NEARLINE, COLDLINE, ARCHIVE, and DURABLE_REDUCED_AVAILABILITY. If this value is not specified when the bucket is created, it will default to STANDARD. For more information, see storage classes." + }, + "timeCreated": { + "type": "string", + "description": "The creation time of the bucket in RFC 3339 format.", + "format": "date-time" + }, + "updated": { + "type": "string", + "description": "The modification time of the bucket in RFC 3339 format.", + "format": "date-time" + }, + "versioning": { + "type": "object", + "description": "The bucket's versioning configuration.", + "properties": { + "enabled": { + "type": "boolean", + "description": "While set to true, versioning is fully enabled for this bucket." } - }, - "satisfiesPZS": { - "type": "boolean", - "description": "Reserved for future use." } - } - }, - "BucketAccessControl": { - "id": "BucketAccessControl", - "type": "object", - "description": "An access-control entry.", - "properties": { - "bucket": { - "type": "string", - "description": "The name of the bucket." - }, - "domain": { - "type": "string", - "description": "The domain associated with the entity, if any." - }, - "email": { - "type": "string", - "description": "The email address associated with the entity, if any." - }, - "entity": { - "type": "string", - "description": "The entity holding the permission, in one of the following forms: \n- user-userId \n- user-email \n- group-groupId \n- group-email \n- domain-domain \n- project-team-projectId \n- allUsers \n- allAuthenticatedUsers Examples: \n- The user liz@example.com would be user-liz@example.com. \n- The group example@googlegroups.com would be group-example@googlegroups.com. \n- To refer to all members of the Google Apps for Business domain example.com, the entity would be domain-example.com.", - "annotations": { - "required": [ - "storage.bucketAccessControls.insert" - ] + }, + "website": { + "type": "object", + "description": "The bucket's website configuration, controlling how the service behaves when accessing bucket contents as a web site. See the Static Website Examples for more information.", + "properties": { + "mainPageSuffix": { + "type": "string", + "description": "If the requested object path is missing, the service will ensure the path has a trailing '/', append this suffix, and attempt to retrieve the resulting object. This allows the creation of index.html objects to represent directory pages." + }, + "notFoundPage": { + "type": "string", + "description": "If the requested object path is missing, and any mainPageSuffix object is missing, if applicable, the service will return the named object from this bucket as the content for a 404 Not Found result." } - }, - "entityId": { - "type": "string", - "description": "The ID for the entity, if any." - }, - "etag": { - "type": "string", - "description": "HTTP 1.1 Entity tag for the access-control entry." - }, - "id": { - "type": "string", - "description": "The ID of the access-control entry." - }, - "kind": { - "type": "string", - "description": "The kind of item this is. For bucket access control entries, this is always storage#bucketAccessControl.", - "default": "storage#bucketAccessControl" - }, - "projectTeam": { - "type": "object", - "description": "The project team associated with the entity, if any.", - "properties": { - "projectNumber": { - "type": "string", - "description": "The project number." - }, - "team": { - "type": "string", - "description": "The team." - } - } - }, - "role": { - "type": "string", - "description": "The access permission for the entity.", - "annotations": { - "required": [ - "storage.bucketAccessControls.insert" - ] - } - }, - "selfLink": { - "type": "string", - "description": "The link to this access-control entry." } + }, + "satisfiesPZS": { + "type": "boolean", + "description": "Reserved for future use." } - }, - "BucketAccessControls": { - "id": "BucketAccessControls", - "type": "object", - "description": "An access-control list.", - "properties": { + } + }, + "AnywhereCache": { + "id": "AnywhereCache", + "type": "object", + "description": "An Anywhere Cache instance.", + "properties": { + "kind": { + "type": "string", + "description": "The kind of item this is. For Anywhere Cache, this is always storage#anywhereCache.", + "default": "storage#anywhereCache" + }, + "id": { + "type": "string", + "description": "The ID of the resource, including the project number, bucket name and anywhere cache ID." + }, + "selfLink": { + "type": "string", + "description": "The link to this cache instance." + }, + "bucket": { + "type": "string", + "description": "The name of the bucket containing this cache instance." + }, + "anywhereCacheId": { + "type": "string", + "description": "The ID of the Anywhere cache instance." + }, + "state": { + "type": "string", + "description": "The current state of the cache instance." + }, + "createTime": { + "type": "string", + "description": "The creation time of the cache instance in RFC 3339 format.", + "format": "date-time" + }, + "updateTime": { + "type": "string", + "description": "The modification time of the cache instance metadata in RFC 3339 format.", + "format": "date-time" + }, + "ttl": { + "type": "string", + "description": "The TTL of all cache entries in whole seconds. e.g., \"7200s\". ", + "format": "google-duration" + }, + "admissionPolicy": { + "type": "string", + "description": "The cache-level entry admission policy." + }, + "pendingUpdate": { + "type": "boolean", + "description": "True if the cache instance has an active Update long-running operation." + } + } + }, + "AnywhereCaches": { + "id": "AnywhereCaches", + "type": "object", + "description": "A list of Anywhere Caches.", + "properties": { + "kind": { + "type": "string", + "description": "The kind of item this is. For lists of Anywhere Caches, this is always storage#anywhereCaches.", + "default": "storage#anywhereCaches" + }, + "nextPageToken": { + "type": "string", + "description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results." + }, + "items": { + "type": "array", + "description": "The list of items.", "items": { - "type": "array", - "description": "The list of items.", - "items": { - "$ref": "BucketAccessControl" + "$ref": "AnywhereCache" + } + } + } + }, + "BucketAccessControl": { + "id": "BucketAccessControl", + "type": "object", + "description": "An access-control entry.", + "properties": { + "bucket": { + "type": "string", + "description": "The name of the bucket." + }, + "domain": { + "type": "string", + "description": "The domain associated with the entity, if any." + }, + "email": { + "type": "string", + "description": "The email address associated with the entity, if any." + }, + "entity": { + "type": "string", + "description": "The entity holding the permission, in one of the following forms: \n- user-userId \n- user-email \n- group-groupId \n- group-email \n- domain-domain \n- project-team-projectId \n- allUsers \n- allAuthenticatedUsers Examples: \n- The user liz@example.com would be user-liz@example.com. \n- The group example@googlegroups.com would be group-example@googlegroups.com. \n- To refer to all members of the Google Apps for Business domain example.com, the entity would be domain-example.com.", + "annotations": { + "required": [ + "storage.bucketAccessControls.insert" + ] + } + }, + "entityId": { + "type": "string", + "description": "The ID for the entity, if any." + }, + "etag": { + "type": "string", + "description": "HTTP 1.1 Entity tag for the access-control entry." + }, + "id": { + "type": "string", + "description": "The ID of the access-control entry." + }, + "kind": { + "type": "string", + "description": "The kind of item this is. For bucket access control entries, this is always storage#bucketAccessControl.", + "default": "storage#bucketAccessControl" + }, + "projectTeam": { + "type": "object", + "description": "The project team associated with the entity, if any.", + "properties": { + "projectNumber": { + "type": "string", + "description": "The project number." + }, + "team": { + "type": "string", + "description": "The team." } - }, - "kind": { - "type": "string", - "description": "The kind of item this is. For lists of bucket access control entries, this is always storage#bucketAccessControls.", - "default": "storage#bucketAccessControls" } + }, + "role": { + "type": "string", + "description": "The access permission for the entity.", + "annotations": { + "required": [ + "storage.bucketAccessControls.insert" + ] + } + }, + "selfLink": { + "type": "string", + "description": "The link to this access-control entry." } - }, - "Buckets": { - "id": "Buckets", - "type": "object", - "description": "A list of buckets.", - "properties": { + } + }, + "BucketAccessControls": { + "id": "BucketAccessControls", + "type": "object", + "description": "An access-control list.", + "properties": { + "items": { + "type": "array", + "description": "The list of items.", "items": { - "type": "array", - "description": "The list of items.", - "items": { - "$ref": "Bucket" - } - }, - "kind": { - "type": "string", - "description": "The kind of item this is. For lists of buckets, this is always storage#buckets.", - "default": "storage#buckets" - }, - "nextPageToken": { - "type": "string", - "description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results." + "$ref": "BucketAccessControl" } + }, + "kind": { + "type": "string", + "description": "The kind of item this is. For lists of bucket access control entries, this is always storage#bucketAccessControls.", + "default": "storage#bucketAccessControls" } - }, - "Channel": { - "id": "Channel", - "type": "object", - "description": "An notification channel used to watch for resource changes.", - "properties": { - "address": { - "type": "string", - "description": "The address where notifications are delivered for this channel." - }, - "expiration": { - "type": "string", - "description": "Date and time of notification channel expiration, expressed as a Unix timestamp, in milliseconds. Optional.", - "format": "int64" - }, - "id": { - "type": "string", - "description": "A UUID or similar unique string that identifies this channel." - }, - "kind": { - "type": "string", - "description": "Identifies this as a notification channel used to watch for changes to a resource, which is \"api#channel\".", - "default": "api#channel" - }, - "params": { - "type": "object", - "description": "Additional parameters controlling delivery channel behavior. Optional.", - "additionalProperties": { - "type": "string", - "description": "Declares a new parameter by name." - } - }, - "payload": { - "type": "boolean", - "description": "A Boolean value to indicate whether payload is wanted. Optional." - }, - "resourceId": { - "type": "string", - "description": "An opaque ID that identifies the resource being watched on this channel. Stable across different API versions." - }, - "resourceUri": { - "type": "string", - "description": "A version-specific identifier for the watched resource." - }, - "token": { - "type": "string", - "description": "An arbitrary string delivered to the target address with each notification delivered over this channel. Optional." - }, - "type": { - "type": "string", - "description": "The type of delivery mechanism used for this channel." + } + }, + "Buckets": { + "id": "Buckets", + "type": "object", + "description": "A list of buckets.", + "properties": { + "items": { + "type": "array", + "description": "The list of items.", + "items": { + "$ref": "Bucket" } + }, + "kind": { + "type": "string", + "description": "The kind of item this is. For lists of buckets, this is always storage#buckets.", + "default": "storage#buckets" + }, + "nextPageToken": { + "type": "string", + "description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results." } - }, - "ComposeRequest": { - "id": "ComposeRequest", - "type": "object", - "description": "A Compose request.", - "properties": { - "destination": { - "$ref": "Object", - "description": "Properties of the resulting object." - }, - "kind": { + } + }, + "Channel": { + "id": "Channel", + "type": "object", + "description": "An notification channel used to watch for resource changes.", + "properties": { + "address": { + "type": "string", + "description": "The address where notifications are delivered for this channel." + }, + "expiration": { + "type": "string", + "description": "Date and time of notification channel expiration, expressed as a Unix timestamp, in milliseconds. Optional.", + "format": "int64" + }, + "id": { + "type": "string", + "description": "A UUID or similar unique string that identifies this channel." + }, + "kind": { + "type": "string", + "description": "Identifies this as a notification channel used to watch for changes to a resource, which is \"api#channel\".", + "default": "api#channel" + }, + "params": { + "type": "object", + "description": "Additional parameters controlling delivery channel behavior. Optional.", + "additionalProperties": { "type": "string", - "description": "The kind of item this is.", - "default": "storage#composeRequest" - }, - "sourceObjects": { - "type": "array", - "description": "The list of source objects that will be concatenated into a single object.", - "items": { - "type": "object", - "properties": { - "generation": { - "type": "string", - "description": "The generation of this object to use as the source.", - "format": "int64" - }, - "name": { - "type": "string", - "description": "The source object's name. All source objects must reside in the same bucket.", - "annotations": { - "required": [ - "storage.objects.compose" - ] - } - }, - "objectPreconditions": { - "type": "object", - "description": "Conditions that must be met for this operation to execute.", - "properties": { - "ifGenerationMatch": { - "type": "string", - "description": "Only perform the composition if the generation of the source object that would be used matches this value. If this value and a generation are both specified, they must be the same value or the call will fail.", - "format": "int64" - } + "description": "Declares a new parameter by name." + } + }, + "payload": { + "type": "boolean", + "description": "A Boolean value to indicate whether payload is wanted. Optional." + }, + "resourceId": { + "type": "string", + "description": "An opaque ID that identifies the resource being watched on this channel. Stable across different API versions." + }, + "resourceUri": { + "type": "string", + "description": "A version-specific identifier for the watched resource." + }, + "token": { + "type": "string", + "description": "An arbitrary string delivered to the target address with each notification delivered over this channel. Optional." + }, + "type": { + "type": "string", + "description": "The type of delivery mechanism used for this channel." + } + } + }, + "ComposeRequest": { + "id": "ComposeRequest", + "type": "object", + "description": "A Compose request.", + "properties": { + "destination": { + "$ref": "Object", + "description": "Properties of the resulting object." + }, + "kind": { + "type": "string", + "description": "The kind of item this is.", + "default": "storage#composeRequest" + }, + "sourceObjects": { + "type": "array", + "description": "The list of source objects that will be concatenated into a single object.", + "items": { + "type": "object", + "properties": { + "generation": { + "type": "string", + "description": "The generation of this object to use as the source.", + "format": "int64" + }, + "name": { + "type": "string", + "description": "The source object's name. All source objects must reside in the same bucket.", + "annotations": { + "required": [ + "storage.objects.compose" + ] + } + }, + "objectPreconditions": { + "type": "object", + "description": "Conditions that must be met for this operation to execute.", + "properties": { + "ifGenerationMatch": { + "type": "string", + "description": "Only perform the composition if the generation of the source object that would be used matches this value. If this value and a generation are both specified, they must be the same value or the call will fail.", + "format": "int64" } } } - }, - "annotations": { - "required": [ - "storage.objects.compose" - ] } - } - } - }, - "Expr": { - "id": "Expr", - "type": "object", - "description": "Represents an expression text. Example: title: \"User account presence\" description: \"Determines whether the request has a user account\" expression: \"size(request.user) > 0\"", - "properties": { - "description": { - "type": "string", - "description": "An optional description of the expression. This is a longer text which describes the expression, e.g. when hovered over it in a UI." - }, - "expression": { - "type": "string", - "description": "Textual representation of an expression in Common Expression Language syntax. The application context of the containing message determines which well-known feature set of CEL is supported." - }, - "location": { - "type": "string", - "description": "An optional string indicating the location of the expression for error reporting, e.g. a file name and a position in the file." }, - "title": { - "type": "string", - "description": "An optional title for the expression, i.e. a short string describing its purpose. This can be used e.g. in UIs which allow to enter the expression." + "annotations": { + "required": [ + "storage.objects.compose" + ] } } - }, - "HmacKey": { - "id": "HmacKey", - "type": "object", - "description": "JSON template to produce a JSON-style HMAC Key resource for Create responses.", - "properties": { - "kind": { - "type": "string", - "description": "The kind of item this is. For HMAC keys, this is always storage#hmacKey.", - "default": "storage#hmacKey" - }, - "metadata": { - "$ref": "HmacKeyMetadata", - "description": "Key metadata." - }, - "secret": { - "type": "string", - "description": "HMAC secret key material." - } + } + }, + "Expr": { + "id": "Expr", + "type": "object", + "description": "Represents an expression text. Example: title: \"User account presence\" description: \"Determines whether the request has a user account\" expression: \"size(request.user) > 0\"", + "properties": { + "description": { + "type": "string", + "description": "An optional description of the expression. This is a longer text which describes the expression, e.g. when hovered over it in a UI." + }, + "expression": { + "type": "string", + "description": "Textual representation of an expression in Common Expression Language syntax. The application context of the containing message determines which well-known feature set of CEL is supported." + }, + "location": { + "type": "string", + "description": "An optional string indicating the location of the expression for error reporting, e.g. a file name and a position in the file." + }, + "title": { + "type": "string", + "description": "An optional title for the expression, i.e. a short string describing its purpose. This can be used e.g. in UIs which allow to enter the expression." } - }, - "HmacKeyMetadata": { - "id": "HmacKeyMetadata", - "type": "object", - "description": "JSON template to produce a JSON-style HMAC Key metadata resource.", - "properties": { - "accessId": { - "type": "string", - "description": "The ID of the HMAC Key." - }, - "etag": { - "type": "string", - "description": "HTTP 1.1 Entity tag for the HMAC key." - }, - "id": { - "type": "string", - "description": "The ID of the HMAC key, including the Project ID and the Access ID." - }, - "kind": { - "type": "string", - "description": "The kind of item this is. For HMAC Key metadata, this is always storage#hmacKeyMetadata.", - "default": "storage#hmacKeyMetadata" - }, - "projectId": { - "type": "string", - "description": "Project ID owning the service account to which the key authenticates." - }, - "selfLink": { - "type": "string", - "description": "The link to this resource." - }, - "serviceAccountEmail": { - "type": "string", - "description": "The email address of the key's associated service account." - }, - "state": { - "type": "string", - "description": "The state of the key. Can be one of ACTIVE, INACTIVE, or DELETED." + } + }, + "GoogleLongrunningOperation": { + "description": "This resource represents a long-running operation that is the result of a network API call.", + "id": "GoogleLongrunningOperation", + "properties": { + "done": { + "description": "If the value is \"false\", it means the operation is still in progress. If \"true\", the operation is completed, and either \"error\" or \"response\" is available.", + "type": "boolean" + }, + "error": { + "$ref": "GoogleRpcStatus", + "description": "The error result of the operation in case of failure or cancellation." + }, + "metadata": { + "additionalProperties": { + "description": "Properties of the object. Contains field @type with type URL.", + "type": "any" }, - "timeCreated": { - "type": "string", - "description": "The creation time of the HMAC key in RFC 3339 format.", - "format": "date-time" + "description": "Service-specific metadata associated with the operation. It typically contains progress information and common metadata such as create time. Some services might not provide such metadata. Any method that returns a long-running operation should document the metadata type, if any.", + "type": "object" + }, + "name": { + "description": "The server-assigned name, which is only unique within the same service that originally returns it. If you use the default HTTP mapping, the \"name\" should be a resource name ending with \"operations/{operationId}\".", + "type": "string" + }, + "response": { + "additionalProperties": { + "description": "Properties of the object. Contains field @type with type URL.", + "type": "any" }, - "updated": { - "type": "string", - "description": "The last modification time of the HMAC key metadata in RFC 3339 format.", - "format": "date-time" - } + "description": "The normal response of the operation in case of success. If the original method returns no data on success, such as \"Delete\", the response is google.protobuf.Empty. If the original method is standard Get/Create/Update, the response should be the resource. For other methods, the response should have the type \"XxxResponse\", where \"Xxx\" is the original method name. For example, if the original method name is \"TakeSnapshot()\", the inferred response type is \"TakeSnapshotResponse\".", + "type": "object" } }, - "HmacKeysMetadata": { - "id": "HmacKeysMetadata", - "type": "object", - "description": "A list of hmacKeys.", - "properties": { + "type": "object" + }, + "GoogleLongrunningListOperationsResponse": { + "description": "The response message for storage.buckets.operations.list.", + "id": "GoogleLongrunningListOperationsResponse", + "properties": { + "nextPageToken": { + "type": "string", + "description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results." + }, + "operations": { + "description": "A list of operations that matches the specified filter in the request.", "items": { - "type": "array", - "description": "The list of items.", - "items": { - "$ref": "HmacKeyMetadata" - } - }, - "kind": { - "type": "string", - "description": "The kind of item this is. For lists of hmacKeys, this is always storage#hmacKeysMetadata.", - "default": "storage#hmacKeysMetadata" + "$ref": "GoogleLongrunningOperation" }, - "nextPageToken": { - "type": "string", - "description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results." - } + "type": "array" } }, - "Notification": { - "id": "Notification", - "type": "object", - "description": "A subscription to receive Google PubSub notifications.", - "properties": { - "custom_attributes": { - "type": "object", - "description": "An optional list of additional attributes to attach to each Cloud PubSub message published for this notification subscription.", + "type": "object" + }, + "GoogleRpcStatus": { + "description": "The \"Status\" type defines a logical error model that is suitable for different programming environments, including REST APIs and RPC APIs. It is used by [gRPC](https://github.com/grpc). Each \"Status\" message contains three pieces of data: error code, error message, and error details. You can find out more about this error model and how to work with it in the [API Design Guide](https://cloud.google.com/apis/design/errors).", + "id": "GoogleRpcStatus", + "properties": { + "code": { + "description": "The status code, which should be an enum value of google.rpc.Code.", + "format": "int32", + "type": "integer" + }, + "details": { + "description": "A list of messages that carry the error details. There is a common set of message types for APIs to use.", + "items": { "additionalProperties": { - "type": "string" - } - }, - "etag": { - "type": "string", - "description": "HTTP 1.1 Entity tag for this subscription notification." - }, - "event_types": { - "type": "array", - "description": "If present, only send notifications about listed event types. If empty, sent notifications for all event types.", - "items": { - "type": "string" - } - }, - "id": { - "type": "string", - "description": "The ID of the notification." - }, - "kind": { - "type": "string", - "description": "The kind of item this is. For notifications, this is always storage#notification.", - "default": "storage#notification" - }, - "object_name_prefix": { - "type": "string", - "description": "If present, only apply this notification configuration to object names that begin with this prefix." - }, - "payload_format": { - "type": "string", - "description": "The desired content of the Payload.", - "default": "JSON_API_V1", - "annotations": { - "required": [ - "storage.notifications.insert" - ] - } - }, - "selfLink": { - "type": "string", - "description": "The canonical URL of this notification." + "description": "Properties of the object. Contains field @type with type URL.", + "type": "any" + }, + "type": "object" }, - "topic": { - "type": "string", - "description": "The Cloud PubSub topic to which this subscription publishes. Formatted as: '//pubsub.googleapis.com/projects/{project-identifier}/topics/{my-topic}'", - "annotations": { - "required": [ - "storage.notifications.insert" - ] - } - } + "type": "array" + }, + "message": { + "description": "A developer-facing error message, which should be in English.", + "type": "string" } }, - "Notifications": { - "id": "Notifications", - "type": "object", - "description": "A list of notification subscriptions.", - "properties": { + "type": "object" + }, + "HmacKey": { + "id": "HmacKey", + "type": "object", + "description": "JSON template to produce a JSON-style HMAC Key resource for Create responses.", + "properties": { + "kind": { + "type": "string", + "description": "The kind of item this is. For HMAC keys, this is always storage#hmacKey.", + "default": "storage#hmacKey" + }, + "metadata": { + "$ref": "HmacKeyMetadata", + "description": "Key metadata." + }, + "secret": { + "type": "string", + "description": "HMAC secret key material." + } + } + }, + "HmacKeyMetadata": { + "id": "HmacKeyMetadata", + "type": "object", + "description": "JSON template to produce a JSON-style HMAC Key metadata resource.", + "properties": { + "accessId": { + "type": "string", + "description": "The ID of the HMAC Key." + }, + "etag": { + "type": "string", + "description": "HTTP 1.1 Entity tag for the HMAC key." + }, + "id": { + "type": "string", + "description": "The ID of the HMAC key, including the Project ID and the Access ID." + }, + "kind": { + "type": "string", + "description": "The kind of item this is. For HMAC Key metadata, this is always storage#hmacKeyMetadata.", + "default": "storage#hmacKeyMetadata" + }, + "projectId": { + "type": "string", + "description": "Project ID owning the service account to which the key authenticates." + }, + "selfLink": { + "type": "string", + "description": "The link to this resource." + }, + "serviceAccountEmail": { + "type": "string", + "description": "The email address of the key's associated service account." + }, + "state": { + "type": "string", + "description": "The state of the key. Can be one of ACTIVE, INACTIVE, or DELETED." + }, + "timeCreated": { + "type": "string", + "description": "The creation time of the HMAC key in RFC 3339 format.", + "format": "date-time" + }, + "updated": { + "type": "string", + "description": "The last modification time of the HMAC key metadata in RFC 3339 format.", + "format": "date-time" + } + } + }, + "HmacKeysMetadata": { + "id": "HmacKeysMetadata", + "type": "object", + "description": "A list of hmacKeys.", + "properties": { + "items": { + "type": "array", + "description": "The list of items.", "items": { - "type": "array", - "description": "The list of items.", - "items": { - "$ref": "Notification" - } - }, - "kind": { - "type": "string", - "description": "The kind of item this is. For lists of notifications, this is always storage#notifications.", - "default": "storage#notifications" + "$ref": "HmacKeyMetadata" } + }, + "kind": { + "type": "string", + "description": "The kind of item this is. For lists of hmacKeys, this is always storage#hmacKeysMetadata.", + "default": "storage#hmacKeysMetadata" + }, + "nextPageToken": { + "type": "string", + "description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results." } - }, - "Object": { - "id": "Object", - "type": "object", - "description": "An object.", - "properties": { - "acl": { - "type": "array", - "description": "Access controls on the object.", - "items": { - "$ref": "ObjectAccessControl" - }, - "annotations": { - "required": [ - "storage.objects.update" - ] - } - }, - "bucket": { - "type": "string", - "description": "The name of the bucket containing this object." - }, - "cacheControl": { - "type": "string", - "description": "Cache-Control directive for the object data. If omitted, and the object is accessible to all anonymous users, the default will be public, max-age=3600." - }, - "componentCount": { - "type": "integer", - "description": "Number of underlying components that make up this object. Components are accumulated by compose operations.", - "format": "int32" + } + }, + "ManagedFolder": { + "id": "ManagedFolder", + "type": "object", + "description": "A managed folder.", + "properties": { + "bucket": { + "type": "string", + "description": "The name of the bucket containing this managed folder." + }, + "id": { + "type": "string", + "description": "The ID of the managed folder, including the bucket name and managed folder name." + }, + "kind": { + "type": "string", + "description": "The kind of item this is. For managed folders, this is always storage#managedFolder.", + "default": "storage#managedFolder" + }, + "metageneration": { + "type": "string", + "description": "The version of the metadata for this managed folder. Used for preconditions and for detecting changes in metadata.", + "format": "int64" + }, + "name": { + "type": "string", + "description": "The name of the managed folder. Required if not specified by URL parameter." + }, + "selfLink": { + "type": "string", + "description": "The link to this managed folder." + }, + "createTime": { + "type": "string", + "description": "The creation time of the managed folder in RFC 3339 format.", + "format": "date-time" + }, + "updateTime": { + "type": "string", + "description": "The last update time of the managed folder metadata in RFC 3339 format.", + "format": "date-time" + } + } + }, + "ManagedFolders": { + "id": "ManagedFolders", + "type": "object", + "description": "A list of managed folders.", + "properties": { + "items": { + "type": "array", + "description": "The list of items.", + "items": { + "$ref": "ManagedFolder" + } + }, + "kind": { + "type": "string", + "description": "The kind of item this is. For lists of managed folders, this is always storage#managedFolders.", + "default": "storage#managedFolders" + }, + "nextPageToken": { + "type": "string", + "description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results." + } + } + }, + "Notification": { + "id": "Notification", + "type": "object", + "description": "A subscription to receive Google PubSub notifications.", + "properties": { + "custom_attributes": { + "type": "object", + "description": "An optional list of additional attributes to attach to each Cloud PubSub message published for this notification subscription.", + "additionalProperties": { + "type": "string" + } + }, + "etag": { + "type": "string", + "description": "HTTP 1.1 Entity tag for this subscription notification." + }, + "event_types": { + "type": "array", + "description": "If present, only send notifications about listed event types. If empty, sent notifications for all event types.", + "items": { + "type": "string" + } + }, + "id": { + "type": "string", + "description": "The ID of the notification." + }, + "kind": { + "type": "string", + "description": "The kind of item this is. For notifications, this is always storage#notification.", + "default": "storage#notification" + }, + "object_name_prefix": { + "type": "string", + "description": "If present, only apply this notification configuration to object names that begin with this prefix." + }, + "payload_format": { + "type": "string", + "description": "The desired content of the Payload.", + "default": "JSON_API_V1", + "annotations": { + "required": [ + "storage.notifications.insert" + ] + } + }, + "selfLink": { + "type": "string", + "description": "The canonical URL of this notification." + }, + "topic": { + "type": "string", + "description": "The Cloud PubSub topic to which this subscription publishes. Formatted as: '//pubsub.googleapis.com/projects/{project-identifier}/topics/{my-topic}'", + "annotations": { + "required": [ + "storage.notifications.insert" + ] + } + } + } + }, + "Notifications": { + "id": "Notifications", + "type": "object", + "description": "A list of notification subscriptions.", + "properties": { + "items": { + "type": "array", + "description": "The list of items.", + "items": { + "$ref": "Notification" + } + }, + "kind": { + "type": "string", + "description": "The kind of item this is. For lists of notifications, this is always storage#notifications.", + "default": "storage#notifications" + } + } + }, + "Object": { + "id": "Object", + "type": "object", + "description": "An object.", + "properties": { + "acl": { + "type": "array", + "description": "Access controls on the object.", + "items": { + "$ref": "ObjectAccessControl" }, - "contentDisposition": { + "annotations": { + "required": [ + "storage.objects.update" + ] + } + }, + "bucket": { + "type": "string", + "description": "The name of the bucket containing this object." + }, + "cacheControl": { + "type": "string", + "description": "Cache-Control directive for the object data. If omitted, and the object is accessible to all anonymous users, the default will be public, max-age=3600." + }, + "componentCount": { + "type": "integer", + "description": "Number of underlying components that make up this object. Components are accumulated by compose operations.", + "format": "int32" + }, + "contentDisposition": { + "type": "string", + "description": "Content-Disposition of the object data." + }, + "contentEncoding": { + "type": "string", + "description": "Content-Encoding of the object data." + }, + "contentLanguage": { + "type": "string", + "description": "Content-Language of the object data." + }, + "contentType": { + "type": "string", + "description": "Content-Type of the object data. If an object is stored without a Content-Type, it is served as application/octet-stream." + }, + "crc32c": { + "type": "string", + "description": "CRC32c checksum, as described in RFC 4960, Appendix B; encoded using base64 in big-endian byte order. For more information about using the CRC32c checksum, see Hashes and ETags: Best Practices." + }, + "customTime": { + "type": "string", + "description": "A timestamp in RFC 3339 format specified by the user for an object.", + "format": "date-time" + }, + "customerEncryption": { + "type": "object", + "description": "Metadata of customer-supplied encryption key, if the object is encrypted by such a key.", + "properties": { + "encryptionAlgorithm": { + "type": "string", + "description": "The encryption algorithm." + }, + "keySha256": { + "type": "string", + "description": "SHA256 hash value of the encryption key." + } + } + }, + "etag": { + "type": "string", + "description": "HTTP 1.1 Entity tag for the object." + }, + "eventBasedHold": { + "type": "boolean", + "description": "Whether an object is under event-based hold. Event-based hold is a way to retain objects until an event occurs, which is signified by the hold's release (i.e. this value is set to false). After being released (set to false), such objects will be subject to bucket-level retention (if any). One sample use case of this flag is for banks to hold loan documents for at least 3 years after loan is paid in full. Here, bucket-level retention is 3 years and the event is the loan being paid in full. In this example, these objects will be held intact for any number of years until the event has occurred (event-based hold on the object is released) and then 3 more years after that. That means retention duration of the objects begins from the moment event-based hold transitioned from true to false." + }, + "generation": { + "type": "string", + "description": "The content generation of this object. Used for object versioning.", + "format": "int64" + }, + "id": { + "type": "string", + "description": "The ID of the object, including the bucket name, object name, and generation number." + }, + "kind": { + "type": "string", + "description": "The kind of item this is. For objects, this is always storage#object.", + "default": "storage#object" + }, + "kmsKeyName": { + "type": "string", + "description": "Not currently supported. Specifying the parameter causes the request to fail with status code 400 - Bad Request." + }, + "md5Hash": { + "type": "string", + "description": "MD5 hash of the data; encoded using base64. For more information about using the MD5 hash, see Hashes and ETags: Best Practices." + }, + "mediaLink": { + "type": "string", + "description": "Media download link." + }, + "metadata": { + "type": "object", + "description": "User-provided metadata, in key/value pairs.", + "additionalProperties": { "type": "string", - "description": "Content-Disposition of the object data." + "description": "An individual metadata entry." + } + }, + "metageneration": { + "type": "string", + "description": "The version of the metadata for this object at this generation. Used for preconditions and for detecting changes in metadata. A metageneration number is only meaningful in the context of a particular generation of a particular object.", + "format": "int64" + }, + "name": { + "type": "string", + "description": "The name of the object. Required if not specified by URL parameter." + }, + "owner": { + "type": "object", + "description": "The owner of the object. This will always be the uploader of the object.", + "properties": { + "entity": { + "type": "string", + "description": "The entity, in the form user-userId." + }, + "entityId": { + "type": "string", + "description": "The ID for the entity." + } + } + }, + "retentionExpirationTime": { + "type": "string", + "description": "A server-determined value that specifies the earliest time that the object's retention period expires. This value is in RFC 3339 format. Note 1: This field is not provided for objects with an active event-based hold, since retention expiration is unknown until the hold is removed. Note 2: This value can be provided even when temporary hold is set (so that the user can reason about policy without having to first unset the temporary hold).", + "format": "date-time" + }, + "retention": { + "type": "object", + "description": "A collection of object level retention parameters.", + "properties": { + "retainUntilTime": { + "type": "string", + "description": "A time in RFC 3339 format until which object retention protects this object.", + "format": "date-time" + }, + "mode": { + "type": "string", + "description": "The bucket's object retention mode, can only be Unlocked or Locked." + } + } + }, + "selfLink": { + "type": "string", + "description": "The link to this object." + }, + "size": { + "type": "string", + "description": "Content-Length of the data in bytes.", + "format": "uint64" + }, + "storageClass": { + "type": "string", + "description": "Storage class of the object." + }, + "temporaryHold": { + "type": "boolean", + "description": "Whether an object is under temporary hold. While this flag is set to true, the object is protected against deletion and overwrites. A common use case of this flag is regulatory investigations where objects need to be retained while the investigation is ongoing. Note that unlike event-based hold, temporary hold does not impact retention expiration time of an object." + }, + "timeCreated": { + "type": "string", + "description": "The creation time of the object in RFC 3339 format.", + "format": "date-time" + }, + "timeDeleted": { + "type": "string", + "description": "The time at which the object became noncurrent in RFC 3339 format. Will be returned if and only if this version of the object has been deleted.", + "format": "date-time" + }, + "softDeleteTime": { + "type": "string", + "description": "The time at which the object became soft-deleted in RFC 3339 format.", + "format": "date-time" + }, + "hardDeleteTime": { + "type": "string", + "description": "This is the time (in the future) when the soft-deleted object will no longer be restorable. It is equal to the soft delete time plus the current soft delete retention duration of the bucket.", + "format": "date-time" + }, + "timeStorageClassUpdated": { + "type": "string", + "description": "The time at which the object's storage class was last changed. When the object is initially created, it will be set to timeCreated.", + "format": "date-time" + }, + "updated": { + "type": "string", + "description": "The modification time of the object metadata in RFC 3339 format. Set initially to object creation time and then updated whenever any metadata of the object changes. This includes changes made by a requester, such as modifying custom metadata, as well as changes made by Cloud Storage on behalf of a requester, such as changing the storage class based on an Object Lifecycle Configuration.", + "format": "date-time" + } + } + }, + "ObjectAccessControl": { + "id": "ObjectAccessControl", + "type": "object", + "description": "An access-control entry.", + "properties": { + "bucket": { + "type": "string", + "description": "The name of the bucket." + }, + "domain": { + "type": "string", + "description": "The domain associated with the entity, if any." + }, + "email": { + "type": "string", + "description": "The email address associated with the entity, if any." + }, + "entity": { + "type": "string", + "description": "The entity holding the permission, in one of the following forms: \n- user-userId \n- user-email \n- group-groupId \n- group-email \n- domain-domain \n- project-team-projectId \n- allUsers \n- allAuthenticatedUsers Examples: \n- The user liz@example.com would be user-liz@example.com. \n- The group example@googlegroups.com would be group-example@googlegroups.com. \n- To refer to all members of the Google Apps for Business domain example.com, the entity would be domain-example.com.", + "annotations": { + "required": [ + "storage.defaultObjectAccessControls.insert", + "storage.objectAccessControls.insert" + ] + } + }, + "entityId": { + "type": "string", + "description": "The ID for the entity, if any." + }, + "etag": { + "type": "string", + "description": "HTTP 1.1 Entity tag for the access-control entry." + }, + "generation": { + "type": "string", + "description": "The content generation of the object, if applied to an object.", + "format": "int64" + }, + "id": { + "type": "string", + "description": "The ID of the access-control entry." + }, + "kind": { + "type": "string", + "description": "The kind of item this is. For object access control entries, this is always storage#objectAccessControl.", + "default": "storage#objectAccessControl" + }, + "object": { + "type": "string", + "description": "The name of the object, if applied to an object." + }, + "projectTeam": { + "type": "object", + "description": "The project team associated with the entity, if any.", + "properties": { + "projectNumber": { + "type": "string", + "description": "The project number." + }, + "team": { + "type": "string", + "description": "The team." + } + } + }, + "role": { + "type": "string", + "description": "The access permission for the entity.", + "annotations": { + "required": [ + "storage.defaultObjectAccessControls.insert", + "storage.objectAccessControls.insert" + ] + } + }, + "selfLink": { + "type": "string", + "description": "The link to this access-control entry." + } + } + }, + "ObjectAccessControls": { + "id": "ObjectAccessControls", + "type": "object", + "description": "An access-control list.", + "properties": { + "items": { + "type": "array", + "description": "The list of items.", + "items": { + "$ref": "ObjectAccessControl" + } + }, + "kind": { + "type": "string", + "description": "The kind of item this is. For lists of object access control entries, this is always storage#objectAccessControls.", + "default": "storage#objectAccessControls" + } + } + }, + "Objects": { + "id": "Objects", + "type": "object", + "description": "A list of objects.", + "properties": { + "items": { + "type": "array", + "description": "The list of items.", + "items": { + "$ref": "Object" + } + }, + "kind": { + "type": "string", + "description": "The kind of item this is. For lists of objects, this is always storage#objects.", + "default": "storage#objects" + }, + "nextPageToken": { + "type": "string", + "description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results." + }, + "prefixes": { + "type": "array", + "description": "The list of prefixes of objects matching-but-not-listed up to and including the requested delimiter.", + "items": { + "type": "string" + } + } + } + }, + "Policy": { + "id": "Policy", + "type": "object", + "description": "A bucket/object/managedFolder IAM policy.", + "properties": { + "bindings": { + "type": "array", + "description": "An association between a role, which comes with a set of permissions, and members who may assume that role.", + "items": { + "type": "object", + "properties": { + "condition": { + "$ref": "Expr", + "description": "The condition that is associated with this binding. NOTE: an unsatisfied condition will not allow user access via current binding. Different bindings, including their conditions, are examined independently." + }, + "members": { + "type": "array", + "description": "A collection of identifiers for members who may assume the provided role. Recognized identifiers are as follows: \n- allUsers \u2014 A special identifier that represents anyone on the internet; with or without a Google account. \n- allAuthenticatedUsers \u2014 A special identifier that represents anyone who is authenticated with a Google account or a service account. \n- user:emailid \u2014 An email address that represents a specific account. For example, user:alice@gmail.com or user:joe@example.com. \n- serviceAccount:emailid \u2014 An email address that represents a service account. For example, serviceAccount:my-other-app@appspot.gserviceaccount.com . \n- group:emailid \u2014 An email address that represents a Google group. For example, group:admins@example.com. \n- domain:domain \u2014 A Google Apps domain name that represents all the users of that domain. For example, domain:google.com or domain:example.com. \n- projectOwner:projectid \u2014 Owners of the given project. For example, projectOwner:my-example-project \n- projectEditor:projectid \u2014 Editors of the given project. For example, projectEditor:my-example-project \n- projectViewer:projectid \u2014 Viewers of the given project. For example, projectViewer:my-example-project", + "items": { + "type": "string" + }, + "annotations": { + "required": [ + "storage.buckets.setIamPolicy", + "storage.objects.setIamPolicy", + "storage.managedFolders.setIamPolicy" + ] + } + }, + "role": { + "type": "string", + "description": "The role to which members belong. Two types of roles are supported: new IAM roles, which grant permissions that do not map directly to those provided by ACLs, and legacy IAM roles, which do map directly to ACL permissions. All roles are of the format roles/storage.specificRole.\nThe new IAM roles are: \n- roles/storage.admin \u2014 Full control of Google Cloud Storage resources. \n- roles/storage.objectViewer \u2014 Read-Only access to Google Cloud Storage objects. \n- roles/storage.objectCreator \u2014 Access to create objects in Google Cloud Storage. \n- roles/storage.objectAdmin \u2014 Full control of Google Cloud Storage objects. The legacy IAM roles are: \n- roles/storage.legacyObjectReader \u2014 Read-only access to objects without listing. Equivalent to an ACL entry on an object with the READER role. \n- roles/storage.legacyObjectOwner \u2014 Read/write access to existing objects without listing. Equivalent to an ACL entry on an object with the OWNER role. \n- roles/storage.legacyBucketReader \u2014 Read access to buckets with object listing. Equivalent to an ACL entry on a bucket with the READER role. \n- roles/storage.legacyBucketWriter \u2014 Read access to buckets with object listing/creation/deletion. Equivalent to an ACL entry on a bucket with the WRITER role. \n- roles/storage.legacyBucketOwner \u2014 Read and write access to existing buckets with object listing/creation/deletion. Equivalent to an ACL entry on a bucket with the OWNER role.", + "annotations": { + "required": [ + "storage.buckets.setIamPolicy", + "storage.objects.setIamPolicy", + "storage.managedFolders.setIamPolicy" + ] + } + } + } }, - "contentEncoding": { - "type": "string", - "description": "Content-Encoding of the object data." + "annotations": { + "required": [ + "storage.buckets.setIamPolicy", + "storage.objects.setIamPolicy", + "storage.managedFolders.setIamPolicy" + ] + } + }, + "etag": { + "type": "string", + "description": "HTTP 1.1 Entity tag for the policy.", + "format": "byte" + }, + "kind": { + "type": "string", + "description": "The kind of item this is. For policies, this is always storage#policy. This field is ignored on input.", + "default": "storage#policy" + }, + "resourceId": { + "type": "string", + "description": "The ID of the resource to which this policy belongs. Will be of the form projects/_/buckets/bucket for buckets, projects/_/buckets/bucket/objects/object for objects, and projects/_/buckets/bucket/managedFolders/managedFolder. A specific generation may be specified by appending #generationNumber to the end of the object name, e.g. projects/_/buckets/my-bucket/objects/data.txt#17. The current generation can be denoted with #0. This field is ignored on input." + }, + "version": { + "type": "integer", + "description": "The IAM policy format version.", + "format": "int32" + } + } + }, + "RewriteResponse": { + "id": "RewriteResponse", + "type": "object", + "description": "A rewrite response.", + "properties": { + "done": { + "type": "boolean", + "description": "true if the copy is finished; otherwise, false if the copy is in progress. This property is always present in the response." + }, + "kind": { + "type": "string", + "description": "The kind of item this is.", + "default": "storage#rewriteResponse" + }, + "objectSize": { + "type": "string", + "description": "The total size of the object being copied in bytes. This property is always present in the response.", + "format": "int64" + }, + "resource": { + "$ref": "Object", + "description": "A resource containing the metadata for the copied-to object. This property is present in the response only when copying completes." + }, + "rewriteToken": { + "type": "string", + "description": "A token to use in subsequent requests to continue copying data. This token is present in the response only when there is more data to copy." + }, + "totalBytesRewritten": { + "type": "string", + "description": "The total bytes written so far, which can be used to provide a waiting user with a progress indicator. This property is always present in the response.", + "format": "int64" + } + } + }, + "ServiceAccount": { + "id": "ServiceAccount", + "type": "object", + "description": "A subscription to receive Google PubSub notifications.", + "properties": { + "email_address": { + "type": "string", + "description": "The ID of the notification." + }, + "kind": { + "type": "string", + "description": "The kind of item this is. For notifications, this is always storage#notification.", + "default": "storage#serviceAccount" + } + } + }, + "TestIamPermissionsResponse": { + "id": "TestIamPermissionsResponse", + "type": "object", + "description": "A storage.(buckets|objects|managedFolders).testIamPermissions response.", + "properties": { + "kind": { + "type": "string", + "description": "The kind of item this is.", + "default": "storage#testIamPermissionsResponse" + }, + "permissions": { + "type": "array", + "description": "The permissions held by the caller. Permissions are always of the format storage.resource.capability, where resource is one of buckets, objects, or managedFolders. The supported permissions are as follows: \n- storage.buckets.delete \u2014 Delete bucket. \n- storage.buckets.get \u2014 Read bucket metadata. \n- storage.buckets.getIamPolicy \u2014 Read bucket IAM policy. \n- storage.buckets.create \u2014 Create bucket. \n- storage.buckets.list \u2014 List buckets. \n- storage.buckets.setIamPolicy \u2014 Update bucket IAM policy. \n- storage.buckets.update \u2014 Update bucket metadata. \n- storage.objects.delete \u2014 Delete object. \n- storage.objects.get \u2014 Read object data and metadata. \n- storage.objects.getIamPolicy \u2014 Read object IAM policy. \n- storage.objects.create \u2014 Create object. \n- storage.objects.list \u2014 List objects. \n- storage.objects.setIamPolicy \u2014 Update object IAM policy. \n- storage.objects.update \u2014 Update object metadata. \n- storage.managedFolders.delete \u2014 Delete managed folder. \n- storage.managedFolders.get \u2014 Read managed folder metadata. \n- storage.managedFolders.getIamPolicy \u2014 Read managed folder IAM policy. \n- storage.managedFolders.create \u2014 Create managed folder. \n- storage.managedFolders.list \u2014 List managed folders. \n- storage.managedFolders.setIamPolicy \u2014 Update managed folder IAM policy.", + "items": { + "type": "string" + } + } + } + }, + "BulkRestoreObjectsRequest": { + "id": "BulkRestoreObjectsRequest", + "type": "object", + "description": "A bulk restore objects request.", + "properties": { + "allowOverwrite": { + "type": "boolean", + "description": "If false (default), the restore will not overwrite live objects with the same name at the destination. This means some deleted objects may be skipped. If true, live objects will be overwritten resulting in a noncurrent object (if versioning is enabled). If versioning is not enabled, overwriting the object will result in a soft-deleted object. In either case, if a noncurrent object already exists with the same name, a live version can be written without issue." + }, + "softDeletedAfterTime": { + "type": "string", + "description": "Restores only the objects that were soft-deleted after this time.", + "format": "date-time" + }, + "softDeletedBeforeTime": { + "type": "string", + "description": "Restores only the objects that were soft-deleted before this time.", + "format": "date-time" + }, + "matchGlobs": { + "type": "array", + "description": "Restores only the objects matching any of the specified glob(s). If this parameter is not specified, all objects will be restored within the specified time range.", + "items": { + "type": "string" + } + }, + "copySourceAcl": { + "type": "boolean", + "description": "If true, copies the source object's ACL; otherwise, uses the bucket's default object ACL. The default is false." + } + } + } + }, + "resources": { + "anywhereCache": { + "methods": { + "insert": { + "id": "storage.anywhereCaches.insert", + "path": "b/{bucket}/anywhereCaches", + "httpMethod": "POST", + "description": "Creates an Anywhere Cache instance.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the partent bucket", + "required": true, + "location": "path" + } }, - "contentLanguage": { - "type": "string", - "description": "Content-Language of the object data." + "parameterOrder": [ + "bucket" + ], + "request": { + "$ref": "AnywhereCache" }, - "contentType": { - "type": "string", - "description": "Content-Type of the object data. If an object is stored without a Content-Type, it is served as application/octet-stream." + "response": { + "$ref": "GoogleLongrunningOperation" }, - "crc32c": { - "type": "string", - "description": "CRC32c checksum, as described in RFC 4960, Appendix B; encoded using base64 in big-endian byte order. For more information about using the CRC32c checksum, see Hashes and ETags: Best Practices." + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "update": { + "id": "storage.anywhereCaches.update", + "path": "b/{bucket}/anywhereCaches/{anywhereCacheId}", + "httpMethod": "PATCH", + "description": "Updates the config(ttl and admissionPolicy) of an Anywhere Cache instance.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the partent bucket", + "required": true, + "location": "path" + }, + "anywhereCacheId": { + "type": "string", + "description": "The ID of requested Anywhere Cache instance.", + "required": true, + "location": "path" + } }, - "customTime": { - "type": "string", - "description": "A timestamp in RFC 3339 format specified by the user for an object.", - "format": "date-time" + "parameterOrder": [ + "bucket", + "anywhereCacheId" + ], + "request": { + "$ref": "AnywhereCache" + }, + "response": { + "$ref": "GoogleLongrunningOperation" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "get": { + "id": "storage.anywhereCaches.get", + "path": "b/{bucket}/anywhereCaches/{anywhereCacheId}", + "httpMethod": "GET", + "description": "Returns the metadata of an Anywhere Cache instance.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the partent bucket", + "required": true, + "location": "path" + }, + "anywhereCacheId": { + "type": "string", + "description": "The ID of requested Anywhere Cache instance.", + "required": true, + "location": "path" + } }, - "customerEncryption": { - "type": "object", - "description": "Metadata of customer-supplied encryption key, if the object is encrypted by such a key.", - "properties": { - "encryptionAlgorithm": { - "type": "string", - "description": "The encryption algorithm." - }, - "keySha256": { - "type": "string", - "description": "SHA256 hash value of the encryption key." - } + "parameterOrder": [ + "bucket", + "anywhereCacheId" + ], + "response": { + "$ref": "AnywhereCache" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "list": { + "id": "storage.anywhereCaches.list", + "path": "b/{bucket}/anywhereCache", + "httpMethod": "GET", + "description": "Returns a list of Anywhere Cache instances of the bucket matching the criteria.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the partent bucket", + "required": true, + "location": "path" + }, + "pageSize": { + "type": "integer", + "description": "Maximum number of items return in a single page of responses. Maximum 1000.", + "format": "int32", + "minimum": "0", + "location": "query" + }, + "pageToken": { + "type": "string", + "description": "A previously-returned page token representing part of the larger set of results to view.", + "location": "query" + } + }, + "parameterOrder": [ + "bucket" + ], + "response": { + "$ref": "AnywhereCaches" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "pause": { + "id": "storage.anywhereCaches.pause", + "path": "b/{bucket}/anywhereCaches/{anywhereCacheId}/pause", + "httpMethod": "POST", + "description": "Pauses an Anywhere Cache instance.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the partent bucket", + "required": true, + "location": "path" + }, + "anywhereCacheId": { + "type": "string", + "description": "The ID of requested Anywhere Cache instance.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "bucket", + "anywhereCacheId" + ], + "response": { + "$ref": "AnywhereCache" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "resume": { + "id": "storage.anywhereCaches.resume", + "path": "b/{bucket}/anywhereCaches/{anywhereCacheId}/resume", + "httpMethod": "POST", + "description": "Resumes a paused or disabled Anywhere Cache instance.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the partent bucket", + "required": true, + "location": "path" + }, + "anywhereCacheId": { + "type": "string", + "description": "The ID of requested Anywhere Cache instance.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "bucket", + "anywhereCacheId" + ], + "response": { + "$ref": "AnywhereCache" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "disable": { + "id": "storage.anywhereCaches.disable", + "path": "b/{bucket}/anywhereCaches/{anywhereCacheId}/disable", + "httpMethod": "POST", + "description": "Disables an Anywhere Cache instance.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the partent bucket", + "required": true, + "location": "path" + }, + "anywhereCacheId": { + "type": "string", + "description": "The ID of requested Anywhere Cache instance.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "bucket", + "anywhereCacheId" + ], + "response": { + "$ref": "AnywhereCache" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + } + } + }, + "bucketAccessControls": { + "methods": { + "delete": { + "id": "storage.bucketAccessControls.delete", + "path": "b/{bucket}/acl/{entity}", + "httpMethod": "DELETE", + "description": "Permanently deletes the ACL entry for the specified entity on the specified bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" + }, + "entity": { + "type": "string", + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "required": true, + "location": "path" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } + }, + "parameterOrder": [ + "bucket", + "entity" + ], + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "get": { + "id": "storage.bucketAccessControls.get", + "path": "b/{bucket}/acl/{entity}", + "httpMethod": "GET", + "description": "Returns the ACL entry for the specified entity on the specified bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" + }, + "entity": { + "type": "string", + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "required": true, + "location": "path" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } + }, + "parameterOrder": [ + "bucket", + "entity" + ], + "response": { + "$ref": "BucketAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "insert": { + "id": "storage.bucketAccessControls.insert", + "path": "b/{bucket}/acl", + "httpMethod": "POST", + "description": "Creates a new ACL entry on the specified bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } + }, + "parameterOrder": [ + "bucket" + ], + "request": { + "$ref": "BucketAccessControl" + }, + "response": { + "$ref": "BucketAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "list": { + "id": "storage.bucketAccessControls.list", + "path": "b/{bucket}/acl", + "httpMethod": "GET", + "description": "Retrieves ACL entries on the specified bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } + }, + "parameterOrder": [ + "bucket" + ], + "response": { + "$ref": "BucketAccessControls" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "patch": { + "id": "storage.bucketAccessControls.patch", + "path": "b/{bucket}/acl/{entity}", + "httpMethod": "PATCH", + "description": "Patches an ACL entry on the specified bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" + }, + "entity": { + "type": "string", + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "required": true, + "location": "path" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } + }, + "parameterOrder": [ + "bucket", + "entity" + ], + "request": { + "$ref": "BucketAccessControl" + }, + "response": { + "$ref": "BucketAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "update": { + "id": "storage.bucketAccessControls.update", + "path": "b/{bucket}/acl/{entity}", + "httpMethod": "PUT", + "description": "Updates an ACL entry on the specified bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" + }, + "entity": { + "type": "string", + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "required": true, + "location": "path" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } + }, + "parameterOrder": [ + "bucket", + "entity" + ], + "request": { + "$ref": "BucketAccessControl" + }, + "response": { + "$ref": "BucketAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + } + } + }, + "buckets": { + "methods": { + "delete": { + "id": "storage.buckets.delete", + "path": "b/{bucket}", + "httpMethod": "DELETE", + "description": "Permanently deletes an empty bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" + }, + "ifMetagenerationMatch": { + "type": "string", + "description": "If set, only deletes the bucket if its metageneration matches this value.", + "format": "int64", + "location": "query" + }, + "ifMetagenerationNotMatch": { + "type": "string", + "description": "If set, only deletes the bucket if its metageneration does not match this value.", + "format": "int64", + "location": "query" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } + }, + "parameterOrder": [ + "bucket" + ], + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "get": { + "id": "storage.buckets.get", + "path": "b/{bucket}", + "httpMethod": "GET", + "description": "Returns metadata for the specified bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" + }, + "ifMetagenerationMatch": { + "type": "string", + "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration matches the given value.", + "format": "int64", + "location": "query" + }, + "ifMetagenerationNotMatch": { + "type": "string", + "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration does not match the given value.", + "format": "int64", + "location": "query" + }, + "projection": { + "type": "string", + "description": "Set of properties to return. Defaults to noAcl.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit owner, acl and defaultObjectAcl properties." + ], + "location": "query" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } + }, + "parameterOrder": [ + "bucket" + ], + "response": { + "$ref": "Bucket" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "getIamPolicy": { + "id": "storage.buckets.getIamPolicy", + "path": "b/{bucket}/iam", + "httpMethod": "GET", + "description": "Returns an IAM policy for the specified bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" + }, + "optionsRequestedPolicyVersion": { + "type": "integer", + "description": "The IAM policy format version to be returned. If the optionsRequestedPolicyVersion is for an older version that doesn't support part of the requested IAM policy, the request fails.", + "format": "int32", + "minimum": "1", + "location": "query" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" } }, - "etag": { - "type": "string", - "description": "HTTP 1.1 Entity tag for the object." + "parameterOrder": [ + "bucket" + ], + "response": { + "$ref": "Policy" }, - "eventBasedHold": { - "type": "boolean", - "description": "Whether an object is under event-based hold. Event-based hold is a way to retain objects until an event occurs, which is signified by the hold's release (i.e. this value is set to false). After being released (set to false), such objects will be subject to bucket-level retention (if any). One sample use case of this flag is for banks to hold loan documents for at least 3 years after loan is paid in full. Here, bucket-level retention is 3 years and the event is the loan being paid in full. In this example, these objects will be held intact for any number of years until the event has occurred (event-based hold on the object is released) and then 3 more years after that. That means retention duration of the objects begins from the moment event-based hold transitioned from true to false." + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "insert": { + "id": "storage.buckets.insert", + "path": "b", + "httpMethod": "POST", + "description": "Creates a new bucket.", + "parameters": { + "predefinedAcl": { + "type": "string", + "description": "Apply a predefined set of access controls to this bucket.", + "enum": [ + "authenticatedRead", + "private", + "projectPrivate", + "publicRead", + "publicReadWrite" + ], + "enumDescriptions": [ + "Project team owners get OWNER access, and allAuthenticatedUsers get READER access.", + "Project team owners get OWNER access.", + "Project team members get access according to their roles.", + "Project team owners get OWNER access, and allUsers get READER access.", + "Project team owners get OWNER access, and allUsers get WRITER access." + ], + "location": "query" + }, + "predefinedDefaultObjectAcl": { + "type": "string", + "description": "Apply a predefined set of default object access controls to this bucket.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query" + }, + "project": { + "type": "string", + "description": "A valid API project identifier.", + "required": true, + "location": "query" + }, + "projection": { + "type": "string", + "description": "Set of properties to return. Defaults to noAcl, unless the bucket resource specifies acl or defaultObjectAcl properties, when it defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit owner, acl and defaultObjectAcl properties." + ], + "location": "query" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request.", + "location": "query" + }, + "enableObjectRetention": { + "type": "boolean", + "description": "When set to true, object retention is enabled for this bucket.", + "default": "false", + "location": "query" + } }, - "generation": { - "type": "string", - "description": "The content generation of this object. Used for object versioning.", - "format": "int64" + "parameterOrder": [ + "project" + ], + "request": { + "$ref": "Bucket" }, - "id": { - "type": "string", - "description": "The ID of the object, including the bucket name, object name, and generation number." + "response": { + "$ref": "Bucket" }, - "kind": { - "type": "string", - "description": "The kind of item this is. For objects, this is always storage#object.", - "default": "storage#object" + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "list": { + "id": "storage.buckets.list", + "path": "b", + "httpMethod": "GET", + "description": "Retrieves a list of buckets for a given project.", + "parameters": { + "maxResults": { + "type": "integer", + "description": "Maximum number of buckets to return in a single response. The service will use this parameter or 1,000 items, whichever is smaller.", + "default": "1000", + "format": "uint32", + "minimum": "0", + "location": "query" + }, + "pageToken": { + "type": "string", + "description": "A previously-returned page token representing part of the larger set of results to view.", + "location": "query" + }, + "prefix": { + "type": "string", + "description": "Filter results to buckets whose names begin with this prefix.", + "location": "query" + }, + "project": { + "type": "string", + "description": "A valid API project identifier.", + "required": true, + "location": "query" + }, + "projection": { + "type": "string", + "description": "Set of properties to return. Defaults to noAcl.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit owner, acl and defaultObjectAcl properties." + ], + "location": "query" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request.", + "location": "query" + } }, - "kmsKeyName": { - "type": "string", - "description": "Not currently supported. Specifying the parameter causes the request to fail with status code 400 - Bad Request." + "parameterOrder": [ + "project" + ], + "response": { + "$ref": "Buckets" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "lockRetentionPolicy": { + "id": "storage.buckets.lockRetentionPolicy", + "path": "b/{bucket}/lockRetentionPolicy", + "httpMethod": "POST", + "description": "Locks retention policy on a bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" + }, + "ifMetagenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether bucket's current metageneration matches the given value.", + "required": true, + "format": "int64", + "location": "query" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "md5Hash": { - "type": "string", - "description": "MD5 hash of the data; encoded using base64. For more information about using the MD5 hash, see Hashes and ETags: Best Practices." + "parameterOrder": [ + "bucket", + "ifMetagenerationMatch" + ], + "response": { + "$ref": "Bucket" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "patch": { + "id": "storage.buckets.patch", + "path": "b/{bucket}", + "httpMethod": "PATCH", + "description": "Patches a bucket. Changes to the bucket will be readable immediately after writing, but configuration changes may take time to propagate.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" + }, + "ifMetagenerationMatch": { + "type": "string", + "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration matches the given value.", + "format": "int64", + "location": "query" + }, + "ifMetagenerationNotMatch": { + "type": "string", + "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration does not match the given value.", + "format": "int64", + "location": "query" + }, + "predefinedAcl": { + "type": "string", + "description": "Apply a predefined set of access controls to this bucket.", + "enum": [ + "authenticatedRead", + "private", + "projectPrivate", + "publicRead", + "publicReadWrite" + ], + "enumDescriptions": [ + "Project team owners get OWNER access, and allAuthenticatedUsers get READER access.", + "Project team owners get OWNER access.", + "Project team members get access according to their roles.", + "Project team owners get OWNER access, and allUsers get READER access.", + "Project team owners get OWNER access, and allUsers get WRITER access." + ], + "location": "query" + }, + "predefinedDefaultObjectAcl": { + "type": "string", + "description": "Apply a predefined set of default object access controls to this bucket.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query" + }, + "projection": { + "type": "string", + "description": "Set of properties to return. Defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit owner, acl and defaultObjectAcl properties." + ], + "location": "query" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "mediaLink": { - "type": "string", - "description": "Media download link." + "parameterOrder": [ + "bucket" + ], + "request": { + "$ref": "Bucket" }, - "metadata": { - "type": "object", - "description": "User-provided metadata, in key/value pairs.", - "additionalProperties": { + "response": { + "$ref": "Bucket" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "setIamPolicy": { + "id": "storage.buckets.setIamPolicy", + "path": "b/{bucket}/iam", + "httpMethod": "PUT", + "description": "Updates an IAM policy for the specified bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" + }, + "userProject": { "type": "string", - "description": "An individual metadata entry." + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" } }, - "metageneration": { - "type": "string", - "description": "The version of the metadata for this object at this generation. Used for preconditions and for detecting changes in metadata. A metageneration number is only meaningful in the context of a particular generation of a particular object.", - "format": "int64" + "parameterOrder": [ + "bucket" + ], + "request": { + "$ref": "Policy" }, - "name": { - "type": "string", - "description": "The name of the object. Required if not specified by URL parameter." + "response": { + "$ref": "Policy" }, - "owner": { - "type": "object", - "description": "The owner of the object. This will always be the uploader of the object.", - "properties": { - "entity": { - "type": "string", - "description": "The entity, in the form user-userId." - }, - "entityId": { - "type": "string", - "description": "The ID for the entity." - } + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "testIamPermissions": { + "id": "storage.buckets.testIamPermissions", + "path": "b/{bucket}/iam/testPermissions", + "httpMethod": "GET", + "description": "Tests a set of permissions on the given bucket to see which, if any, are held by the caller.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" + }, + "permissions": { + "type": "string", + "description": "Permissions to test.", + "required": true, + "repeated": true, + "location": "query" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" } }, - "retentionExpirationTime": { - "type": "string", - "description": "A server-determined value that specifies the earliest time that the object's retention period expires. This value is in RFC 3339 format. Note 1: This field is not provided for objects with an active event-based hold, since retention expiration is unknown until the hold is removed. Note 2: This value can be provided even when temporary hold is set (so that the user can reason about policy without having to first unset the temporary hold).", - "format": "date-time" + "parameterOrder": [ + "bucket", + "permissions" + ], + "response": { + "$ref": "TestIamPermissionsResponse" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "update": { + "id": "storage.buckets.update", + "path": "b/{bucket}", + "httpMethod": "PUT", + "description": "Updates a bucket. Changes to the bucket will be readable immediately after writing, but configuration changes may take time to propagate.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" + }, + "ifMetagenerationMatch": { + "type": "string", + "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration matches the given value.", + "format": "int64", + "location": "query" + }, + "ifMetagenerationNotMatch": { + "type": "string", + "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration does not match the given value.", + "format": "int64", + "location": "query" + }, + "predefinedAcl": { + "type": "string", + "description": "Apply a predefined set of access controls to this bucket.", + "enum": [ + "authenticatedRead", + "private", + "projectPrivate", + "publicRead", + "publicReadWrite" + ], + "enumDescriptions": [ + "Project team owners get OWNER access, and allAuthenticatedUsers get READER access.", + "Project team owners get OWNER access.", + "Project team members get access according to their roles.", + "Project team owners get OWNER access, and allUsers get READER access.", + "Project team owners get OWNER access, and allUsers get WRITER access." + ], + "location": "query" + }, + "predefinedDefaultObjectAcl": { + "type": "string", + "description": "Apply a predefined set of default object access controls to this bucket.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query" + }, + "projection": { + "type": "string", + "description": "Set of properties to return. Defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit owner, acl and defaultObjectAcl properties." + ], + "location": "query" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "selfLink": { - "type": "string", - "description": "The link to this object." + "parameterOrder": [ + "bucket" + ], + "request": { + "$ref": "Bucket" }, - "size": { - "type": "string", - "description": "Content-Length of the data in bytes.", - "format": "uint64" + "response": { + "$ref": "Bucket" }, - "storageClass": { - "type": "string", - "description": "Storage class of the object." + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + } + } + }, + "operations": { + "methods": { + "cancel": { + "description": "Starts asynchronous cancellation on a long-running operation. The server makes a best effort to cancel the operation, but success is not guaranteed.", + "path": "b/{bucket}/operations/{operationId}/cancel", + "httpMethod": "POST", + "id": "storage.buckets.operations.cancel", + "parameterOrder": [ + "bucket", + "operationId" + ], + "parameters": { + "bucket": { + "description": "The parent bucket of the operation resource.", + "location": "path", + "required": true, + "type": "string" + }, + "operationId": { + "description": "The ID of the operation resource.", + "location": "path", + "required": true, + "type": "string" + } }, - "temporaryHold": { - "type": "boolean", - "description": "Whether an object is under temporary hold. While this flag is set to true, the object is protected against deletion and overwrites. A common use case of this flag is regulatory investigations where objects need to be retained while the investigation is ongoing. Note that unlike event-based hold, temporary hold does not impact retention expiration time of an object." + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "get": { + "description": "Gets the latest state of a long-running operation.", + "path": "b/{bucket}/operations/{operationId}", + "httpMethod": "GET", + "id": "storage.buckets.operations.get", + "parameterOrder": [ + "bucket", + "operationId" + ], + "parameters": { + "bucket": { + "description": "The parent bucket of the operation resource.", + "location": "path", + "required": true, + "type": "string" + }, + "operationId": { + "description": "The ID of the operation resource.", + "location": "path", + "required": true, + "type": "string" + } }, - "timeCreated": { - "type": "string", - "description": "The creation time of the object in RFC 3339 format.", - "format": "date-time" + "response": { + "$ref": "GoogleLongrunningOperation" }, - "timeDeleted": { - "type": "string", - "description": "The deletion time of the object in RFC 3339 format. Will be returned if and only if this version of the object has been deleted.", - "format": "date-time" + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "list": { + "description": "Lists operations that match the specified filter in the request.", + "path": "b/{bucket}/operations", + "httpMethod": "GET", + "id": "storage.buckets.operations.list", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "filter": { + "description": "A filter to narrow down results to a preferred subset. The filtering language is documented in more detail in [AIP-160](https://google.aip.dev/160).", + "location": "query", + "type": "string" + }, + "bucket": { + "description": "Name of the bucket in which to look for operations.", + "location": "path", + "required": true, + "type": "string" + }, + "pageSize": { + "description": "Maximum number of items to return in a single page of responses. Fewer total results may be returned than requested. The service uses this parameter or 100 items, whichever is smaller.", + "minimum": "0", + "format": "int32", + "location": "query", + "type": "integer" + }, + "pageToken": { + "description": "A previously-returned page token representing part of the larger set of results to view.", + "location": "query", + "type": "string" + } }, - "timeStorageClassUpdated": { - "type": "string", - "description": "The time at which the object's storage class was last changed. When the object is initially created, it will be set to timeCreated.", - "format": "date-time" + "response": { + "$ref": "GoogleLongrunningListOperationsResponse" }, - "updated": { - "type": "string", - "description": "The modification time of the object metadata in RFC 3339 format. Set initially to object creation time and then updated whenever any metadata of the object changes. This includes changes made by a requester, such as modifying custom metadata, as well as changes made by Cloud Storage on behalf of a requester, such as changing the storage class based on an Object Lifecycle Configuration.", - "format": "date-time" - } + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] } - }, - "ObjectAccessControl": { - "id": "ObjectAccessControl", - "type": "object", - "description": "An access-control entry.", - "properties": { - "bucket": { - "type": "string", - "description": "The name of the bucket." - }, - "domain": { - "type": "string", - "description": "The domain associated with the entity, if any." + } + }, + "channels": { + "methods": { + "stop": { + "id": "storage.channels.stop", + "path": "channels/stop", + "httpMethod": "POST", + "description": "Stop watching resources through this channel", + "request": { + "$ref": "Channel", + "parameterName": "resource" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + } + } + }, + "defaultObjectAccessControls": { + "methods": { + "delete": { + "id": "storage.defaultObjectAccessControls.delete", + "path": "b/{bucket}/defaultObjectAcl/{entity}", + "httpMethod": "DELETE", + "description": "Permanently deletes the default object ACL entry for the specified entity on the specified bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" + }, + "entity": { + "type": "string", + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "required": true, + "location": "path" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "email": { - "type": "string", - "description": "The email address associated with the entity, if any." + "parameterOrder": [ + "bucket", + "entity" + ], + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "get": { + "id": "storage.defaultObjectAccessControls.get", + "path": "b/{bucket}/defaultObjectAcl/{entity}", + "httpMethod": "GET", + "description": "Returns the default object ACL entry for the specified entity on the specified bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" + }, + "entity": { + "type": "string", + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "required": true, + "location": "path" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "entity": { - "type": "string", - "description": "The entity holding the permission, in one of the following forms: \n- user-userId \n- user-email \n- group-groupId \n- group-email \n- domain-domain \n- project-team-projectId \n- allUsers \n- allAuthenticatedUsers Examples: \n- The user liz@example.com would be user-liz@example.com. \n- The group example@googlegroups.com would be group-example@googlegroups.com. \n- To refer to all members of the Google Apps for Business domain example.com, the entity would be domain-example.com.", - "annotations": { - "required": [ - "storage.defaultObjectAccessControls.insert", - "storage.objectAccessControls.insert" - ] + "parameterOrder": [ + "bucket", + "entity" + ], + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "insert": { + "id": "storage.defaultObjectAccessControls.insert", + "path": "b/{bucket}/defaultObjectAcl", + "httpMethod": "POST", + "description": "Creates a new default object ACL entry on the specified bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" } }, - "entityId": { - "type": "string", - "description": "The ID for the entity, if any." + "parameterOrder": [ + "bucket" + ], + "request": { + "$ref": "ObjectAccessControl" }, - "etag": { - "type": "string", - "description": "HTTP 1.1 Entity tag for the access-control entry." + "response": { + "$ref": "ObjectAccessControl" }, - "generation": { - "type": "string", - "description": "The content generation of the object, if applied to an object.", - "format": "int64" + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "list": { + "id": "storage.defaultObjectAccessControls.list", + "path": "b/{bucket}/defaultObjectAcl", + "httpMethod": "GET", + "description": "Retrieves default object ACL entries on the specified bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" + }, + "ifMetagenerationMatch": { + "type": "string", + "description": "If present, only return default ACL listing if the bucket's current metageneration matches this value.", + "format": "int64", + "location": "query" + }, + "ifMetagenerationNotMatch": { + "type": "string", + "description": "If present, only return default ACL listing if the bucket's current metageneration does not match the given value.", + "format": "int64", + "location": "query" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "id": { - "type": "string", - "description": "The ID of the access-control entry." + "parameterOrder": [ + "bucket" + ], + "response": { + "$ref": "ObjectAccessControls" }, - "kind": { - "type": "string", - "description": "The kind of item this is. For object access control entries, this is always storage#objectAccessControl.", - "default": "storage#objectAccessControl" + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "patch": { + "id": "storage.defaultObjectAccessControls.patch", + "path": "b/{bucket}/defaultObjectAcl/{entity}", + "httpMethod": "PATCH", + "description": "Patches a default object ACL entry on the specified bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" + }, + "entity": { + "type": "string", + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "required": true, + "location": "path" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "object": { - "type": "string", - "description": "The name of the object, if applied to an object." + "parameterOrder": [ + "bucket", + "entity" + ], + "request": { + "$ref": "ObjectAccessControl" }, - "projectTeam": { - "type": "object", - "description": "The project team associated with the entity, if any.", - "properties": { - "projectNumber": { - "type": "string", - "description": "The project number." - }, - "team": { - "type": "string", - "description": "The team." - } - } + "response": { + "$ref": "ObjectAccessControl" }, - "role": { - "type": "string", - "description": "The access permission for the entity.", - "annotations": { - "required": [ - "storage.defaultObjectAccessControls.insert", - "storage.objectAccessControls.insert" - ] + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "update": { + "id": "storage.defaultObjectAccessControls.update", + "path": "b/{bucket}/defaultObjectAcl/{entity}", + "httpMethod": "PUT", + "description": "Updates a default object ACL entry on the specified bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" + }, + "entity": { + "type": "string", + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "required": true, + "location": "path" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" } }, - "selfLink": { - "type": "string", - "description": "The link to this access-control entry." - } - } - }, - "ObjectAccessControls": { - "id": "ObjectAccessControls", - "type": "object", - "description": "An access-control list.", - "properties": { - "items": { - "type": "array", - "description": "The list of items.", - "items": { - "$ref": "ObjectAccessControl" - } + "parameterOrder": [ + "bucket", + "entity" + ], + "request": { + "$ref": "ObjectAccessControl" }, - "kind": { - "type": "string", - "description": "The kind of item this is. For lists of object access control entries, this is always storage#objectAccessControls.", - "default": "storage#objectAccessControls" - } + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] } - }, - "Objects": { - "id": "Objects", - "type": "object", - "description": "A list of objects.", - "properties": { - "items": { - "type": "array", - "description": "The list of items.", - "items": { - "$ref": "Object" + } + }, + "managedFolders": { + "methods": { + "delete": { + "id": "storage.managedFolders.delete", + "path": "b/{bucket}/managedFolders/{managedFolder}", + "httpMethod": "DELETE", + "description": "Permanently deletes a managed folder.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the bucket containing the managed folder.", + "required": true, + "location": "path" + }, + "managedFolder": { + "type": "string", + "description": "The managed folder name/path.", + "required": true, + "location": "path" + }, + "ifMetagenerationMatch": { + "type": "string", + "description": "If set, only deletes the managed folder if its metageneration matches this value.", + "format": "int64", + "location": "query" + }, + "ifMetagenerationNotMatch": { + "type": "string", + "description": "If set, only deletes the managed folder if its metageneration does not match this value.", + "format": "int64", + "location": "query" } }, - "kind": { - "type": "string", - "description": "The kind of item this is. For lists of objects, this is always storage#objects.", - "default": "storage#objects" - }, - "nextPageToken": { - "type": "string", - "description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results." - }, - "prefixes": { - "type": "array", - "description": "The list of prefixes of objects matching-but-not-listed up to and including the requested delimiter.", - "items": { - "type": "string" + "parameterOrder": [ + "bucket", + "managedFolder" + ], + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "get": { + "id": "storage.managedFolders.get", + "path": "b/{bucket}/managedFolders/{managedFolder}", + "httpMethod": "GET", + "description": "Returns metadata of the specified managed folder.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the bucket containing the managed folder.", + "required": true, + "location": "path" + }, + "managedFolder": { + "type": "string", + "description": "The managed folder name/path.", + "required": true, + "location": "path" + }, + "ifMetagenerationMatch": { + "type": "string", + "description": "Makes the return of the managed folder metadata conditional on whether the managed folder's current metageneration matches the given value.", + "format": "int64", + "location": "query" + }, + "ifMetagenerationNotMatch": { + "type": "string", + "description": "Makes the return of the managed folder metadata conditional on whether the managed folder's current metageneration does not match the given value.", + "format": "int64", + "location": "query" } - } - } - }, - "Policy": { - "id": "Policy", - "type": "object", - "description": "A bucket/object IAM policy.", - "properties": { - "bindings": { - "type": "array", - "description": "An association between a role, which comes with a set of permissions, and members who may assume that role.", - "items": { - "type": "object", - "properties": { - "condition": { - "$ref": "Expr", - "description": "The condition that is associated with this binding. NOTE: an unsatisfied condition will not allow user access via current binding. Different bindings, including their conditions, are examined independently." - }, - "members": { - "type": "array", - "description": "A collection of identifiers for members who may assume the provided role. Recognized identifiers are as follows: \n- allUsers \u2014 A special identifier that represents anyone on the internet; with or without a Google account. \n- allAuthenticatedUsers \u2014 A special identifier that represents anyone who is authenticated with a Google account or a service account. \n- user:emailid \u2014 An email address that represents a specific account. For example, user:alice@gmail.com or user:joe@example.com. \n- serviceAccount:emailid \u2014 An email address that represents a service account. For example, serviceAccount:my-other-app@appspot.gserviceaccount.com . \n- group:emailid \u2014 An email address that represents a Google group. For example, group:admins@example.com. \n- domain:domain \u2014 A Google Apps domain name that represents all the users of that domain. For example, domain:google.com or domain:example.com. \n- projectOwner:projectid \u2014 Owners of the given project. For example, projectOwner:my-example-project \n- projectEditor:projectid \u2014 Editors of the given project. For example, projectEditor:my-example-project \n- projectViewer:projectid \u2014 Viewers of the given project. For example, projectViewer:my-example-project", - "items": { - "type": "string" - }, - "annotations": { - "required": [ - "storage.buckets.setIamPolicy", - "storage.objects.setIamPolicy" - ] - } - }, - "role": { - "type": "string", - "description": "The role to which members belong. Two types of roles are supported: new IAM roles, which grant permissions that do not map directly to those provided by ACLs, and legacy IAM roles, which do map directly to ACL permissions. All roles are of the format roles/storage.specificRole.\nThe new IAM roles are: \n- roles/storage.admin \u2014 Full control of Google Cloud Storage resources. \n- roles/storage.objectViewer \u2014 Read-Only access to Google Cloud Storage objects. \n- roles/storage.objectCreator \u2014 Access to create objects in Google Cloud Storage. \n- roles/storage.objectAdmin \u2014 Full control of Google Cloud Storage objects. The legacy IAM roles are: \n- roles/storage.legacyObjectReader \u2014 Read-only access to objects without listing. Equivalent to an ACL entry on an object with the READER role. \n- roles/storage.legacyObjectOwner \u2014 Read/write access to existing objects without listing. Equivalent to an ACL entry on an object with the OWNER role. \n- roles/storage.legacyBucketReader \u2014 Read access to buckets with object listing. Equivalent to an ACL entry on a bucket with the READER role. \n- roles/storage.legacyBucketWriter \u2014 Read access to buckets with object listing/creation/deletion. Equivalent to an ACL entry on a bucket with the WRITER role. \n- roles/storage.legacyBucketOwner \u2014 Read and write access to existing buckets with object listing/creation/deletion. Equivalent to an ACL entry on a bucket with the OWNER role.", - "annotations": { - "required": [ - "storage.buckets.setIamPolicy", - "storage.objects.setIamPolicy" - ] - } - } - } + }, + "parameterOrder": [ + "bucket", + "managedFolder" + ], + "response": { + "$ref": "ManagedFolder" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "getIamPolicy": { + "id": "storage.managedFolders.getIamPolicy", + "path": "b/{bucket}/managedFolders/{managedFolder}/iam", + "httpMethod": "GET", + "description": "Returns an IAM policy for the specified managed folder.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the bucket containing the managed folder.", + "required": true, + "location": "path" + }, + "optionsRequestedPolicyVersion": { + "type": "integer", + "description": "The IAM policy format version to be returned. If the optionsRequestedPolicyVersion is for an older version that doesn't support part of the requested IAM policy, the request fails.", + "format": "int32", + "minimum": "1", + "location": "query" + }, + "managedFolder": { + "type": "string", + "description": "The managed folder name/path.", + "required": true, + "location": "path" }, - "annotations": { - "required": [ - "storage.buckets.setIamPolicy", - "storage.objects.setIamPolicy" - ] + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } + }, + "parameterOrder": [ + "bucket", + "managedFolder" + ], + "response": { + "$ref": "Policy" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "insert": { + "id": "storage.managedFolders.insert", + "path": "b/{bucket}/managedFolders", + "httpMethod": "POST", + "description": "Creates a new managed folder.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the bucket containing the managed folder.", + "required": true, + "location": "path" } }, - "etag": { - "type": "string", - "description": "HTTP 1.1 Entity tag for the policy.", - "format": "byte" + "parameterOrder": [ + "bucket" + ], + "request": { + "$ref": "ManagedFolder" }, - "kind": { - "type": "string", - "description": "The kind of item this is. For policies, this is always storage#policy. This field is ignored on input.", - "default": "storage#policy" + "response": { + "$ref": "ManagedFolder" }, - "resourceId": { - "type": "string", - "description": "The ID of the resource to which this policy belongs. Will be of the form projects/_/buckets/bucket for buckets, and projects/_/buckets/bucket/objects/object for objects. A specific generation may be specified by appending #generationNumber to the end of the object name, e.g. projects/_/buckets/my-bucket/objects/data.txt#17. The current generation can be denoted with #0. This field is ignored on input." + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "list": { + "id": "storage.managedFolders.list", + "path": "b/{bucket}/managedFolders", + "httpMethod": "GET", + "description": "Lists managed folders in the given bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the bucket containing the managed folder.", + "required": true, + "location": "path" + }, + "pageSize": { + "type": "integer", + "description": "Maximum number of items return in a single page of responses.", + "format": "int32", + "minimum": "0", + "location": "query" + }, + "pageToken": { + "type": "string", + "description": "A previously-returned page token representing part of the larger set of results to view.", + "location": "query" + }, + "prefix": { + "type": "string", + "description": "The managed folder name/path prefix to filter the output list of results.", + "location": "query" + } }, - "version": { - "type": "integer", - "description": "The IAM policy format version.", - "format": "int32" - } - } - }, - "RewriteResponse": { - "id": "RewriteResponse", - "type": "object", - "description": "A rewrite response.", - "properties": { - "done": { - "type": "boolean", - "description": "true if the copy is finished; otherwise, false if the copy is in progress. This property is always present in the response." - }, - "kind": { - "type": "string", - "description": "The kind of item this is.", - "default": "storage#rewriteResponse" + "parameterOrder": [ + "bucket" + ], + "response": { + "$ref": "ManagedFolders" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "setIamPolicy": { + "id": "storage.managedFolders.setIamPolicy", + "path": "b/{bucket}/managedFolders/{managedFolder}/iam", + "httpMethod": "PUT", + "description": "Updates an IAM policy for the specified managed folder.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the bucket containing the managed folder.", + "required": true, + "location": "path" + }, + "managedFolder": { + "type": "string", + "description": "The managed folder name/path.", + "required": true, + "location": "path" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "objectSize": { - "type": "string", - "description": "The total size of the object being copied in bytes. This property is always present in the response.", - "format": "int64" + "parameterOrder": [ + "bucket", + "managedFolder" + ], + "request": { + "$ref": "Policy" }, - "resource": { - "$ref": "Object", - "description": "A resource containing the metadata for the copied-to object. This property is present in the response only when copying completes." + "response": { + "$ref": "Policy" }, - "rewriteToken": { - "type": "string", - "description": "A token to use in subsequent requests to continue copying data. This token is present in the response only when there is more data to copy." + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "testIamPermissions": { + "id": "storage.managedFolders.testIamPermissions", + "path": "b/{bucket}/managedFolders/{managedFolder}/iam/testPermissions", + "httpMethod": "GET", + "description": "Tests a set of permissions on the given managed folder to see which, if any, are held by the caller.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the bucket containing the managed folder.", + "required": true, + "location": "path" + }, + "managedFolder": { + "type": "string", + "description": "The managed folder name/path.", + "required": true, + "location": "path" + }, + "permissions": { + "type": "string", + "description": "Permissions to test.", + "required": true, + "repeated": true, + "location": "query" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "totalBytesRewritten": { - "type": "string", - "description": "The total bytes written so far, which can be used to provide a waiting user with a progress indicator. This property is always present in the response.", - "format": "int64" - } + "parameterOrder": [ + "bucket", + "managedFolder", + "permissions" + ], + "response": { + "$ref": "TestIamPermissionsResponse" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] } - }, - "ServiceAccount": { - "id": "ServiceAccount", - "type": "object", - "description": "A subscription to receive Google PubSub notifications.", - "properties": { - "email_address": { - "type": "string", - "description": "The ID of the notification." + } + }, + "notifications": { + "methods": { + "delete": { + "id": "storage.notifications.delete", + "path": "b/{bucket}/notificationConfigs/{notification}", + "httpMethod": "DELETE", + "description": "Permanently deletes a notification subscription.", + "parameters": { + "bucket": { + "type": "string", + "description": "The parent bucket of the notification.", + "required": true, + "location": "path" + }, + "notification": { + "type": "string", + "description": "ID of the notification to delete.", + "required": true, + "location": "path" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "kind": { - "type": "string", - "description": "The kind of item this is. For notifications, this is always storage#notification.", - "default": "storage#serviceAccount" - } - } - }, - "TestIamPermissionsResponse": { - "id": "TestIamPermissionsResponse", - "type": "object", - "description": "A storage.(buckets|objects).testIamPermissions response.", - "properties": { - "kind": { - "type": "string", - "description": "The kind of item this is.", - "default": "storage#testIamPermissionsResponse" + "parameterOrder": [ + "bucket", + "notification" + ], + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "get": { + "id": "storage.notifications.get", + "path": "b/{bucket}/notificationConfigs/{notification}", + "httpMethod": "GET", + "description": "View a notification configuration.", + "parameters": { + "bucket": { + "type": "string", + "description": "The parent bucket of the notification.", + "required": true, + "location": "path" + }, + "notification": { + "type": "string", + "description": "Notification ID", + "required": true, + "location": "path" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "permissions": { - "type": "array", - "description": "The permissions held by the caller. Permissions are always of the format storage.resource.capability, where resource is one of buckets or objects. The supported permissions are as follows: \n- storage.buckets.delete \u2014 Delete bucket. \n- storage.buckets.get \u2014 Read bucket metadata. \n- storage.buckets.getIamPolicy \u2014 Read bucket IAM policy. \n- storage.buckets.create \u2014 Create bucket. \n- storage.buckets.list \u2014 List buckets. \n- storage.buckets.setIamPolicy \u2014 Update bucket IAM policy. \n- storage.buckets.update \u2014 Update bucket metadata. \n- storage.objects.delete \u2014 Delete object. \n- storage.objects.get \u2014 Read object data and metadata. \n- storage.objects.getIamPolicy \u2014 Read object IAM policy. \n- storage.objects.create \u2014 Create object. \n- storage.objects.list \u2014 List objects. \n- storage.objects.setIamPolicy \u2014 Update object IAM policy. \n- storage.objects.update \u2014 Update object metadata.", - "items": { - "type": "string" + "parameterOrder": [ + "bucket", + "notification" + ], + "response": { + "$ref": "Notification" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "insert": { + "id": "storage.notifications.insert", + "path": "b/{bucket}/notificationConfigs", + "httpMethod": "POST", + "description": "Creates a notification subscription for a given bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "The parent bucket of the notification.", + "required": true, + "location": "path" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" } - } + }, + "parameterOrder": [ + "bucket" + ], + "request": { + "$ref": "Notification" + }, + "response": { + "$ref": "Notification" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "list": { + "id": "storage.notifications.list", + "path": "b/{bucket}/notificationConfigs", + "httpMethod": "GET", + "description": "Retrieves a list of notification subscriptions for a given bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a Google Cloud Storage bucket.", + "required": true, + "location": "path" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } + }, + "parameterOrder": [ + "bucket" + ], + "response": { + "$ref": "Notifications" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] } } }, - "resources": { - "bucketAccessControls": { - "methods": { - "delete": { - "id": "storage.bucketAccessControls.delete", - "path": "b/{bucket}/acl/{entity}", - "httpMethod": "DELETE", - "description": "Permanently deletes the ACL entry for the specified entity on the specified bucket.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "entity": { - "type": "string", - "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", - "required": true, - "location": "path" + "objectAccessControls": { + "methods": { + "delete": { + "id": "storage.objectAccessControls.delete", + "path": "b/{bucket}/o/{object}/acl/{entity}", + "httpMethod": "DELETE", + "description": "Permanently deletes the ACL entry for the specified entity on the specified object.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "entity": { + "type": "string", + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "required": true, + "location": "path" }, - "parameterOrder": [ - "bucket", - "entity" - ], - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] + "generation": { + "type": "string", + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query" + }, + "object": { + "type": "string", + "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", + "required": true, + "location": "path" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "get": { - "id": "storage.bucketAccessControls.get", - "path": "b/{bucket}/acl/{entity}", - "httpMethod": "GET", - "description": "Returns the ACL entry for the specified entity on the specified bucket.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "entity": { - "type": "string", - "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", - "required": true, - "location": "path" + "parameterOrder": [ + "bucket", + "object", + "entity" + ], + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "get": { + "id": "storage.objectAccessControls.get", + "path": "b/{bucket}/o/{object}/acl/{entity}", + "httpMethod": "GET", + "description": "Returns the ACL entry for the specified entity on the specified object.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "entity": { + "type": "string", + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "required": true, + "location": "path" }, - "parameterOrder": [ - "bucket", - "entity" - ], - "response": { - "$ref": "BucketAccessControl" + "generation": { + "type": "string", + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] - }, - "insert": { - "id": "storage.bucketAccessControls.insert", - "path": "b/{bucket}/acl", - "httpMethod": "POST", - "description": "Creates a new ACL entry on the specified bucket.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" + "object": { + "type": "string", + "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", + "required": true, + "location": "path" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } + }, + "parameterOrder": [ + "bucket", + "object", + "entity" + ], + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "insert": { + "id": "storage.objectAccessControls.insert", + "path": "b/{bucket}/o/{object}/acl", + "httpMethod": "POST", + "description": "Creates a new ACL entry on the specified object.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" }, - "parameterOrder": [ - "bucket" - ], - "request": { - "$ref": "BucketAccessControl" + "generation": { + "type": "string", + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query" }, - "response": { - "$ref": "BucketAccessControl" + "object": { + "type": "string", + "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", + "required": true, + "location": "path" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "list": { - "id": "storage.bucketAccessControls.list", - "path": "b/{bucket}/acl", - "httpMethod": "GET", - "description": "Retrieves ACL entries on the specified bucket.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" + "parameterOrder": [ + "bucket", + "object" + ], + "request": { + "$ref": "ObjectAccessControl" + }, + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "list": { + "id": "storage.objectAccessControls.list", + "path": "b/{bucket}/o/{object}/acl", + "httpMethod": "GET", + "description": "Retrieves ACL entries on the specified object.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "generation": { + "type": "string", + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query" }, - "parameterOrder": [ - "bucket" - ], - "response": { - "$ref": "BucketAccessControls" + "object": { + "type": "string", + "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", + "required": true, + "location": "path" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "patch": { - "id": "storage.bucketAccessControls.patch", - "path": "b/{bucket}/acl/{entity}", - "httpMethod": "PATCH", - "description": "Patches an ACL entry on the specified bucket.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "entity": { - "type": "string", - "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", - "required": true, - "location": "path" + "parameterOrder": [ + "bucket", + "object" + ], + "response": { + "$ref": "ObjectAccessControls" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "patch": { + "id": "storage.objectAccessControls.patch", + "path": "b/{bucket}/o/{object}/acl/{entity}", + "httpMethod": "PATCH", + "description": "Patches an ACL entry on the specified object.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "entity": { + "type": "string", + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "required": true, + "location": "path" }, - "parameterOrder": [ - "bucket", - "entity" - ], - "request": { - "$ref": "BucketAccessControl" + "generation": { + "type": "string", + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query" }, - "response": { - "$ref": "BucketAccessControl" + "object": { + "type": "string", + "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", + "required": true, + "location": "path" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "update": { - "id": "storage.bucketAccessControls.update", - "path": "b/{bucket}/acl/{entity}", - "httpMethod": "PUT", - "description": "Updates an ACL entry on the specified bucket.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "entity": { - "type": "string", - "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", - "required": true, - "location": "path" + "parameterOrder": [ + "bucket", + "object", + "entity" + ], + "request": { + "$ref": "ObjectAccessControl" + }, + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "update": { + "id": "storage.objectAccessControls.update", + "path": "b/{bucket}/o/{object}/acl/{entity}", + "httpMethod": "PUT", + "description": "Updates an ACL entry on the specified object.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of a bucket.", + "required": true, + "location": "path" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "entity": { + "type": "string", + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "required": true, + "location": "path" }, - "parameterOrder": [ - "bucket", - "entity" - ], - "request": { - "$ref": "BucketAccessControl" + "generation": { + "type": "string", + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query" }, - "response": { - "$ref": "BucketAccessControl" + "object": { + "type": "string", + "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", + "required": true, + "location": "path" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] - } + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } + }, + "parameterOrder": [ + "bucket", + "object", + "entity" + ], + "request": { + "$ref": "ObjectAccessControl" + }, + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] } - }, - "buckets": { - "methods": { - "delete": { - "id": "storage.buckets.delete", - "path": "b/{bucket}", - "httpMethod": "DELETE", - "description": "Permanently deletes an empty bucket.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "ifMetagenerationMatch": { - "type": "string", - "description": "If set, only deletes the bucket if its metageneration matches this value.", - "format": "int64", - "location": "query" - }, - "ifMetagenerationNotMatch": { - "type": "string", - "description": "If set, only deletes the bucket if its metageneration does not match this value.", - "format": "int64", - "location": "query" + } + }, + "objects": { + "methods": { + "compose": { + "id": "storage.objects.compose", + "path": "b/{destinationBucket}/o/{destinationObject}/compose", + "httpMethod": "POST", + "description": "Concatenates a list of existing objects into a new object in the same bucket.", + "parameters": { + "destinationBucket": { + "type": "string", + "description": "Name of the bucket containing the source objects. The destination object is stored in this bucket.", + "required": true, + "location": "path" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "destinationObject": { + "type": "string", + "description": "Name of the new object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", + "required": true, + "location": "path" }, - "parameterOrder": [ - "bucket" - ], - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_write" - ] - }, - "get": { - "id": "storage.buckets.get", - "path": "b/{bucket}", - "httpMethod": "GET", - "description": "Returns metadata for the specified bucket.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "ifMetagenerationMatch": { - "type": "string", - "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration matches the given value.", - "format": "int64", - "location": "query" - }, - "ifMetagenerationNotMatch": { - "type": "string", - "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration does not match the given value.", - "format": "int64", - "location": "query" - }, - "projection": { - "type": "string", - "description": "Set of properties to return. Defaults to noAcl.", - "enum": [ - "full", - "noAcl" - ], - "enumDescriptions": [ - "Include all properties.", - "Omit owner, acl and defaultObjectAcl properties." - ], - "location": "query" - }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "destinationPredefinedAcl": { + "type": "string", + "description": "Apply a predefined set of access controls to the destination object.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query" }, - "parameterOrder": [ - "bucket" - ], - "response": { - "$ref": "Bucket" - }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_only", - "https://www.googleapis.com/auth/devstorage.read_write" - ] - }, - "getIamPolicy": { - "id": "storage.buckets.getIamPolicy", - "path": "b/{bucket}/iam", - "httpMethod": "GET", - "description": "Returns an IAM policy for the specified bucket.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "optionsRequestedPolicyVersion": { - "type": "integer", - "description": "The IAM policy format version to be returned. If the optionsRequestedPolicyVersion is for an older version that doesn't support part of the requested IAM policy, the request fails.", - "format": "int32", - "minimum": "1", - "location": "query" + "ifGenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "ifMetagenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + "format": "int64", + "location": "query" }, - "parameterOrder": [ - "bucket" - ], - "response": { - "$ref": "Policy" + "kmsKeyName": { + "type": "string", + "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", + "location": "query" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "insert": { - "id": "storage.buckets.insert", - "path": "b", - "httpMethod": "POST", - "description": "Creates a new bucket.", - "parameters": { - "predefinedAcl": { - "type": "string", - "description": "Apply a predefined set of access controls to this bucket.", - "enum": [ - "authenticatedRead", - "private", - "projectPrivate", - "publicRead", - "publicReadWrite" - ], - "enumDescriptions": [ - "Project team owners get OWNER access, and allAuthenticatedUsers get READER access.", - "Project team owners get OWNER access.", - "Project team members get access according to their roles.", - "Project team owners get OWNER access, and allUsers get READER access.", - "Project team owners get OWNER access, and allUsers get WRITER access." - ], - "location": "query" - }, - "predefinedDefaultObjectAcl": { - "type": "string", - "description": "Apply a predefined set of default object access controls to this bucket.", - "enum": [ - "authenticatedRead", - "bucketOwnerFullControl", - "bucketOwnerRead", - "private", - "projectPrivate", - "publicRead" - ], - "enumDescriptions": [ - "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", - "Object owner gets OWNER access, and project team owners get OWNER access.", - "Object owner gets OWNER access, and project team owners get READER access.", - "Object owner gets OWNER access.", - "Object owner gets OWNER access, and project team members get access according to their roles.", - "Object owner gets OWNER access, and allUsers get READER access." - ], - "location": "query" - }, - "project": { - "type": "string", - "description": "A valid API project identifier.", - "required": true, - "location": "query" - }, - "projection": { - "type": "string", - "description": "Set of properties to return. Defaults to noAcl, unless the bucket resource specifies acl or defaultObjectAcl properties, when it defaults to full.", - "enum": [ - "full", - "noAcl" - ], - "enumDescriptions": [ - "Include all properties.", - "Omit owner, acl and defaultObjectAcl properties." - ], - "location": "query" - }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request.", - "location": "query" - } - }, - "parameterOrder": [ - "project" - ], - "request": { - "$ref": "Bucket" + "parameterOrder": [ + "destinationBucket", + "destinationObject" + ], + "request": { + "$ref": "ComposeRequest" + }, + "response": { + "$ref": "Object" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "copy": { + "id": "storage.objects.copy", + "path": "b/{sourceBucket}/o/{sourceObject}/copyTo/b/{destinationBucket}/o/{destinationObject}", + "httpMethod": "POST", + "description": "Copies a source object to a destination object. Optionally overrides metadata.", + "parameters": { + "destinationBucket": { + "type": "string", + "description": "Name of the bucket in which to store the new object. Overrides the provided object metadata's bucket value, if any.For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", + "required": true, + "location": "path" }, - "response": { - "$ref": "Bucket" + "destinationKmsKeyName": { + "type": "string", + "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", + "location": "query" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_write" - ] - }, - "list": { - "id": "storage.buckets.list", - "path": "b", - "httpMethod": "GET", - "description": "Retrieves a list of buckets for a given project.", - "parameters": { - "maxResults": { - "type": "integer", - "description": "Maximum number of buckets to return in a single response. The service will use this parameter or 1,000 items, whichever is smaller.", - "default": "1000", - "format": "uint32", - "minimum": "0", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "A previously-returned page token representing part of the larger set of results to view.", - "location": "query" - }, - "prefix": { - "type": "string", - "description": "Filter results to buckets whose names begin with this prefix.", - "location": "query" - }, - "project": { - "type": "string", - "description": "A valid API project identifier.", - "required": true, - "location": "query" - }, - "projection": { - "type": "string", - "description": "Set of properties to return. Defaults to noAcl.", - "enum": [ - "full", - "noAcl" - ], - "enumDescriptions": [ - "Include all properties.", - "Omit owner, acl and defaultObjectAcl properties." - ], - "location": "query" - }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request.", - "location": "query" - } + "destinationObject": { + "type": "string", + "description": "Name of the new object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any.", + "required": true, + "location": "path" }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "Buckets" - }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_only", - "https://www.googleapis.com/auth/devstorage.read_write" - ] - }, - "lockRetentionPolicy": { - "id": "storage.buckets.lockRetentionPolicy", - "path": "b/{bucket}/lockRetentionPolicy", - "httpMethod": "POST", - "description": "Locks retention policy on a bucket.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "ifMetagenerationMatch": { - "type": "string", - "description": "Makes the operation conditional on whether bucket's current metageneration matches the given value.", - "required": true, - "format": "int64", - "location": "query" + "destinationPredefinedAcl": { + "type": "string", + "description": "Apply a predefined set of access controls to the destination object.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "ifGenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the destination object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query" }, - "parameterOrder": [ - "bucket", - "ifMetagenerationMatch" - ], - "response": { - "$ref": "Bucket" + "ifGenerationNotMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the destination object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_write" - ] - }, - "patch": { - "id": "storage.buckets.patch", - "path": "b/{bucket}", - "httpMethod": "PATCH", - "description": "Patches a bucket. Changes to the bucket will be readable immediately after writing, but configuration changes may take time to propagate.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "ifMetagenerationMatch": { - "type": "string", - "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration matches the given value.", - "format": "int64", - "location": "query" - }, - "ifMetagenerationNotMatch": { - "type": "string", - "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration does not match the given value.", - "format": "int64", - "location": "query" - }, - "predefinedAcl": { - "type": "string", - "description": "Apply a predefined set of access controls to this bucket.", - "enum": [ - "authenticatedRead", - "private", - "projectPrivate", - "publicRead", - "publicReadWrite" - ], - "enumDescriptions": [ - "Project team owners get OWNER access, and allAuthenticatedUsers get READER access.", - "Project team owners get OWNER access.", - "Project team members get access according to their roles.", - "Project team owners get OWNER access, and allUsers get READER access.", - "Project team owners get OWNER access, and allUsers get WRITER access." - ], - "location": "query" - }, - "predefinedDefaultObjectAcl": { - "type": "string", - "description": "Apply a predefined set of default object access controls to this bucket.", - "enum": [ - "authenticatedRead", - "bucketOwnerFullControl", - "bucketOwnerRead", - "private", - "projectPrivate", - "publicRead" - ], - "enumDescriptions": [ - "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", - "Object owner gets OWNER access, and project team owners get OWNER access.", - "Object owner gets OWNER access, and project team owners get READER access.", - "Object owner gets OWNER access.", - "Object owner gets OWNER access, and project team members get access according to their roles.", - "Object owner gets OWNER access, and allUsers get READER access." - ], - "location": "query" - }, - "projection": { - "type": "string", - "description": "Set of properties to return. Defaults to full.", - "enum": [ - "full", - "noAcl" - ], - "enumDescriptions": [ - "Include all properties.", - "Omit owner, acl and defaultObjectAcl properties." - ], - "location": "query" - }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "ifMetagenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the destination object's current metageneration matches the given value.", + "format": "int64", + "location": "query" }, - "parameterOrder": [ - "bucket" - ], - "request": { - "$ref": "Bucket" + "ifMetagenerationNotMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the destination object's current metageneration does not match the given value.", + "format": "int64", + "location": "query" }, - "response": { - "$ref": "Bucket" + "ifSourceGenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the source object's current generation matches the given value.", + "format": "int64", + "location": "query" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] - }, - "setIamPolicy": { - "id": "storage.buckets.setIamPolicy", - "path": "b/{bucket}/iam", - "httpMethod": "PUT", - "description": "Updates an IAM policy for the specified bucket.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" + "ifSourceGenerationNotMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the source object's current generation does not match the given value.", + "format": "int64", + "location": "query" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "ifSourceMetagenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the source object's current metageneration matches the given value.", + "format": "int64", + "location": "query" }, - "parameterOrder": [ - "bucket" - ], - "request": { - "$ref": "Policy" + "ifSourceMetagenerationNotMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the source object's current metageneration does not match the given value.", + "format": "int64", + "location": "query" + }, + "projection": { + "type": "string", + "description": "Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query" }, - "response": { - "$ref": "Policy" + "sourceBucket": { + "type": "string", + "description": "Name of the bucket in which to find the source object.", + "required": true, + "location": "path" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] - }, - "testIamPermissions": { - "id": "storage.buckets.testIamPermissions", - "path": "b/{bucket}/iam/testPermissions", - "httpMethod": "GET", - "description": "Tests a set of permissions on the given bucket to see which, if any, are held by the caller.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "permissions": { - "type": "string", - "description": "Permissions to test.", - "required": true, - "repeated": true, - "location": "query" + "sourceGeneration": { + "type": "string", + "description": "If present, selects a specific revision of the source object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "sourceObject": { + "type": "string", + "description": "Name of the source object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", + "required": true, + "location": "path" }, - "parameterOrder": [ - "bucket", - "permissions" - ], - "response": { - "$ref": "TestIamPermissionsResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_only", - "https://www.googleapis.com/auth/devstorage.read_write" - ] + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "update": { - "id": "storage.buckets.update", - "path": "b/{bucket}", - "httpMethod": "PUT", - "description": "Updates a bucket. Changes to the bucket will be readable immediately after writing, but configuration changes may take time to propagate.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "ifMetagenerationMatch": { - "type": "string", - "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration matches the given value.", - "format": "int64", - "location": "query" - }, - "ifMetagenerationNotMatch": { - "type": "string", - "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration does not match the given value.", - "format": "int64", - "location": "query" - }, - "predefinedAcl": { - "type": "string", - "description": "Apply a predefined set of access controls to this bucket.", - "enum": [ - "authenticatedRead", - "private", - "projectPrivate", - "publicRead", - "publicReadWrite" - ], - "enumDescriptions": [ - "Project team owners get OWNER access, and allAuthenticatedUsers get READER access.", - "Project team owners get OWNER access.", - "Project team members get access according to their roles.", - "Project team owners get OWNER access, and allUsers get READER access.", - "Project team owners get OWNER access, and allUsers get WRITER access." - ], - "location": "query" - }, - "predefinedDefaultObjectAcl": { - "type": "string", - "description": "Apply a predefined set of default object access controls to this bucket.", - "enum": [ - "authenticatedRead", - "bucketOwnerFullControl", - "bucketOwnerRead", - "private", - "projectPrivate", - "publicRead" - ], - "enumDescriptions": [ - "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", - "Object owner gets OWNER access, and project team owners get OWNER access.", - "Object owner gets OWNER access, and project team owners get READER access.", - "Object owner gets OWNER access.", - "Object owner gets OWNER access, and project team members get access according to their roles.", - "Object owner gets OWNER access, and allUsers get READER access." - ], - "location": "query" - }, - "projection": { - "type": "string", - "description": "Set of properties to return. Defaults to full.", - "enum": [ - "full", - "noAcl" - ], - "enumDescriptions": [ - "Include all properties.", - "Omit owner, acl and defaultObjectAcl properties." - ], - "location": "query" - }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "parameterOrder": [ + "sourceBucket", + "sourceObject", + "destinationBucket", + "destinationObject" + ], + "request": { + "$ref": "Object" + }, + "response": { + "$ref": "Object" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "delete": { + "id": "storage.objects.delete", + "path": "b/{bucket}/o/{object}", + "httpMethod": "DELETE", + "description": "Deletes an object and its metadata. Deletions are permanent if versioning is not enabled for the bucket, or if the generation parameter is used.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the bucket in which the object resides.", + "required": true, + "location": "path" }, - "parameterOrder": [ - "bucket" - ], - "request": { - "$ref": "Bucket" + "generation": { + "type": "string", + "description": "If present, permanently deletes a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query" }, - "response": { - "$ref": "Bucket" + "ifGenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] - } - } - }, - "channels": { - "methods": { - "stop": { - "id": "storage.channels.stop", - "path": "channels/stop", - "httpMethod": "POST", - "description": "Stop watching resources through this channel", - "request": { - "$ref": "Channel", - "parameterName": "resource" - }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_only", - "https://www.googleapis.com/auth/devstorage.read_write" - ] - } - } - }, - "defaultObjectAccessControls": { - "methods": { - "delete": { - "id": "storage.defaultObjectAccessControls.delete", - "path": "b/{bucket}/defaultObjectAcl/{entity}", - "httpMethod": "DELETE", - "description": "Permanently deletes the default object ACL entry for the specified entity on the specified bucket.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "entity": { - "type": "string", - "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", - "required": true, - "location": "path" + "ifGenerationNotMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "ifMetagenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + "format": "int64", + "location": "query" }, - "parameterOrder": [ - "bucket", - "entity" - ], - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] + "ifMetagenerationNotMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + "format": "int64", + "location": "query" + }, + "object": { + "type": "string", + "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", + "required": true, + "location": "path" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "get": { - "id": "storage.defaultObjectAccessControls.get", - "path": "b/{bucket}/defaultObjectAcl/{entity}", - "httpMethod": "GET", - "description": "Returns the default object ACL entry for the specified entity on the specified bucket.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "entity": { - "type": "string", - "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", - "required": true, - "location": "path" + "parameterOrder": [ + "bucket", + "object" + ], + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "get": { + "id": "storage.objects.get", + "path": "b/{bucket}/o/{object}", + "httpMethod": "GET", + "description": "Retrieves an object or its metadata.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the bucket in which the object resides.", + "required": true, + "location": "path" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "generation": { + "type": "string", + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query" }, - "parameterOrder": [ - "bucket", - "entity" - ], - "response": { - "$ref": "ObjectAccessControl" + "ifGenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] - }, - "insert": { - "id": "storage.defaultObjectAccessControls.insert", - "path": "b/{bucket}/defaultObjectAcl", - "httpMethod": "POST", - "description": "Creates a new default object ACL entry on the specified bucket.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" + "ifGenerationNotMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "ifMetagenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + "format": "int64", + "location": "query" }, - "parameterOrder": [ - "bucket" - ], - "request": { - "$ref": "ObjectAccessControl" + "ifMetagenerationNotMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + "format": "int64", + "location": "query" }, - "response": { - "$ref": "ObjectAccessControl" + "object": { + "type": "string", + "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", + "required": true, + "location": "path" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] + "projection": { + "type": "string", + "description": "Set of properties to return. Defaults to noAcl.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + }, + "softDeleted": { + "type": "boolean", + "description": "If true, only soft-deleted object versions will be listed. The default is false. For more information, see Soft Delete.", + "location": "query" + } }, - "list": { - "id": "storage.defaultObjectAccessControls.list", - "path": "b/{bucket}/defaultObjectAcl", - "httpMethod": "GET", - "description": "Retrieves default object ACL entries on the specified bucket.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "ifMetagenerationMatch": { - "type": "string", - "description": "If present, only return default ACL listing if the bucket's current metageneration matches this value.", - "format": "int64", - "location": "query" - }, - "ifMetagenerationNotMatch": { - "type": "string", - "description": "If present, only return default ACL listing if the bucket's current metageneration does not match the given value.", - "format": "int64", - "location": "query" + "parameterOrder": [ + "bucket", + "object" + ], + "response": { + "$ref": "Object" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ], + "supportsMediaDownload": true, + "useMediaDownloadService": true + }, + "getIamPolicy": { + "id": "storage.objects.getIamPolicy", + "path": "b/{bucket}/o/{object}/iam", + "httpMethod": "GET", + "description": "Returns an IAM policy for the specified object.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the bucket in which the object resides.", + "required": true, + "location": "path" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "generation": { + "type": "string", + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query" }, - "parameterOrder": [ - "bucket" - ], - "response": { - "$ref": "ObjectAccessControls" + "object": { + "type": "string", + "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", + "required": true, + "location": "path" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "patch": { - "id": "storage.defaultObjectAccessControls.patch", - "path": "b/{bucket}/defaultObjectAcl/{entity}", - "httpMethod": "PATCH", - "description": "Patches a default object ACL entry on the specified bucket.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "entity": { - "type": "string", - "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", - "required": true, - "location": "path" + "parameterOrder": [ + "bucket", + "object" + ], + "response": { + "$ref": "Policy" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "insert": { + "id": "storage.objects.insert", + "path": "b/{bucket}/o", + "httpMethod": "POST", + "description": "Stores a new object and metadata.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the bucket in which to store the new object. Overrides the provided object metadata's bucket value, if any.", + "required": true, + "location": "path" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "contentEncoding": { + "type": "string", + "description": "If set, sets the contentEncoding property of the final object to this value. Setting this parameter is equivalent to setting the contentEncoding metadata property. This can be useful when uploading an object with uploadType=media to indicate the encoding of the content being uploaded.", + "location": "query" }, - "parameterOrder": [ - "bucket", - "entity" - ], - "request": { - "$ref": "ObjectAccessControl" + "ifGenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query" }, - "response": { - "$ref": "ObjectAccessControl" + "ifGenerationNotMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] - }, - "update": { - "id": "storage.defaultObjectAccessControls.update", - "path": "b/{bucket}/defaultObjectAcl/{entity}", - "httpMethod": "PUT", - "description": "Updates a default object ACL entry on the specified bucket.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "entity": { - "type": "string", - "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", - "required": true, - "location": "path" + "ifMetagenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + "format": "int64", + "location": "query" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "ifMetagenerationNotMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + "format": "int64", + "location": "query" }, - "parameterOrder": [ - "bucket", - "entity" - ], - "request": { - "$ref": "ObjectAccessControl" + "kmsKeyName": { + "type": "string", + "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", + "location": "query" }, - "response": { - "$ref": "ObjectAccessControl" + "name": { + "type": "string", + "description": "Name of the object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", + "location": "query" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] - } - } - }, - "notifications": { - "methods": { - "delete": { - "id": "storage.notifications.delete", - "path": "b/{bucket}/notificationConfigs/{notification}", - "httpMethod": "DELETE", - "description": "Permanently deletes a notification subscription.", - "parameters": { - "bucket": { - "type": "string", - "description": "The parent bucket of the notification.", - "required": true, - "location": "path" - }, - "notification": { - "type": "string", - "description": "ID of the notification to delete.", - "required": true, - "location": "path" + "predefinedAcl": { + "type": "string", + "description": "Apply a predefined set of access controls to this object.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "projection": { + "type": "string", + "description": "Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query" }, - "parameterOrder": [ - "bucket", - "notification" - ], - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_write" - ] + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "get": { - "id": "storage.notifications.get", - "path": "b/{bucket}/notificationConfigs/{notification}", - "httpMethod": "GET", - "description": "View a notification configuration.", - "parameters": { - "bucket": { - "type": "string", - "description": "The parent bucket of the notification.", - "required": true, - "location": "path" - }, - "notification": { - "type": "string", - "description": "Notification ID", - "required": true, - "location": "path" - }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" + "parameterOrder": [ + "bucket" + ], + "request": { + "$ref": "Object" + }, + "response": { + "$ref": "Object" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ], + "supportsMediaUpload": true, + "mediaUpload": { + "accept": [ + "*/*" + ], + "protocols": { + "simple": { + "multipart": true, + "path": "/upload/storage/v1/b/{bucket}/o" + }, + "resumable": { + "multipart": true, + "path": "/resumable/upload/storage/v1/b/{bucket}/o" } + } + } + }, + "list": { + "id": "storage.objects.list", + "path": "b/{bucket}/o", + "httpMethod": "GET", + "description": "Retrieves a list of objects matching the criteria.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the bucket in which to look for objects.", + "required": true, + "location": "path" }, - "parameterOrder": [ - "bucket", - "notification" - ], - "response": { - "$ref": "Notification" - }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_only", - "https://www.googleapis.com/auth/devstorage.read_write" - ] - }, - "insert": { - "id": "storage.notifications.insert", - "path": "b/{bucket}/notificationConfigs", - "httpMethod": "POST", - "description": "Creates a notification subscription for a given bucket.", - "parameters": { - "bucket": { - "type": "string", - "description": "The parent bucket of the notification.", - "required": true, - "location": "path" + "delimiter": { + "type": "string", + "description": "Returns results in a directory-like mode. items will contain only objects whose names, aside from the prefix, do not contain delimiter. Objects whose names, aside from the prefix, contain delimiter will have their name, truncated after the delimiter, returned in prefixes. Duplicate prefixes are omitted.", + "location": "query" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "endOffset": { + "type": "string", + "description": "Filter results to objects whose names are lexicographically before endOffset. If startOffset is also set, the objects listed will have names between startOffset (inclusive) and endOffset (exclusive).", + "location": "query" + }, + "includeTrailingDelimiter": { + "type": "boolean", + "description": "If true, objects that end in exactly one instance of delimiter will have their metadata included in items in addition to prefixes.", + "location": "query" + }, + "maxResults": { + "type": "integer", + "description": "Maximum number of items plus prefixes to return in a single page of responses. As duplicate prefixes are omitted, fewer total results may be returned than requested. The service will use this parameter or 1,000 items, whichever is smaller.", + "default": "1000", + "format": "uint32", + "minimum": "0", + "location": "query" + }, + "pageToken": { + "type": "string", + "description": "A previously-returned page token representing part of the larger set of results to view.", + "location": "query" }, - "parameterOrder": [ - "bucket" - ], - "request": { - "$ref": "Notification" + "prefix": { + "type": "string", + "description": "Filter results to objects whose names begin with this prefix.", + "location": "query" + }, + "projection": { + "type": "string", + "description": "Set of properties to return. Defaults to noAcl.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query" }, - "response": { - "$ref": "Notification" + "startOffset": { + "type": "string", + "description": "Filter results to objects whose names are lexicographically equal to or after startOffset. If endOffset is also set, the objects listed will have names between startOffset (inclusive) and endOffset (exclusive).", + "location": "query" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_write" - ] + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + }, + "versions": { + "type": "boolean", + "description": "If true, lists all versions of an object as distinct results. The default is false. For more information, see Object Versioning.", + "location": "query" + }, + "matchGlob": { + "type": "string", + "description": "Filter results to objects and prefixes that match this glob pattern.", + "location": "query" + }, + "softDeleted": { + "type": "boolean", + "description": "If true, only soft-deleted object versions will be listed. The default is false. For more information, see Soft Delete.", + "location": "query" + }, + "includeFoldersAsPrefixes": { + "type": "boolean", + "description": "Only applicable if delimiter is set to '/'. If true, will also include folders and managed folders (besides objects) in the returned prefixes.", + "location": "query" + } }, - "list": { - "id": "storage.notifications.list", - "path": "b/{bucket}/notificationConfigs", - "httpMethod": "GET", - "description": "Retrieves a list of notification subscriptions for a given bucket.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a Google Cloud Storage bucket.", - "required": true, - "location": "path" + "parameterOrder": [ + "bucket" + ], + "response": { + "$ref": "Objects" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ], + "supportsSubscription": true + }, + "patch": { + "id": "storage.objects.patch", + "path": "b/{bucket}/o/{object}", + "httpMethod": "PATCH", + "description": "Patches an object's metadata.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the bucket in which the object resides.", + "required": true, + "location": "path" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "generation": { + "type": "string", + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query" }, - "parameterOrder": [ - "bucket" - ], - "response": { - "$ref": "Notifications" - }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_only", - "https://www.googleapis.com/auth/devstorage.read_write" - ] - } - } - }, - "objectAccessControls": { - "methods": { - "delete": { - "id": "storage.objectAccessControls.delete", - "path": "b/{bucket}/o/{object}/acl/{entity}", - "httpMethod": "DELETE", - "description": "Permanently deletes the ACL entry for the specified entity on the specified object.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "entity": { - "type": "string", - "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", - "required": true, - "location": "path" - }, - "generation": { - "type": "string", - "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", - "format": "int64", - "location": "query" - }, - "object": { - "type": "string", - "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", - "required": true, - "location": "path" + "ifGenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "ifGenerationNotMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query" }, - "parameterOrder": [ - "bucket", - "object", - "entity" - ], - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] - }, - "get": { - "id": "storage.objectAccessControls.get", - "path": "b/{bucket}/o/{object}/acl/{entity}", - "httpMethod": "GET", - "description": "Returns the ACL entry for the specified entity on the specified object.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "entity": { - "type": "string", - "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", - "required": true, - "location": "path" - }, - "generation": { - "type": "string", - "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", - "format": "int64", - "location": "query" - }, - "object": { - "type": "string", - "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", - "required": true, - "location": "path" + "ifMetagenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + "format": "int64", + "location": "query" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "ifMetagenerationNotMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + "format": "int64", + "location": "query" }, - "parameterOrder": [ - "bucket", - "object", - "entity" - ], - "response": { - "$ref": "ObjectAccessControl" + "overrideUnlockedRetention": { + "type": "boolean", + "description": "Must be true to remove the retention configuration, reduce its unlocked retention period, or change its mode from unlocked to locked.", + "location": "query" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] - }, - "insert": { - "id": "storage.objectAccessControls.insert", - "path": "b/{bucket}/o/{object}/acl", - "httpMethod": "POST", - "description": "Creates a new ACL entry on the specified object.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "generation": { - "type": "string", - "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", - "format": "int64", - "location": "query" - }, - "object": { - "type": "string", - "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", - "required": true, - "location": "path" + "object": { + "type": "string", + "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", + "required": true, + "location": "path" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "predefinedAcl": { + "type": "string", + "description": "Apply a predefined set of access controls to this object.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query" }, - "parameterOrder": [ - "bucket", - "object" - ], - "request": { - "$ref": "ObjectAccessControl" + "projection": { + "type": "string", + "description": "Set of properties to return. Defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request, for Requester Pays buckets.", + "location": "query" + } + }, + "parameterOrder": [ + "bucket", + "object" + ], + "request": { + "$ref": "Object" + }, + "response": { + "$ref": "Object" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "rewrite": { + "id": "storage.objects.rewrite", + "path": "b/{sourceBucket}/o/{sourceObject}/rewriteTo/b/{destinationBucket}/o/{destinationObject}", + "httpMethod": "POST", + "description": "Rewrites a source object to a destination object. Optionally overrides metadata.", + "parameters": { + "destinationBucket": { + "type": "string", + "description": "Name of the bucket in which to store the new object. Overrides the provided object metadata's bucket value, if any.", + "required": true, + "location": "path" + }, + "destinationKmsKeyName": { + "type": "string", + "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", + "location": "query" }, - "response": { - "$ref": "ObjectAccessControl" + "destinationObject": { + "type": "string", + "description": "Name of the new object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", + "required": true, + "location": "path" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] - }, - "list": { - "id": "storage.objectAccessControls.list", - "path": "b/{bucket}/o/{object}/acl", - "httpMethod": "GET", - "description": "Retrieves ACL entries on the specified object.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "generation": { - "type": "string", - "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", - "format": "int64", - "location": "query" - }, - "object": { - "type": "string", - "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", - "required": true, - "location": "path" + "destinationPredefinedAcl": { + "type": "string", + "description": "Apply a predefined set of access controls to the destination object.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "ifGenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query" }, - "parameterOrder": [ - "bucket", - "object" - ], - "response": { - "$ref": "ObjectAccessControls" + "ifGenerationNotMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] - }, - "patch": { - "id": "storage.objectAccessControls.patch", - "path": "b/{bucket}/o/{object}/acl/{entity}", - "httpMethod": "PATCH", - "description": "Patches an ACL entry on the specified object.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "entity": { - "type": "string", - "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", - "required": true, - "location": "path" - }, - "generation": { - "type": "string", - "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", - "format": "int64", - "location": "query" - }, - "object": { - "type": "string", - "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", - "required": true, - "location": "path" + "ifMetagenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the destination object's current metageneration matches the given value.", + "format": "int64", + "location": "query" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "ifMetagenerationNotMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the destination object's current metageneration does not match the given value.", + "format": "int64", + "location": "query" }, - "parameterOrder": [ - "bucket", - "object", - "entity" - ], - "request": { - "$ref": "ObjectAccessControl" + "ifSourceGenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the source object's current generation matches the given value.", + "format": "int64", + "location": "query" }, - "response": { - "$ref": "ObjectAccessControl" + "ifSourceGenerationNotMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the source object's current generation does not match the given value.", + "format": "int64", + "location": "query" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] - }, - "update": { - "id": "storage.objectAccessControls.update", - "path": "b/{bucket}/o/{object}/acl/{entity}", - "httpMethod": "PUT", - "description": "Updates an ACL entry on the specified object.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of a bucket.", - "required": true, - "location": "path" - }, - "entity": { - "type": "string", - "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", - "required": true, - "location": "path" - }, - "generation": { - "type": "string", - "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", - "format": "int64", - "location": "query" - }, - "object": { - "type": "string", - "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", - "required": true, - "location": "path" + "ifSourceMetagenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the source object's current metageneration matches the given value.", + "format": "int64", + "location": "query" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "ifSourceMetagenerationNotMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the source object's current metageneration does not match the given value.", + "format": "int64", + "location": "query" }, - "parameterOrder": [ - "bucket", - "object", - "entity" - ], - "request": { - "$ref": "ObjectAccessControl" + "maxBytesRewrittenPerCall": { + "type": "string", + "description": "The maximum number of bytes that will be rewritten per rewrite request. Most callers shouldn't need to specify this parameter - it is primarily in place to support testing. If specified the value must be an integral multiple of 1 MiB (1048576). Also, this only applies to requests where the source and destination span locations and/or storage classes. Finally, this value must not change across rewrite calls else you'll get an error that the rewriteToken is invalid.", + "format": "int64", + "location": "query" }, - "response": { - "$ref": "ObjectAccessControl" + "projection": { + "type": "string", + "description": "Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] - } - } - }, - "objects": { - "methods": { - "compose": { - "id": "storage.objects.compose", - "path": "b/{destinationBucket}/o/{destinationObject}/compose", - "httpMethod": "POST", - "description": "Concatenates a list of existing objects into a new object in the same bucket.", - "parameters": { - "destinationBucket": { - "type": "string", - "description": "Name of the bucket containing the source objects. The destination object is stored in this bucket.", - "required": true, - "location": "path" - }, - "destinationObject": { - "type": "string", - "description": "Name of the new object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", - "required": true, - "location": "path" - }, - "destinationPredefinedAcl": { - "type": "string", - "description": "Apply a predefined set of access controls to the destination object.", - "enum": [ - "authenticatedRead", - "bucketOwnerFullControl", - "bucketOwnerRead", - "private", - "projectPrivate", - "publicRead" - ], - "enumDescriptions": [ - "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", - "Object owner gets OWNER access, and project team owners get OWNER access.", - "Object owner gets OWNER access, and project team owners get READER access.", - "Object owner gets OWNER access.", - "Object owner gets OWNER access, and project team members get access according to their roles.", - "Object owner gets OWNER access, and allUsers get READER access." - ], - "location": "query" - }, - "ifGenerationMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", - "format": "int64", - "location": "query" - }, - "ifMetagenerationMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", - "format": "int64", - "location": "query" - }, - "kmsKeyName": { - "type": "string", - "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", - "location": "query" + "rewriteToken": { + "type": "string", + "description": "Include this field (from the previous rewrite response) on each rewrite request after the first one, until the rewrite response 'done' flag is true. Calls that provide a rewriteToken can omit all other request fields, but if included those fields must match the values provided in the first rewrite request.", + "location": "query" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "sourceBucket": { + "type": "string", + "description": "Name of the bucket in which to find the source object.", + "required": true, + "location": "path" }, - "parameterOrder": [ - "destinationBucket", - "destinationObject" - ], - "request": { - "$ref": "ComposeRequest" + "sourceGeneration": { + "type": "string", + "description": "If present, selects a specific revision of the source object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query" }, - "response": { - "$ref": "Object" + "sourceObject": { + "type": "string", + "description": "Name of the source object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", + "required": true, + "location": "path" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_write" - ] + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "copy": { - "id": "storage.objects.copy", - "path": "b/{sourceBucket}/o/{sourceObject}/copyTo/b/{destinationBucket}/o/{destinationObject}", - "httpMethod": "POST", - "description": "Copies a source object to a destination object. Optionally overrides metadata.", - "parameters": { - "destinationBucket": { - "type": "string", - "description": "Name of the bucket in which to store the new object. Overrides the provided object metadata's bucket value, if any.For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", - "required": true, - "location": "path" - }, - "destinationKmsKeyName": { - "type": "string", - "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", - "location": "query" - }, - "destinationObject": { - "type": "string", - "description": "Name of the new object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any.", - "required": true, - "location": "path" - }, - "destinationPredefinedAcl": { - "type": "string", - "description": "Apply a predefined set of access controls to the destination object.", - "enum": [ - "authenticatedRead", - "bucketOwnerFullControl", - "bucketOwnerRead", - "private", - "projectPrivate", - "publicRead" - ], - "enumDescriptions": [ - "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", - "Object owner gets OWNER access, and project team owners get OWNER access.", - "Object owner gets OWNER access, and project team owners get READER access.", - "Object owner gets OWNER access.", - "Object owner gets OWNER access, and project team members get access according to their roles.", - "Object owner gets OWNER access, and allUsers get READER access." - ], - "location": "query" - }, - "ifGenerationMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the destination object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", - "format": "int64", - "location": "query" - }, - "ifGenerationNotMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the destination object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", - "format": "int64", - "location": "query" - }, - "ifMetagenerationMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the destination object's current metageneration matches the given value.", - "format": "int64", - "location": "query" - }, - "ifMetagenerationNotMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the destination object's current metageneration does not match the given value.", - "format": "int64", - "location": "query" - }, - "ifSourceGenerationMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the source object's current generation matches the given value.", - "format": "int64", - "location": "query" - }, - "ifSourceGenerationNotMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the source object's current generation does not match the given value.", - "format": "int64", - "location": "query" - }, - "ifSourceMetagenerationMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the source object's current metageneration matches the given value.", - "format": "int64", - "location": "query" - }, - "ifSourceMetagenerationNotMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the source object's current metageneration does not match the given value.", - "format": "int64", - "location": "query" - }, - "projection": { - "type": "string", - "description": "Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full.", - "enum": [ - "full", - "noAcl" - ], - "enumDescriptions": [ - "Include all properties.", - "Omit the owner, acl property." - ], - "location": "query" - }, - "sourceBucket": { - "type": "string", - "description": "Name of the bucket in which to find the source object.", - "required": true, - "location": "path" - }, - "sourceGeneration": { - "type": "string", - "description": "If present, selects a specific revision of the source object (as opposed to the latest version, the default).", - "format": "int64", - "location": "query" - }, - "sourceObject": { - "type": "string", - "description": "Name of the source object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", - "required": true, - "location": "path" - }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "parameterOrder": [ + "sourceBucket", + "sourceObject", + "destinationBucket", + "destinationObject" + ], + "request": { + "$ref": "Object" + }, + "response": { + "$ref": "RewriteResponse" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "setIamPolicy": { + "id": "storage.objects.setIamPolicy", + "path": "b/{bucket}/o/{object}/iam", + "httpMethod": "PUT", + "description": "Updates an IAM policy for the specified object.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the bucket in which the object resides.", + "required": true, + "location": "path" }, - "parameterOrder": [ - "sourceBucket", - "sourceObject", - "destinationBucket", - "destinationObject" - ], - "request": { - "$ref": "Object" + "generation": { + "type": "string", + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query" }, - "response": { - "$ref": "Object" + "object": { + "type": "string", + "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", + "required": true, + "location": "path" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_write" - ] + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "delete": { - "id": "storage.objects.delete", - "path": "b/{bucket}/o/{object}", - "httpMethod": "DELETE", - "description": "Deletes an object and its metadata. Deletions are permanent if versioning is not enabled for the bucket, or if the generation parameter is used.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of the bucket in which the object resides.", - "required": true, - "location": "path" - }, - "generation": { - "type": "string", - "description": "If present, permanently deletes a specific revision of this object (as opposed to the latest version, the default).", - "format": "int64", - "location": "query" - }, - "ifGenerationMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", - "format": "int64", - "location": "query" - }, - "ifGenerationNotMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", - "format": "int64", - "location": "query" - }, - "ifMetagenerationMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", - "format": "int64", - "location": "query" - }, - "ifMetagenerationNotMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", - "format": "int64", - "location": "query" - }, - "object": { - "type": "string", - "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", - "required": true, - "location": "path" - }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "parameterOrder": [ + "bucket", + "object" + ], + "request": { + "$ref": "Policy" + }, + "response": { + "$ref": "Policy" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "testIamPermissions": { + "id": "storage.objects.testIamPermissions", + "path": "b/{bucket}/o/{object}/iam/testPermissions", + "httpMethod": "GET", + "description": "Tests a set of permissions on the given object to see which, if any, are held by the caller.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the bucket in which the object resides.", + "required": true, + "location": "path" }, - "parameterOrder": [ - "bucket", - "object" - ], - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_write" - ] - }, - "get": { - "id": "storage.objects.get", - "path": "b/{bucket}/o/{object}", - "httpMethod": "GET", - "description": "Retrieves an object or its metadata.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of the bucket in which the object resides.", - "required": true, - "location": "path" - }, - "generation": { - "type": "string", - "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", - "format": "int64", - "location": "query" - }, - "ifGenerationMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", - "format": "int64", - "location": "query" - }, - "ifGenerationNotMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", - "format": "int64", - "location": "query" - }, - "ifMetagenerationMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", - "format": "int64", - "location": "query" - }, - "ifMetagenerationNotMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", - "format": "int64", - "location": "query" - }, - "object": { - "type": "string", - "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", - "required": true, - "location": "path" - }, - "projection": { - "type": "string", - "description": "Set of properties to return. Defaults to noAcl.", - "enum": [ - "full", - "noAcl" - ], - "enumDescriptions": [ - "Include all properties.", - "Omit the owner, acl property." - ], - "location": "query" - }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "generation": { + "type": "string", + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query" }, - "parameterOrder": [ - "bucket", - "object" - ], - "response": { - "$ref": "Object" - }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_only", - "https://www.googleapis.com/auth/devstorage.read_write" - ], - "supportsMediaDownload": true, - "useMediaDownloadService": true - }, - "getIamPolicy": { - "id": "storage.objects.getIamPolicy", - "path": "b/{bucket}/o/{object}/iam", - "httpMethod": "GET", - "description": "Returns an IAM policy for the specified object.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of the bucket in which the object resides.", - "required": true, - "location": "path" - }, - "generation": { - "type": "string", - "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", - "format": "int64", - "location": "query" - }, - "object": { - "type": "string", - "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", - "required": true, - "location": "path" + "object": { + "type": "string", + "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", + "required": true, + "location": "path" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "permissions": { + "type": "string", + "description": "Permissions to test.", + "required": true, + "repeated": true, + "location": "query" }, - "parameterOrder": [ - "bucket", - "object" - ], - "response": { - "$ref": "Policy" - }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_only", - "https://www.googleapis.com/auth/devstorage.read_write" - ] + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "insert": { - "id": "storage.objects.insert", - "path": "b/{bucket}/o", - "httpMethod": "POST", - "description": "Stores a new object and metadata.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of the bucket in which to store the new object. Overrides the provided object metadata's bucket value, if any.", - "required": true, - "location": "path" - }, - "contentEncoding": { - "type": "string", - "description": "If set, sets the contentEncoding property of the final object to this value. Setting this parameter is equivalent to setting the contentEncoding metadata property. This can be useful when uploading an object with uploadType=media to indicate the encoding of the content being uploaded.", - "location": "query" - }, - "ifGenerationMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", - "format": "int64", - "location": "query" - }, - "ifGenerationNotMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", - "format": "int64", - "location": "query" - }, - "ifMetagenerationMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", - "format": "int64", - "location": "query" - }, - "ifMetagenerationNotMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", - "format": "int64", - "location": "query" - }, - "kmsKeyName": { - "type": "string", - "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", - "location": "query" - }, - "name": { - "type": "string", - "description": "Name of the object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", - "location": "query" - }, - "predefinedAcl": { - "type": "string", - "description": "Apply a predefined set of access controls to this object.", - "enum": [ - "authenticatedRead", - "bucketOwnerFullControl", - "bucketOwnerRead", - "private", - "projectPrivate", - "publicRead" - ], - "enumDescriptions": [ - "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", - "Object owner gets OWNER access, and project team owners get OWNER access.", - "Object owner gets OWNER access, and project team owners get READER access.", - "Object owner gets OWNER access.", - "Object owner gets OWNER access, and project team members get access according to their roles.", - "Object owner gets OWNER access, and allUsers get READER access." - ], - "location": "query" - }, - "projection": { - "type": "string", - "description": "Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full.", - "enum": [ - "full", - "noAcl" - ], - "enumDescriptions": [ - "Include all properties.", - "Omit the owner, acl property." - ], - "location": "query" - }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "parameterOrder": [ + "bucket", + "object", + "permissions" + ], + "response": { + "$ref": "TestIamPermissionsResponse" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "update": { + "id": "storage.objects.update", + "path": "b/{bucket}/o/{object}", + "httpMethod": "PUT", + "description": "Updates an object's metadata.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the bucket in which the object resides.", + "required": true, + "location": "path" }, - "parameterOrder": [ - "bucket" - ], - "request": { - "$ref": "Object" + "generation": { + "type": "string", + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query" }, - "response": { - "$ref": "Object" + "ifGenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_write" - ], - "supportsMediaUpload": true, - "mediaUpload": { - "accept": [ - "*/*" - ], - "protocols": { - "simple": { - "multipart": true, - "path": "/upload/storage/v1/b/{bucket}/o" - }, - "resumable": { - "multipart": true, - "path": "/resumable/upload/storage/v1/b/{bucket}/o" - } - } - } - }, - "list": { - "id": "storage.objects.list", - "path": "b/{bucket}/o", - "httpMethod": "GET", - "description": "Retrieves a list of objects matching the criteria.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of the bucket in which to look for objects.", - "required": true, - "location": "path" - }, - "delimiter": { - "type": "string", - "description": "Returns results in a directory-like mode. items will contain only objects whose names, aside from the prefix, do not contain delimiter. Objects whose names, aside from the prefix, contain delimiter will have their name, truncated after the delimiter, returned in prefixes. Duplicate prefixes are omitted.", - "location": "query" - }, - "endOffset": { - "type": "string", - "description": "Filter results to objects whose names are lexicographically before endOffset. If startOffset is also set, the objects listed will have names between startOffset (inclusive) and endOffset (exclusive).", - "location": "query" - }, - "includeTrailingDelimiter": { - "type": "boolean", - "description": "If true, objects that end in exactly one instance of delimiter will have their metadata included in items in addition to prefixes.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Maximum number of items plus prefixes to return in a single page of responses. As duplicate prefixes are omitted, fewer total results may be returned than requested. The service will use this parameter or 1,000 items, whichever is smaller.", - "default": "1000", - "format": "uint32", - "minimum": "0", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "A previously-returned page token representing part of the larger set of results to view.", - "location": "query" - }, - "prefix": { - "type": "string", - "description": "Filter results to objects whose names begin with this prefix.", - "location": "query" - }, - "projection": { - "type": "string", - "description": "Set of properties to return. Defaults to noAcl.", - "enum": [ - "full", - "noAcl" - ], - "enumDescriptions": [ - "Include all properties.", - "Omit the owner, acl property." - ], - "location": "query" - }, - "startOffset": { - "type": "string", - "description": "Filter results to objects whose names are lexicographically equal to or after startOffset. If endOffset is also set, the objects listed will have names between startOffset (inclusive) and endOffset (exclusive).", - "location": "query" - }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - }, - "versions": { - "type": "boolean", - "description": "If true, lists all versions of an object as distinct results. The default is false. For more information, see Object Versioning.", - "location": "query" - } + "ifGenerationNotMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query" }, - "parameterOrder": [ - "bucket" - ], - "response": { - "$ref": "Objects" - }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_only", - "https://www.googleapis.com/auth/devstorage.read_write" - ], - "supportsSubscription": true - }, - "patch": { - "id": "storage.objects.patch", - "path": "b/{bucket}/o/{object}", - "httpMethod": "PATCH", - "description": "Patches an object's metadata.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of the bucket in which the object resides.", - "required": true, - "location": "path" - }, - "generation": { - "type": "string", - "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", - "format": "int64", - "location": "query" - }, - "ifGenerationMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", - "format": "int64", - "location": "query" - }, - "ifGenerationNotMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", - "format": "int64", - "location": "query" - }, - "ifMetagenerationMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", - "format": "int64", - "location": "query" - }, - "ifMetagenerationNotMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", - "format": "int64", - "location": "query" - }, - "object": { - "type": "string", - "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", - "required": true, - "location": "path" - }, - "predefinedAcl": { - "type": "string", - "description": "Apply a predefined set of access controls to this object.", - "enum": [ - "authenticatedRead", - "bucketOwnerFullControl", - "bucketOwnerRead", - "private", - "projectPrivate", - "publicRead" - ], - "enumDescriptions": [ - "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", - "Object owner gets OWNER access, and project team owners get OWNER access.", - "Object owner gets OWNER access, and project team owners get READER access.", - "Object owner gets OWNER access.", - "Object owner gets OWNER access, and project team members get access according to their roles.", - "Object owner gets OWNER access, and allUsers get READER access." - ], - "location": "query" - }, - "projection": { - "type": "string", - "description": "Set of properties to return. Defaults to full.", - "enum": [ - "full", - "noAcl" - ], - "enumDescriptions": [ - "Include all properties.", - "Omit the owner, acl property." - ], - "location": "query" - }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request, for Requester Pays buckets.", - "location": "query" - } + "ifMetagenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + "format": "int64", + "location": "query" + }, + "ifMetagenerationNotMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + "format": "int64", + "location": "query" + }, + "overrideUnlockedRetention": { + "type": "boolean", + "description": "Must be true to remove the retention configuration, reduce its unlocked retention period, or change its mode from unlocked to locked.", + "location": "query" }, - "parameterOrder": [ - "bucket", - "object" - ], - "request": { - "$ref": "Object" + "object": { + "type": "string", + "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", + "required": true, + "location": "path" }, - "response": { - "$ref": "Object" + "predefinedAcl": { + "type": "string", + "description": "Apply a predefined set of access controls to this object.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] + "projection": { + "type": "string", + "description": "Set of properties to return. Defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } }, - "rewrite": { - "id": "storage.objects.rewrite", - "path": "b/{sourceBucket}/o/{sourceObject}/rewriteTo/b/{destinationBucket}/o/{destinationObject}", - "httpMethod": "POST", - "description": "Rewrites a source object to a destination object. Optionally overrides metadata.", - "parameters": { - "destinationBucket": { - "type": "string", - "description": "Name of the bucket in which to store the new object. Overrides the provided object metadata's bucket value, if any.", - "required": true, - "location": "path" - }, - "destinationKmsKeyName": { - "type": "string", - "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", - "location": "query" - }, - "destinationObject": { - "type": "string", - "description": "Name of the new object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", - "required": true, - "location": "path" - }, - "destinationPredefinedAcl": { - "type": "string", - "description": "Apply a predefined set of access controls to the destination object.", - "enum": [ - "authenticatedRead", - "bucketOwnerFullControl", - "bucketOwnerRead", - "private", - "projectPrivate", - "publicRead" - ], - "enumDescriptions": [ - "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", - "Object owner gets OWNER access, and project team owners get OWNER access.", - "Object owner gets OWNER access, and project team owners get READER access.", - "Object owner gets OWNER access.", - "Object owner gets OWNER access, and project team members get access according to their roles.", - "Object owner gets OWNER access, and allUsers get READER access." - ], - "location": "query" - }, - "ifGenerationMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", - "format": "int64", - "location": "query" - }, - "ifGenerationNotMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", - "format": "int64", - "location": "query" - }, - "ifMetagenerationMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the destination object's current metageneration matches the given value.", - "format": "int64", - "location": "query" - }, - "ifMetagenerationNotMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the destination object's current metageneration does not match the given value.", - "format": "int64", - "location": "query" - }, - "ifSourceGenerationMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the source object's current generation matches the given value.", - "format": "int64", - "location": "query" - }, - "ifSourceGenerationNotMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the source object's current generation does not match the given value.", - "format": "int64", - "location": "query" - }, - "ifSourceMetagenerationMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the source object's current metageneration matches the given value.", - "format": "int64", - "location": "query" - }, - "ifSourceMetagenerationNotMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the source object's current metageneration does not match the given value.", - "format": "int64", - "location": "query" - }, - "maxBytesRewrittenPerCall": { - "type": "string", - "description": "The maximum number of bytes that will be rewritten per rewrite request. Most callers shouldn't need to specify this parameter - it is primarily in place to support testing. If specified the value must be an integral multiple of 1 MiB (1048576). Also, this only applies to requests where the source and destination span locations and/or storage classes. Finally, this value must not change across rewrite calls else you'll get an error that the rewriteToken is invalid.", - "format": "int64", - "location": "query" - }, - "projection": { - "type": "string", - "description": "Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full.", - "enum": [ - "full", - "noAcl" - ], - "enumDescriptions": [ - "Include all properties.", - "Omit the owner, acl property." - ], - "location": "query" - }, - "rewriteToken": { - "type": "string", - "description": "Include this field (from the previous rewrite response) on each rewrite request after the first one, until the rewrite response 'done' flag is true. Calls that provide a rewriteToken can omit all other request fields, but if included those fields must match the values provided in the first rewrite request.", - "location": "query" - }, - "sourceBucket": { - "type": "string", - "description": "Name of the bucket in which to find the source object.", - "required": true, - "location": "path" - }, - "sourceGeneration": { - "type": "string", - "description": "If present, selects a specific revision of the source object (as opposed to the latest version, the default).", - "format": "int64", - "location": "query" - }, - "sourceObject": { - "type": "string", - "description": "Name of the source object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", - "required": true, - "location": "path" - }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "parameterOrder": [ + "bucket", + "object" + ], + "request": { + "$ref": "Object" + }, + "response": { + "$ref": "Object" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "watchAll": { + "id": "storage.objects.watchAll", + "path": "b/{bucket}/o/watch", + "httpMethod": "POST", + "description": "Watch for changes on all objects in a bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the bucket in which to look for objects.", + "required": true, + "location": "path" }, - "parameterOrder": [ - "sourceBucket", - "sourceObject", - "destinationBucket", - "destinationObject" - ], - "request": { - "$ref": "Object" + "delimiter": { + "type": "string", + "description": "Returns results in a directory-like mode. items will contain only objects whose names, aside from the prefix, do not contain delimiter. Objects whose names, aside from the prefix, contain delimiter will have their name, truncated after the delimiter, returned in prefixes. Duplicate prefixes are omitted.", + "location": "query" }, - "response": { - "$ref": "RewriteResponse" + "endOffset": { + "type": "string", + "description": "Filter results to objects whose names are lexicographically before endOffset. If startOffset is also set, the objects listed will have names between startOffset (inclusive) and endOffset (exclusive).", + "location": "query" + }, + "includeTrailingDelimiter": { + "type": "boolean", + "description": "If true, objects that end in exactly one instance of delimiter will have their metadata included in items in addition to prefixes.", + "location": "query" + }, + "maxResults": { + "type": "integer", + "description": "Maximum number of items plus prefixes to return in a single page of responses. As duplicate prefixes are omitted, fewer total results may be returned than requested. The service will use this parameter or 1,000 items, whichever is smaller.", + "default": "1000", + "format": "uint32", + "minimum": "0", + "location": "query" + }, + "pageToken": { + "type": "string", + "description": "A previously-returned page token representing part of the larger set of results to view.", + "location": "query" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_write" - ] - }, - "setIamPolicy": { - "id": "storage.objects.setIamPolicy", - "path": "b/{bucket}/o/{object}/iam", - "httpMethod": "PUT", - "description": "Updates an IAM policy for the specified object.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of the bucket in which the object resides.", - "required": true, - "location": "path" - }, - "generation": { - "type": "string", - "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", - "format": "int64", - "location": "query" - }, - "object": { - "type": "string", - "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", - "required": true, - "location": "path" + "prefix": { + "type": "string", + "description": "Filter results to objects whose names begin with this prefix.", + "location": "query" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "projection": { + "type": "string", + "description": "Set of properties to return. Defaults to noAcl.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query" }, - "parameterOrder": [ - "bucket", - "object" - ], - "request": { - "$ref": "Policy" + "startOffset": { + "type": "string", + "description": "Filter results to objects whose names are lexicographically equal to or after startOffset. If endOffset is also set, the objects listed will have names between startOffset (inclusive) and endOffset (exclusive).", + "location": "query" }, - "response": { - "$ref": "Policy" + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_write" - ] + "versions": { + "type": "boolean", + "description": "If true, lists all versions of an object as distinct results. The default is false. For more information, see Object Versioning.", + "location": "query" + } }, - "testIamPermissions": { - "id": "storage.objects.testIamPermissions", - "path": "b/{bucket}/o/{object}/iam/testPermissions", - "httpMethod": "GET", - "description": "Tests a set of permissions on the given object to see which, if any, are held by the caller.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of the bucket in which the object resides.", - "required": true, - "location": "path" - }, - "generation": { - "type": "string", - "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", - "format": "int64", - "location": "query" - }, - "object": { - "type": "string", - "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", - "required": true, - "location": "path" - }, - "permissions": { - "type": "string", - "description": "Permissions to test.", - "required": true, - "repeated": true, - "location": "query" + "parameterOrder": [ + "bucket" + ], + "request": { + "$ref": "Channel", + "parameterName": "resource" + }, + "response": { + "$ref": "Channel" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ], + "supportsSubscription": true + }, + "restore": { + "id": "storage.objects.restore", + "path": "b/{bucket}/o/{object}/restore", + "httpMethod": "POST", + "description": "Restores a soft-deleted object.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the bucket in which the object resides.", + "required": true, + "location": "path" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "generation": { + "type": "string", + "description": "Selects a specific revision of this object.", + "required": true, + "format": "int64", + "location": "query" }, - "parameterOrder": [ - "bucket", - "object", - "permissions" - ], - "response": { - "$ref": "TestIamPermissionsResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_only", - "https://www.googleapis.com/auth/devstorage.read_write" - ] - }, - "update": { - "id": "storage.objects.update", - "path": "b/{bucket}/o/{object}", - "httpMethod": "PUT", - "description": "Updates an object's metadata.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of the bucket in which the object resides.", - "required": true, - "location": "path" - }, - "generation": { - "type": "string", - "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", - "format": "int64", - "location": "query" - }, - "ifGenerationMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", - "format": "int64", - "location": "query" - }, - "ifGenerationNotMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", - "format": "int64", - "location": "query" - }, - "ifMetagenerationMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", - "format": "int64", - "location": "query" - }, - "ifMetagenerationNotMatch": { - "type": "string", - "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", - "format": "int64", - "location": "query" - }, - "object": { - "type": "string", - "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", - "required": true, - "location": "path" - }, - "predefinedAcl": { - "type": "string", - "description": "Apply a predefined set of access controls to this object.", - "enum": [ - "authenticatedRead", - "bucketOwnerFullControl", - "bucketOwnerRead", - "private", - "projectPrivate", - "publicRead" - ], - "enumDescriptions": [ - "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", - "Object owner gets OWNER access, and project team owners get OWNER access.", - "Object owner gets OWNER access, and project team owners get READER access.", - "Object owner gets OWNER access.", - "Object owner gets OWNER access, and project team members get access according to their roles.", - "Object owner gets OWNER access, and allUsers get READER access." - ], - "location": "query" - }, - "projection": { - "type": "string", - "description": "Set of properties to return. Defaults to full.", - "enum": [ - "full", - "noAcl" - ], - "enumDescriptions": [ - "Include all properties.", - "Omit the owner, acl property." - ], - "location": "query" - }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - } + "object": { + "type": "string", + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "required": true, + "location": "path" }, - "parameterOrder": [ - "bucket", - "object" - ], - "request": { - "$ref": "Object" + "ifGenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's one live generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query" }, - "response": { - "$ref": "Object" + "ifGenerationNotMatch": { + "type": "string", + "description": "Makes the operation conditional on whether none of the object's live generations match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] - }, - "watchAll": { - "id": "storage.objects.watchAll", - "path": "b/{bucket}/o/watch", - "httpMethod": "POST", - "description": "Watch for changes on all objects in a bucket.", - "parameters": { - "bucket": { - "type": "string", - "description": "Name of the bucket in which to look for objects.", - "required": true, - "location": "path" - }, - "delimiter": { - "type": "string", - "description": "Returns results in a directory-like mode. items will contain only objects whose names, aside from the prefix, do not contain delimiter. Objects whose names, aside from the prefix, contain delimiter will have their name, truncated after the delimiter, returned in prefixes. Duplicate prefixes are omitted.", - "location": "query" - }, - "endOffset": { - "type": "string", - "description": "Filter results to objects whose names are lexicographically before endOffset. If startOffset is also set, the objects listed will have names between startOffset (inclusive) and endOffset (exclusive).", - "location": "query" - }, - "includeTrailingDelimiter": { - "type": "boolean", - "description": "If true, objects that end in exactly one instance of delimiter will have their metadata included in items in addition to prefixes.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Maximum number of items plus prefixes to return in a single page of responses. As duplicate prefixes are omitted, fewer total results may be returned than requested. The service will use this parameter or 1,000 items, whichever is smaller.", - "default": "1000", - "format": "uint32", - "minimum": "0", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "A previously-returned page token representing part of the larger set of results to view.", - "location": "query" - }, - "prefix": { - "type": "string", - "description": "Filter results to objects whose names begin with this prefix.", - "location": "query" - }, - "projection": { - "type": "string", - "description": "Set of properties to return. Defaults to noAcl.", - "enum": [ - "full", - "noAcl" - ], - "enumDescriptions": [ - "Include all properties.", - "Omit the owner, acl property." - ], - "location": "query" - }, - "startOffset": { - "type": "string", - "description": "Filter results to objects whose names are lexicographically equal to or after startOffset. If endOffset is also set, the objects listed will have names between startOffset (inclusive) and endOffset (exclusive).", - "location": "query" - }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request. Required for Requester Pays buckets.", - "location": "query" - }, - "versions": { - "type": "boolean", - "description": "If true, lists all versions of an object as distinct results. The default is false. For more information, see Object Versioning.", - "location": "query" - } + "ifMetagenerationMatch": { + "type": "string", + "description": "Makes the operation conditional on whether the object's one live metageneration matches the given value.", + "format": "int64", + "location": "query" }, - "parameterOrder": [ - "bucket" - ], - "request": { - "$ref": "Channel", - "parameterName": "resource" - }, - "response": { - "$ref": "Channel" - }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_only", - "https://www.googleapis.com/auth/devstorage.read_write" - ], - "supportsSubscription": true - } + "ifMetagenerationNotMatch": { + "type": "string", + "description": "Makes the operation conditional on whether none of the object's live metagenerations match the given value.", + "format": "int64", + "location": "query" + }, + "copySourceAcl": { + "type": "boolean", + "description": "If true, copies the source object's ACL; otherwise, uses the bucket's default object ACL. The default is false.", + "location": "query" + }, + "projection": { + "type": "string", + "description": "Set of properties to return. Defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query" + } + }, + "parameterOrder": [ + "bucket", + "object" + ], + "request": { + "$ref": "Object" + }, + "response": { + "$ref": "Object" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "bulkRestore": { + "id": "storage.objects.bulkRestore", + "path": "b/{bucket}/o/bulkRestore", + "httpMethod": "POST", + "description": "Initiates a long-running bulk restore operation on the specified bucket.", + "parameters": { + "bucket": { + "type": "string", + "description": "Name of the bucket in which the object resides.", + "required": true, + "location": "path" + } + }, + "parameterOrder": [ + "bucket" + ], + "request": { + "$ref": "BulkRestoreObjectsRequest" + }, + "response": { + "$ref": "GoogleLongrunningOperation" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] } - }, - "projects": { - "resources": { - "hmacKeys": { - "methods": { - "create": { - "id": "storage.projects.hmacKeys.create", - "path": "projects/{projectId}/hmacKeys", - "httpMethod": "POST", - "description": "Creates a new HMAC key for the specified service account.", - "parameters": { - "projectId": { - "type": "string", - "description": "Project ID owning the service account.", - "required": true, - "location": "path" - }, - "serviceAccountEmail": { - "type": "string", - "description": "Email address of the service account.", - "required": true, - "location": "query" - }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request.", - "location": "query" - } + } + }, + "projects": { + "resources": { + "hmacKeys": { + "methods": { + "create": { + "id": "storage.projects.hmacKeys.create", + "path": "projects/{projectId}/hmacKeys", + "httpMethod": "POST", + "description": "Creates a new HMAC key for the specified service account.", + "parameters": { + "projectId": { + "type": "string", + "description": "Project ID owning the service account.", + "required": true, + "location": "path" }, - "parameterOrder": [ - "projectId", - "serviceAccountEmail" - ], - "response": { - "$ref": "HmacKey" + "serviceAccountEmail": { + "type": "string", + "description": "Email address of the service account.", + "required": true, + "location": "query" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] + "userProject": { + "type": "string", + "description": "The project to be billed for this request.", + "location": "query" + } }, - "delete": { - "id": "storage.projects.hmacKeys.delete", - "path": "projects/{projectId}/hmacKeys/{accessId}", - "httpMethod": "DELETE", - "description": "Deletes an HMAC key.", - "parameters": { - "accessId": { - "type": "string", - "description": "Name of the HMAC key to be deleted.", - "required": true, - "location": "path" - }, - "projectId": { - "type": "string", - "description": "Project ID owning the requested key", - "required": true, - "location": "path" - }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request.", - "location": "query" - } - }, - "parameterOrder": [ - "projectId", - "accessId" - ], - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_write" - ] + "parameterOrder": [ + "projectId", + "serviceAccountEmail" + ], + "response": { + "$ref": "HmacKey" }, - "get": { - "id": "storage.projects.hmacKeys.get", - "path": "projects/{projectId}/hmacKeys/{accessId}", - "httpMethod": "GET", - "description": "Retrieves an HMAC key's metadata", - "parameters": { - "accessId": { - "type": "string", - "description": "Name of the HMAC key.", - "required": true, - "location": "path" - }, - "projectId": { - "type": "string", - "description": "Project ID owning the service account of the requested key.", - "required": true, - "location": "path" - }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request.", - "location": "query" - } + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "delete": { + "id": "storage.projects.hmacKeys.delete", + "path": "projects/{projectId}/hmacKeys/{accessId}", + "httpMethod": "DELETE", + "description": "Deletes an HMAC key.", + "parameters": { + "accessId": { + "type": "string", + "description": "Name of the HMAC key to be deleted.", + "required": true, + "location": "path" }, - "parameterOrder": [ - "projectId", - "accessId" - ], - "response": { - "$ref": "HmacKeyMetadata" + "projectId": { + "type": "string", + "description": "Project ID owning the requested key", + "required": true, + "location": "path" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_only" - ] + "userProject": { + "type": "string", + "description": "The project to be billed for this request.", + "location": "query" + } }, - "list": { - "id": "storage.projects.hmacKeys.list", - "path": "projects/{projectId}/hmacKeys", - "httpMethod": "GET", - "description": "Retrieves a list of HMAC keys matching the criteria.", - "parameters": { - "maxResults": { - "type": "integer", - "description": "Maximum number of items to return in a single page of responses. The service uses this parameter or 250 items, whichever is smaller. The max number of items per page will also be limited by the number of distinct service accounts in the response. If the number of service accounts in a single response is too high, the page will truncated and a next page token will be returned.", - "default": "250", - "format": "uint32", - "minimum": "0", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "A previously-returned page token representing part of the larger set of results to view.", - "location": "query" - }, - "projectId": { - "type": "string", - "description": "Name of the project in which to look for HMAC keys.", - "required": true, - "location": "path" - }, - "serviceAccountEmail": { - "type": "string", - "description": "If present, only keys for the given service account are returned.", - "location": "query" - }, - "showDeletedKeys": { - "type": "boolean", - "description": "Whether or not to show keys in the DELETED state.", - "location": "query" - }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request.", - "location": "query" - } + "parameterOrder": [ + "projectId", + "accessId" + ], + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "get": { + "id": "storage.projects.hmacKeys.get", + "path": "projects/{projectId}/hmacKeys/{accessId}", + "httpMethod": "GET", + "description": "Retrieves an HMAC key's metadata", + "parameters": { + "accessId": { + "type": "string", + "description": "Name of the HMAC key.", + "required": true, + "location": "path" }, - "parameterOrder": [ - "projectId" - ], - "response": { - "$ref": "HmacKeysMetadata" + "projectId": { + "type": "string", + "description": "Project ID owning the service account of the requested key.", + "required": true, + "location": "path" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_only" - ] + "userProject": { + "type": "string", + "description": "The project to be billed for this request.", + "location": "query" + } }, - "update": { - "id": "storage.projects.hmacKeys.update", - "path": "projects/{projectId}/hmacKeys/{accessId}", - "httpMethod": "PUT", - "description": "Updates the state of an HMAC key. See the HMAC Key resource descriptor for valid states.", - "parameters": { - "accessId": { - "type": "string", - "description": "Name of the HMAC key being updated.", - "required": true, - "location": "path" - }, - "projectId": { - "type": "string", - "description": "Project ID owning the service account of the updated key.", - "required": true, - "location": "path" - }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request.", - "location": "query" - } + "parameterOrder": [ + "projectId", + "accessId" + ], + "response": { + "$ref": "HmacKeyMetadata" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only" + ] + }, + "list": { + "id": "storage.projects.hmacKeys.list", + "path": "projects/{projectId}/hmacKeys", + "httpMethod": "GET", + "description": "Retrieves a list of HMAC keys matching the criteria.", + "parameters": { + "maxResults": { + "type": "integer", + "description": "Maximum number of items to return in a single page of responses. The service uses this parameter or 250 items, whichever is smaller. The max number of items per page will also be limited by the number of distinct service accounts in the response. If the number of service accounts in a single response is too high, the page will truncated and a next page token will be returned.", + "default": "250", + "format": "uint32", + "minimum": "0", + "location": "query" }, - "parameterOrder": [ - "projectId", - "accessId" - ], - "request": { - "$ref": "HmacKeyMetadata" + "pageToken": { + "type": "string", + "description": "A previously-returned page token representing part of the larger set of results to view.", + "location": "query" }, - "response": { - "$ref": "HmacKeyMetadata" + "projectId": { + "type": "string", + "description": "Name of the project in which to look for HMAC keys.", + "required": true, + "location": "path" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/devstorage.full_control" - ] - } - } - }, - "serviceAccount": { - "methods": { - "get": { - "id": "storage.projects.serviceAccount.get", - "path": "projects/{projectId}/serviceAccount", - "httpMethod": "GET", - "description": "Get the email address of this project's Google Cloud Storage service account.", - "parameters": { - "projectId": { - "type": "string", - "description": "Project ID", - "required": true, - "location": "path" + "serviceAccountEmail": { + "type": "string", + "description": "If present, only keys for the given service account are returned.", + "location": "query" }, - "userProject": { - "type": "string", - "description": "The project to be billed for this request.", - "location": "query" - } + "showDeletedKeys": { + "type": "boolean", + "description": "Whether or not to show keys in the DELETED state.", + "location": "query" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request.", + "location": "query" + } + }, + "parameterOrder": [ + "projectId" + ], + "response": { + "$ref": "HmacKeysMetadata" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only" + ] + }, + "update": { + "id": "storage.projects.hmacKeys.update", + "path": "projects/{projectId}/hmacKeys/{accessId}", + "httpMethod": "PUT", + "description": "Updates the state of an HMAC key. See the HMAC Key resource descriptor for valid states.", + "parameters": { + "accessId": { + "type": "string", + "description": "Name of the HMAC key being updated.", + "required": true, + "location": "path" }, - "parameterOrder": [ - "projectId" - ], - "response": { - "$ref": "ServiceAccount" + "projectId": { + "type": "string", + "description": "Project ID owning the service account of the updated key.", + "required": true, + "location": "path" }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_only", - "https://www.googleapis.com/auth/devstorage.read_write" - ] - } + "userProject": { + "type": "string", + "description": "The project to be billed for this request.", + "location": "query" + } + }, + "parameterOrder": [ + "projectId", + "accessId" + ], + "request": { + "$ref": "HmacKeyMetadata" + }, + "response": { + "$ref": "HmacKeyMetadata" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + } + } + }, + "serviceAccount": { + "methods": { + "get": { + "id": "storage.projects.serviceAccount.get", + "path": "projects/{projectId}/serviceAccount", + "httpMethod": "GET", + "description": "Get the email address of this project's Google Cloud Storage service account.", + "parameters": { + "projectId": { + "type": "string", + "description": "Project ID", + "required": true, + "location": "path" + }, + "userProject": { + "type": "string", + "description": "The project to be billed for this request.", + "location": "query" + } + }, + "parameterOrder": [ + "projectId" + ], + "response": { + "$ref": "ServiceAccount" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] } } } } - }, - "revision": "20220718", - "etag": "\"33383537313931303639303633323338353436\"" + } + }, + "revision": "20231028", + "etag": "\"39383633393336373936373236333033393737\"" } diff --git a/lib/Google/vendor/google/cloud-storage/src/HmacKey.php b/lib/Google/vendor/google/cloud-storage/src/HmacKey.php index e23f3de39..b64dd3d6c 100644 --- a/lib/Google/vendor/google/cloud-storage/src/HmacKey.php +++ b/lib/Google/vendor/google/cloud-storage/src/HmacKey.php @@ -34,6 +34,7 @@ class HmacKey { /** * @var ConnectionInterface + * @internal */ private $connection; @@ -54,6 +55,8 @@ class HmacKey /** * @param ConnectionInterface $connection A connection to Cloud Storage. + * This object is created by StorageClient, + * and should not be instantiated outside of this client. * @param string $projectId The current project ID. * @param string $accessId The key identifier. * @param array|null $info The key metadata. @@ -170,7 +173,7 @@ public function update($state, array $options = []) * Delete the HMAC Key. * * Key state must be set to `INACTIVE` prior to deletion. See - * {@see Google\Cloud\Storage\HmacKey::update()} for details. + * {@see HmacKey::update()} for details. * * Example: * ``` diff --git a/lib/Google/vendor/google/cloud-storage/src/Lifecycle.php b/lib/Google/vendor/google/cloud-storage/src/Lifecycle.php index 14f45d0ab..88a9966a3 100644 --- a/lib/Google/vendor/google/cloud-storage/src/Lifecycle.php +++ b/lib/Google/vendor/google/cloud-storage/src/Lifecycle.php @@ -26,8 +26,8 @@ * * This builder does not execute any network requests and is intended to be used * in combination with either - * {@see Google\Cloud\Storage\StorageClient::createBucket()} - * or {@see Google\Cloud\Storage\Bucket::update()}. + * {@see StorageClient::createBucket()} + * or {@see Bucket::update()}. * * Example: * ``` diff --git a/lib/Google/vendor/google/cloud-storage/src/Notification.php b/lib/Google/vendor/google/cloud-storage/src/Notification.php index 67ab58a5a..3caa2b128 100644 --- a/lib/Google/vendor/google/cloud-storage/src/Notification.php +++ b/lib/Google/vendor/google/cloud-storage/src/Notification.php @@ -30,7 +30,7 @@ * and the object that changed. * * To utilize this class and see more examples, please see the relevant - * notifications based methods exposed on {@see Google\Cloud\Storage\Bucket}. + * notifications based methods exposed on {@see Bucket}. * * Example: * ``` @@ -55,6 +55,7 @@ class Notification /** * @var ConnectionInterface Represents a connection to Cloud Storage. + * @internal */ private $connection; @@ -70,7 +71,8 @@ class Notification /** * @param ConnectionInterface $connection Represents a connection to Cloud - * Storage. + * Storage. This object is created by StorageClient, + * and should not be instantiated outside of this client. * @param string $id The notification's ID. * @param string $bucket The name of the bucket associated with this * notification. diff --git a/lib/Google/vendor/google/cloud-storage/src/ObjectIterator.php b/lib/Google/vendor/google/cloud-storage/src/ObjectIterator.php index 0490e3c3c..254bc5e70 100644 --- a/lib/Google/vendor/google/cloud-storage/src/ObjectIterator.php +++ b/lib/Google/vendor/google/cloud-storage/src/ObjectIterator.php @@ -20,7 +20,9 @@ use Google\Cloud\Core\Iterator\ItemIteratorTrait; /** - * Iterates over a set of {@see Google\Cloud\Storage\StorageObject} items. + * ObjectIterator + * + * Iterates over a set of {@see StorageObject} items. */ class ObjectIterator implements \Iterator { diff --git a/lib/Google/vendor/google/cloud-storage/src/ObjectPageIterator.php b/lib/Google/vendor/google/cloud-storage/src/ObjectPageIterator.php index 0d8afb3d9..11ba03dc4 100644 --- a/lib/Google/vendor/google/cloud-storage/src/ObjectPageIterator.php +++ b/lib/Google/vendor/google/cloud-storage/src/ObjectPageIterator.php @@ -20,8 +20,10 @@ use Google\Cloud\Core\Iterator\PageIteratorTrait; /** + * ObjectPageIterator + * * Iterates over a set of pages containing - * {@see Google\Cloud\Storage\StorageObject} items. + * {@see StorageObject} items. */ class ObjectPageIterator implements \Iterator { diff --git a/lib/Google/vendor/google/cloud-storage/src/ReadStream.php b/lib/Google/vendor/google/cloud-storage/src/ReadStream.php index 33e55094c..cfae74d8e 100644 --- a/lib/Google/vendor/google/cloud-storage/src/ReadStream.php +++ b/lib/Google/vendor/google/cloud-storage/src/ReadStream.php @@ -47,7 +47,7 @@ public function __construct(StreamInterface $stream) * * @return int The size of the stream. */ - public function getSize() + public function getSize(): ?int { return $this->stream->getSize() ?: $this->getSizeFromMetadata(); } @@ -58,7 +58,7 @@ public function getSize() * * @return int The Size of the stream */ - private function getSizeFromMetadata() + private function getSizeFromMetadata(): int { foreach ($this->stream->getMetadata('wrapper_data') as $value) { if (substr($value, 0, 15) == "Content-Length:") { @@ -78,7 +78,7 @@ private function getSizeFromMetadata() * @param int $length The number of bytes to read. * @return string Read bytes from the underlying stream. */ - public function read($length) + public function read($length): string { $data = ''; do { diff --git a/lib/Google/vendor/google/cloud-storage/src/SigningHelper.php b/lib/Google/vendor/google/cloud-storage/src/SigningHelper.php index 33f6df6c9..bf48ab81f 100644 --- a/lib/Google/vendor/google/cloud-storage/src/SigningHelper.php +++ b/lib/Google/vendor/google/cloud-storage/src/SigningHelper.php @@ -60,14 +60,15 @@ public static function getHelper() * Sign using the version inferred from `$options.version`. * * @param ConnectionInterface $connection A connection to the Cloud Storage - * API. + * API. This object is created by StorageClient, + * and should not be instantiated outside of this client. * @param Timestamp|\DateTimeInterface|int $expires The signed URL * expiration. * @param string $resource The URI to the storage resource, preceded by a * leading slash. * @param int|null $generation The resource generation. * @param array $options Configuration options. See - * {@see Google\Cloud\Storage\StorageObject::signedUrl()} for + * {@see StorageObject::signedUrl()} for * details. * @return string * @throws \InvalidArgumentException @@ -110,14 +111,15 @@ public function sign(ConnectionInterface $connection, $expires, $resource, $gene * This method will be deprecated in the future. * * @param ConnectionInterface $connection A connection to the Cloud Storage - * API. + * API. This object is created by StorageClient, + * and should not be instantiated outside of this client. * @param Timestamp|\DateTimeInterface|int $expires The signed URL * expiration. * @param string $resource The URI to the storage resource, preceded by a * leading slash. * @param int|null $generation The resource generation. * @param array $options Configuration options. See - * {@see Google\Cloud\Storage\StorageObject::signedUrl()} for + * {@see StorageObject::signedUrl()} for * details. * @return string * @throws \InvalidArgumentException @@ -206,14 +208,15 @@ public function v2Sign(ConnectionInterface $connection, $expires, $resource, $ge * Sign a storage URL using Google Signed URLs v4. * * @param ConnectionInterface $connection A connection to the Cloud Storage - * API. + * API. This object is created by StorageClient, + * and should not be instantiated outside of this client. * @param Timestamp|\DateTimeInterface|int $expires The signed URL * expiration. * @param string $resource The URI to the storage resource, preceded by a * leading slash. * @param int|null $generation The resource generation. * @param array $options Configuration options. See - * {@see Google\Cloud\Storage\StorageObject::signedUrl()} for + * {@see StorageObject::signedUrl()} for * details. * @return string * @throws \InvalidArgumentException @@ -362,12 +365,14 @@ public function v4Sign(ConnectionInterface $connection, $expires, $resource, $ge * Create an HTTP POST policy using v4 signing. * * @param ConnectionInterface $connection A Connection to Google Cloud Storage. + * This object is created by StorageClient, + * and should not be instantiated outside of this client. * @param Timestamp|\DateTimeInterface|int $expires The signed URL * expiration. * @param string $resource The URI to the storage resource, preceded by a * leading slash. * @param array $options Configuration options. See - * {@see Google\Cloud\Storage\Bucket::generateSignedPostPolicyV4()} for details. + * {@see Bucket::generateSignedPostPolicyV4()} for details. * @return array An associative array, containing (string) `uri` and * (array) `fields` keys. */ @@ -780,6 +785,8 @@ private function normalizeCanonicalRequestResource($resource, $bucketBoundHostna * Get the credentials for use with signing. * * @param ConnectionInterface $connection A Storage connection object. + * This object is created by StorageClient, + * and should not be instantiated outside of this client. * @param array $options Configuration options. * @return array A list containing a credentials object at index 0 and the * modified options at index 1. diff --git a/lib/Google/vendor/google/cloud-storage/src/StorageClient.php b/lib/Google/vendor/google/cloud-storage/src/StorageClient.php index 723c1a0b3..d79ef9f03 100644 --- a/lib/Google/vendor/google/cloud-storage/src/StorageClient.php +++ b/lib/Google/vendor/google/cloud-storage/src/StorageClient.php @@ -47,7 +47,7 @@ class StorageClient use ArrayTrait; use ClientTrait; - const VERSION = '1.31.2'; + const VERSION = '1.36.0'; const FULL_CONTROL_SCOPE = 'https://www.googleapis.com/auth/devstorage.full_control'; const READ_ONLY_SCOPE = 'https://www.googleapis.com/auth/devstorage.read_only'; @@ -73,6 +73,7 @@ class StorageClient /** * @var ConnectionInterface Represents a connection to Storage. + * @internal */ protected $connection; @@ -126,9 +127,10 @@ public function __construct(array $config = []) } /** - * Lazily instantiates a bucket. There are no network requests made at this - * point. To see the operations that can be performed on a bucket please - * see {@see Google\Cloud\Storage\Bucket}. + * Lazily instantiates a bucket. + * + * There are no network requests made at this point. To see the operations + * that can be performed on a bucket please see {@see Bucket}. * * If `$userProject` is set to true, the current project ID (used to * instantiate the client) will be billed for all requests. If @@ -269,6 +271,10 @@ function (array $bucket) use ($userProject) { * `"projectPrivate"`, and `"publicRead"`. * @type string $predefinedDefaultObjectAcl Apply a predefined set of * default object access controls to this bucket. + * @type bool $enableObjectRetention Whether object retention should + * be enabled on this bucket. For more information, refer to the + * [Object Retention Lock](https://cloud.google.com/storage/docs/object-lock) + * documentation. * @type string $projection Determines which properties to return. May * be either `"full"` or `"noAcl"`. **Defaults to** `"noAcl"`, * unless the bucket resource specifies acl or defaultObjectAcl @@ -306,6 +312,8 @@ function (array $bucket) use ($userProject) { * Buckets can have either StorageClass OLM rules or Autoclass, * but not both. When Autoclass is enabled on a bucket, adding * StorageClass OLM rules will result in failure. + * For more information, refer to + * [Storage Autoclass](https://cloud.google.com/storage/docs/autoclass) * @type array $versioning The bucket's versioning configuration. * @type array $website The bucket's website configuration. * @type array $billing The bucket's billing configuration. @@ -335,7 +343,7 @@ function (array $bucket) use ($userProject) { * occurs, signified by the hold's release. * @type array $retentionPolicy Defines the retention policy for a * bucket. In order to lock a retention policy, please see - * {@see Google\Cloud\Storage\Bucket::lockRetentionPolicy()}. + * {@see Bucket::lockRetentionPolicy()}. * @type int $retentionPolicy.retentionPeriod Specifies the retention * period for objects in seconds. During the retention period an * object cannot be overwritten or deleted. Retention period must @@ -415,7 +423,7 @@ public function unregisterStreamWrapper($protocol = null) * @param string $uri The URI to accept an upload request. * @param string|resource|StreamInterface $data The data to be uploaded * @param array $options [optional] Configuration Options. Refer to - * {@see Google\Cloud\Core\Upload\AbstractUploader::__construct()}. + * {@see \Google\Cloud\Core\Upload\AbstractUploader::__construct()}. * @return SignedUrlUploader */ public function signedUrlUploader($uri, $data, array $options = []) diff --git a/lib/Google/vendor/google/cloud-storage/src/StorageObject.php b/lib/Google/vendor/google/cloud-storage/src/StorageObject.php index c910aa2e6..e2c207a12 100644 --- a/lib/Google/vendor/google/cloud-storage/src/StorageObject.php +++ b/lib/Google/vendor/google/cloud-storage/src/StorageObject.php @@ -57,6 +57,7 @@ class StorageObject /** * @var ConnectionInterface Represents a connection to Cloud Storage. + * @internal */ protected $connection; @@ -77,7 +78,8 @@ class StorageObject /** * @param ConnectionInterface $connection Represents a connection to Cloud - * Storage. + * Storage. This object is created by StorageClient, + * and should not be instantiated outside of this client. * @param string $name The object's name. * @param string $bucket The name of the bucket the object is contained in. * @param string $generation [optional] The generation of the object. @@ -222,6 +224,18 @@ public function delete(array $options = []) * Acceptable values include, `"authenticatedRead"`, * `"bucketOwnerFullControl"`, `"bucketOwnerRead"`, `"private"`, * `"projectPrivate"`, and `"publicRead"`. + * @type array $retention The full list of available options are outlined + * at the [JSON API docs](https://cloud.google.com/storage/docs/json_api/v1/objects/update#request-body). + * @type string $retention.retainUntilTime The earliest time in RFC 3339 + * UTC "Zulu" format that the object can be deleted or replaced. + * This is the retention configuration set for this object. + * @type string $retention.mode The mode of the retention configuration, + * which can be either `"Unlocked"` or `"Locked"`. + * @type bool $overrideUnlockedRetention Applicable for objects that + * have an unlocked retention configuration. Required to be set to + * `true` if the operation includes a retention property that + * changes the mode to `Locked`, reduces the `retainUntilTime`, or + * removes the retention configuration from the object. * @type string $projection Determines which properties to return. May * be either 'full' or 'noAcl'. * @type string $fields Selector which will cause the response to only @@ -546,7 +560,7 @@ public function rename($name, array $options = []) * Download an object as a string. * * For an example of setting the range header to download a subrange of the - * object please see {@see Google\Cloud\Storage\StorageObject::downloadAsStream()}. + * object please see {@see StorageObject::downloadAsStream()}. * * Example: * ``` @@ -580,7 +594,7 @@ public function downloadAsString(array $options = []) * Download an object to a specified location. * * For an example of setting the range header to download a subrange of the - * object please see {@see Google\Cloud\Storage\StorageObject::downloadAsStream()}. + * object please see {@see StorageObject::downloadAsStream()}. * * Example: * ``` @@ -684,7 +698,7 @@ public function downloadAsStream(array $options = []) * Asynchronously download an object as a stream. * * For an example of setting the range header to download a subrange of the - * object please see {@see Google\Cloud\Storage\StorageObject::downloadAsStream()}. + * object please see {@see StorageObject::downloadAsStream()}. * * Example: * ``` @@ -700,7 +714,7 @@ public function downloadAsStream(array $options = []) * * ``` * // Download all objects in a bucket asynchronously. - * use GuzzleHttp\Promise; + * use GuzzleHttp\Promise\Utils; * use Psr\Http\Message\StreamInterface; * * $promises = []; @@ -712,7 +726,7 @@ public function downloadAsStream(array $options = []) * }); * } * - * Promise\unwrap($promises); + * Utils::unwrap($promises); * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/objects/get Objects get API documentation. @@ -763,10 +777,10 @@ public function downloadAsStreamAsync(array $options = []) * Token Creator" IAM role. * * Additionally, signing using IAM requires different scopes. When creating - * an instance of {@see Google\Cloud\Storage\StorageClient}, provide the + * an instance of {@see StorageClient}, provide the * `https://www.googleapis.com/auth/cloud-platform` scopein `$options.scopes`. * This scope may be used entirely in place of the scopes provided in - * {@see Google\Cloud\Storage\StorageClient}. + * {@see StorageClient}. * * App Engine and Compute Engine will attempt to sign URLs using IAM. * @@ -811,7 +825,7 @@ public function downloadAsStreamAsync(array $options = []) * @see https://cloud.google.com/storage/docs/access-control/signed-urls Signed URLs * * @param Timestamp|\DateTimeInterface|int $expires Specifies when the URL - * will expire. May provide an instance of {@see Google\Cloud\Core\Timestamp}, + * will expire. May provide an instance of {@see \Google\Cloud\Core\Timestamp}, * [http://php.net/datetimeimmutable](`\DateTimeImmutable`), or a * UNIX timestamp as an integer. * @param array $options { @@ -904,7 +918,7 @@ public function signedUrl($expires, array $options = []) /** * Create a Signed Upload URL for this object. * - * This method differs from {@see Google\Cloud\Storage\StorageObject::signedUrl()} + * This method differs from {@see StorageObject::signedUrl()} * in that it allows you to initiate a new resumable upload session. This * can be used to allow non-authenticated users to insert an object into a * bucket. @@ -915,7 +929,7 @@ public function signedUrl($expires, array $options = []) * more information. * * If you prefer to skip this initial step, you may find - * {@see Google\Cloud\Storage\StorageObject::beginSignedUploadSession()} to + * {@see StorageObject::beginSignedUploadSession()} to * fit your needs. Note that `beginSignedUploadSession()` cannot be used * with Google Cloud PHP's Signed URL Uploader, and does not support a * configurable expiration date. @@ -933,7 +947,7 @@ public function signedUrl($expires, array $options = []) * ``` * * @param Timestamp|\DateTimeInterface|int $expires Specifies when the URL - * will expire. May provide an instance of {@see Google\Cloud\Core\Timestamp}, + * will expire. May provide an instance of {@see \Google\Cloud\Core\Timestamp}, * [http://php.net/datetimeimmutable](`\DateTimeImmutable`), or a * UNIX timestamp as an integer. * @param array $options { @@ -1014,7 +1028,7 @@ public function signedUploadUrl($expires, array $options = []) * Create a signed URL upload session. * * The returned URL differs from the return value of - * {@see Google\Cloud\Storage\StorageObject::signedUploadUrl()} in that it + * {@see StorageObject::signedUploadUrl()} in that it * is ready to accept upload data immediately via an HTTP PUT request. * * Because an upload session is created by the client, the expiration date diff --git a/lib/Google/vendor/google/cloud-storage/src/WriteStream.php b/lib/Google/vendor/google/cloud-storage/src/WriteStream.php index c78bcc91a..ba5d07fbc 100644 --- a/lib/Google/vendor/google/cloud-storage/src/WriteStream.php +++ b/lib/Google/vendor/google/cloud-storage/src/WriteStream.php @@ -60,7 +60,7 @@ public function __construct(AbstractUploader $uploader = null, $options = []) /** * Close the stream. Uploads any remaining data. */ - public function close() + public function close(): void { if ($this->uploader && $this->hasWritten) { $this->uploader->upload(); @@ -75,7 +75,7 @@ public function close() * @return int The number of bytes written * @throws \RuntimeException */ - public function write($data) + public function write($data): int { if (!isset($this->uploader)) { throw new \RuntimeException("No uploader set."); @@ -98,12 +98,12 @@ public function write($data) * * @param AbstractUploader $uploader The new uploader to use. */ - public function setUploader($uploader) + public function setUploader($uploader): void { $this->uploader = $uploader; } - private function getChunkedWriteSize() + private function getChunkedWriteSize(): int { return (int) floor($this->getSize() / $this->chunkSize) * $this->chunkSize; } diff --git a/lib/Google/vendor/google/crc32/.github/workflows/test.yml b/lib/Google/vendor/google/crc32/.github/workflows/test.yml deleted file mode 100644 index d5a072b40..000000000 --- a/lib/Google/vendor/google/crc32/.github/workflows/test.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: PHP CRC32 - -on: [push] - -jobs: - lint: - runs-on: ubuntu-latest - strategy: - matrix: - # No need to lint on every version, so pin this to the most recent version. - php-version: ['8.2'] - - steps: - - uses: actions/checkout@v3 - - - name: Setup PHP ${{ matrix.php-version }} with tools - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - tools: php-cs-fixer - - - name: Lint - run: make lint - - test: - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-latest] - php-version: ['7.4', '8.0', '8.1', '8.2'] - - steps: - - uses: actions/checkout@v3 - - - name: Setup PHP ${{ matrix.php-version }} with tools - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - tools: phpunit phpize php-config - - - name: Install dependencies - run: composer install --prefer-dist - - - name: Test - run: make test diff --git a/lib/Google/vendor/google/crc32/.gitignore b/lib/Google/vendor/google/crc32/.gitignore deleted file mode 100644 index c9860255d..000000000 --- a/lib/Google/vendor/google/crc32/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -vendor -.php_cs.cache -ext/.deps -ext/crc32c -*~ -composer.lock diff --git a/lib/Google/vendor/google/crc32/CONTRIBUTING.md b/lib/Google/vendor/google/crc32/CONTRIBUTING.md deleted file mode 100644 index ae4e04324..000000000 --- a/lib/Google/vendor/google/crc32/CONTRIBUTING.md +++ /dev/null @@ -1,28 +0,0 @@ -# How to Contribute - -We'd love to accept your patches and contributions to this project. There are -just a few small guidelines you need to follow. - -## Contributor License Agreement - -Contributions to this project must be accompanied by a Contributor License -Agreement. You (or your employer) retain the copyright to your contribution; -this simply gives us permission to use and redistribute your contributions as -part of the project. Head over to to see -your current agreements on file or to sign a new one. - -You generally only need to submit a CLA once, so if you've already submitted one -(even if it was for a different project), you probably don't need to do it -again. - -## Code reviews - -All submissions, including submissions by project members, require review. We -use GitHub pull requests for this purpose. Consult -[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more -information on using pull requests. - -## Community Guidelines - -This project follows [Google's Open Source Community -Guidelines](https://opensource.google.com/conduct/). \ No newline at end of file diff --git a/lib/Google/vendor/google/crc32/LICENSE b/lib/Google/vendor/google/crc32/LICENSE deleted file mode 100644 index 261eeb9e9..000000000 --- a/lib/Google/vendor/google/crc32/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/lib/Google/vendor/google/crc32/Makefile b/lib/Google/vendor/google/crc32/Makefile deleted file mode 100644 index 8bd47ccc6..000000000 --- a/lib/Google/vendor/google/crc32/Makefile +++ /dev/null @@ -1,71 +0,0 @@ -## -# Copyright 2019 Google Inc. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -## - -.PHONY : all clean benchmark test test_all lint ext ext_test - -COMPOSER ?= composer -PHP_CS_FIXER ?= vendor/bin/php-cs-fixer -PHP_UNIT ?= vendor/bin/phpunit - -PHP_BIN ?= $(shell php-config --prefix)/bin -PHP ?= $(PHP_BIN)/php -PHP_CONFIG ?= $(PHP_BIN)/php-config -PHPIZE ?= $(PHP_BIN)/phpize - -all: lint test - -clean: - -rm -r .php_cs.cache - $(MAKE) -C ext clean - -vendor: composer.lock -composer.lock: composer.json - $(COMPOSER) update - touch composer.lock - -lint: vendor - $(PHP_CS_FIXER) fix --dry-run --diff src - $(PHP_CS_FIXER) fix --dry-run --diff crc32_benchmark.php - $(PHP_CS_FIXER) fix --dry-run --diff tests - $(PHP_CS_FIXER) fix --dry-run --diff ext/tests - -benchmark: ext vendor - $(PHP) -d extension=ext/modules/crc32c.so crc32_benchmark.php - -test: ext vendor - $(PHP) -v - $(PHP) -d extension=ext/modules/crc32c.so $(PHP_UNIT) tests/ - -# Test all the local versions of PHP -test_all: - for phpize in $$(ls $$(brew --prefix)/Cellar/php*/*/bin/phpize); do \ - NO_INTERACTION=1 \ - PHP_BIN=$$(dirname $$phpize) \ - $(MAKE) clean test; \ - done - -ext: ext/modules/crc32c.so - -ext_test: ext - NO_INTERACTION=1 $(MAKE) -C ext test - -ext/modules/crc32c.so: ext/hash_crc32c.c ext/php_crc32c.c ext/php_crc32c.h - cd ext && \ - ./install_crc32c.sh && \ - $(PHPIZE) && \ - ./configure \ - --with-php-config=$(PHP_CONFIG) && \ - $(MAKE) diff --git a/lib/Google/vendor/google/crc32/README.md b/lib/Google/vendor/google/crc32/README.md deleted file mode 100644 index c2bbc58e3..000000000 --- a/lib/Google/vendor/google/crc32/README.md +++ /dev/null @@ -1,138 +0,0 @@ -# php-crc32 - -![Build Status](https://github.com/google/php-crc32/actions/workflows/test.yml/badge.svg) - -by [Andrew Brampton](https://bramp.net) - -**Deprecated**: Since PHP 8.0, the crc32 algorithms within PHP are using [hardware accelerated instructions](https://github.com/php/php-src/commit/c3299d7dab15aeed52a34535f1967d426f5327de), and are surprisingly fast. Thus this extension is not needed anymore! - -CRC32 implementations, that support all crc32 polynomials, as well as (if you -install the pecl extension) hardware accelerated versions of CRC32C (Castagnoli). - -Supports PHP 7.4 though PHP 8.2. Older PHP versions are supported with "v0.1.0". - -# Usage - -```php -require 'vendor/autoload.php'; - -use Google\CRC32\CRC32; - -$crc = CRC32::create(CRC32::CASTAGNOLI); -$crc->update('hello'); -echo $crc->hash(); -``` - -Depending on the environment and the polynomial, `CRC32::create` will choose -the fastest available version, and return one of the following classes: - -* `Google\CRC32\PHP` - A pure PHP implementation. -* `Google\CRC32\Builtin` - A [PHP Hash framework](http://php.net/manual/en/book.hash.php) implementation. -* `Google\CRC32\Google` - A hardware accelerated implementation (using [google/crc32c](https://github.com/google/crc32c)). - -When reading 1M byte chunks, using `CRC32::CASTAGNOLI` with PHP 7.4 on a 2014 Macbook Pro we get the following performance (higher is better): - -``` -Google\CRC32\PHP 12.27 MB/s -Google\CRC32\Builtin 468.74 MB/s (available since PHP 7.4) -Google\CRC32\Google 24,684.46 MB/s (using crc32c.so) -``` - -# Install - -```shell -$ composer require google/crc32 -``` - -# crc32c.so - -To use the hardware accelerated, a custom PHP extension must be installed. This makes use of [google/crc32c](https://github.com/google/crc32c) which provides a highly optomised `CRC32C` (Castagnoli) implementation using the SSE 4.2 instruction set of Intel CPUs. - -The extension can be installed from pecl, or compiled from stratch. - -```shell -TODO pecl install crc32c -``` - -Once installed or compiled, you'll need to add `extension=crc32c.so` to your php.ini file. - -## Compile (Linux / Mac) - -Ensure that [composer](https://getcomposer.org), build tools (e.g [build-essential](https://packages.debian.org/sid/devel/build-essential), [cmake](https://packages.debian.org/sid/devel/cmake), etc), and php dev headers (e.g [php-dev](https://packages.debian.org/sid/php/php-dev)) are installed. - -Simple (using Makefile): - -```shell -make test -``` - -Alternatively (manually): - -```shell -cd ext - -# Install the google/crc32c library -./install_crc32c.sh # From source (recommended) - -# or use your favorite package manager, e.g. -# brew install crc32c - -# Prepare the build environment -phpize -./configure - -# or if using a custom crc32c -# ./configure --with-crc32c=$(brew --prefix crc32c) - -## Build and test -make test -``` - -The extension will now be at `ext/modules/crc32c.so`. This file should be copied to your [extension directory](https://php.net/extension-dir) and reference in your php.ini. - -``` -# php.ini -extension=crc32c.so -``` - -## Testing - -`make test` will test with the current PHP. `make test_all` will search for available -PHP installs, and test with all of them. - -## Benchmark - -To compare the performance of the different `CRC32C` implementations, run `make benchmark`. - -# Related - -* https://bugs.php.net/bug.php?id=71890 - -# TODO - -- [ ] Test if this works on 32 bit machine. -- [x] Add php unit (or similar) testing. -- [x] Publish to packagist -- [ ] Publish to pecl (https://pecl.php.net/account-request.php) -- [x] Update instructions for linux. - - -# Licence (Apache 2) - -*This is not an official Google product (experimental or otherwise), it is just code that happens to be owned by Google.* - -``` -Copyright 2023 Google Inc. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -``` diff --git a/lib/Google/vendor/google/crc32/composer.json b/lib/Google/vendor/google/crc32/composer.json deleted file mode 100644 index a253cd7e4..000000000 --- a/lib/Google/vendor/google/crc32/composer.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "google/crc32", - "description": "Various CRC32 implementations", - "homepage": "https://github.com/google/php-crc32", - "type": "library", - "license": "Apache-2.0", - "authors": [ - { - "name": "Andrew Brampton", - "email": "bramp@google.com" - } - ], - "require": { - "php": ">=7.4" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "v3.15", - "phpunit/phpunit": "^9" - }, - "autoload": { - "psr-4": { - "Google\\CRC32\\": "src" - } - } -} diff --git a/lib/Google/vendor/google/crc32/crc32_benchmark.php b/lib/Google/vendor/google/crc32/crc32_benchmark.php deleted file mode 100644 index 065bdc275..000000000 --- a/lib/Google/vendor/google/crc32/crc32_benchmark.php +++ /dev/null @@ -1,112 +0,0 @@ -update($chunk); - - $i++; - $now = microtime(true); - $duration = ($now - $start); - - if ($duration >= max_duration) { - break; - } - if ($duration >= min_duration && $i >= min_iterations) { - break; - } - } - - // Very quick sanity check - if ($crc->hash() == '00000000') { - exit($name . ' crc check failed'); - } - - - $bytes = $i * $chunk_size; - - echo sprintf("%s\t%10d\t%5d\t%8.2f MB/s\n", $name, $chunk_size, $i, $bytes / ($now - $start) / 1000000); -} - -foreach (array(256, 4096, 1048576, 16777216) as $chunk_size) { - test(new PHP(CRC32::CASTAGNOLI), $chunk_size); - //test(new PHPSlicedBy4(CRC32::CASTAGNOLI), $chunk_size); - test(new Builtin(CRC32::CASTAGNOLI), $chunk_size); - test(new Google(), $chunk_size); -} diff --git a/lib/Google/vendor/google/crc32/ext/.gitignore b/lib/Google/vendor/google/crc32/ext/.gitignore deleted file mode 100644 index 91bef2522..000000000 --- a/lib/Google/vendor/google/crc32/ext/.gitignore +++ /dev/null @@ -1,35 +0,0 @@ -*.lo -*.la -.libs -acinclude.m4 -aclocal.m4 -autom4te.cache -build -config.guess -config.h -config.h.in -config.log -config.nice -config.status -config.sub -configure -configure.ac -configure.in -include -install-sh -libtool -ltmain.sh -Makefile -Makefile.fragments -Makefile.global -Makefile.objects -missing -mkinstalldirs -modules -run-tests.php -tests/*/*.diff -tests/*/*.out -tests/*/*.php -tests/*/*.exp -tests/*/*.log -tests/*/*.sh diff --git a/lib/Google/vendor/google/crc32/ext/config.m4 b/lib/Google/vendor/google/crc32/ext/config.m4 deleted file mode 100644 index c3d3d2e89..000000000 --- a/lib/Google/vendor/google/crc32/ext/config.m4 +++ /dev/null @@ -1,63 +0,0 @@ -dnl Copyright 2019 Google Inc. All Rights Reserved. -dnl -dnl Licensed under the Apache License, Version 2.0 (the "License"); -dnl you may not use this file except in compliance with the License. -dnl You may obtain a copy of the License at -dnl -dnl http://www.apache.org/licenses/LICENSE-2.0 -dnl -dnl Unless required by applicable law or agreed to in writing, software -dnl distributed under the License is distributed on an "AS-IS" BASIS, -dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -dnl See the License for the specific language governing permissions and -dnl limitations under the License. -dnl - -PHP_ARG_WITH(crc32c, for crc32c support, -[ --with-crc32c[=DIR] Include crc32c support. File is the optional path to google/crc32c]) - -if test "$PHP_CRC32C" != "no"; then - PHP_REQUIRE_CXX() # The external crc32c library uses C++. - - if test -r $PHP_CRC32C/; then - SEARCH_PATH=$PHP_CRC32C - else - SEARCH_PATH="$PWD/crc32c/build /usr/local /usr" - fi - - - AC_MSG_CHECKING([for crc32c files]) - SEARCH_FOR="include/crc32c/crc32c.h" - - for i in $SEARCH_PATH ; do - if test -r $i/$SEARCH_FOR; then - CRC32C_DIR=$i - AC_MSG_RESULT(found in $i) - fi - done - - # --with-crc32c -> check with-path - if test -z "$CRC32C_DIR"; then - AC_MSG_RESULT([not found]) - AC_MSG_ERROR([Please install the google/crc32c package, and use --with-crc32c]) - fi - - # --with-crc32c -> add include path - PHP_ADD_INCLUDE($CRC32C_DIR/include) - - # --with-crc32c -> check for lib and symbol presence - LIBNAME=crc32c - LIBSYMBOL=crc32c_extend - - PHP_CHECK_LIBRARY($LIBNAME, $LIBSYMBOL, - [ - PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $CRC32C_DIR/$PHP_LIBDIR, CRC32C_SHARED_LIBADD) - ],[ - AC_MSG_FAILURE([wrong crc32c lib version or lib not found]) - ],[ - -L$CRC32C_DIR/$PHP_LIBDIR -lm - ]) - - PHP_SUBST(CRC32C_SHARED_LIBADD) - PHP_NEW_EXTENSION(crc32c, hash_crc32c.c php_crc32c.c, $ext_shared, , -Wall -Werror) -fi diff --git a/lib/Google/vendor/google/crc32/ext/hash_crc32c.c b/lib/Google/vendor/google/crc32/ext/hash_crc32c.c deleted file mode 100644 index a622a1c6f..000000000 --- a/lib/Google/vendor/google/crc32/ext/hash_crc32c.c +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Copyright 2019 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * crc32c hash extension for PHP - * - * This file contains the crc32c hash function for - * http://php.net/manual/en/function.hash.php - */ -#include "php_crc32c.h" - -#include "ext/hash/php_hash.h" -#include "ext/hash/php_hash_crc32.h" - -#include "crc32c/crc32c.h" - -PHP_HASH_API void CRC32CInit(PHP_CRC32_CTX *context -#if PHP_API_VERSION >= 20201213 -, ZEND_ATTRIBUTE_UNUSED HashTable *args -#endif -) -{ - context->state = 0; -} - -PHP_HASH_API void CRC32CUpdate(PHP_CRC32_CTX *context, const unsigned char *input, size_t len) -{ - context->state = crc32c_extend(context->state, input, len); -} - -PHP_HASH_API void CRC32CFinal(uint8_t crc[4], PHP_CRC32_CTX *context) -{ - int2byte(context->state, crc); - context->state = 0; -} - -PHP_HASH_API int CRC32CCopy(const php_hash_ops *ops, PHP_CRC32_CTX *orig_context, PHP_CRC32_CTX *copy_context) -{ - copy_context->state = orig_context->state; - return SUCCESS; -} - -const php_hash_ops crc32_ops = { -#if PHP_API_VERSION >= 20200620 - "crc32c", -#endif - (php_hash_init_func_t) CRC32CInit, - (php_hash_update_func_t) CRC32CUpdate, - (php_hash_final_func_t) CRC32CFinal, - (php_hash_copy_func_t) CRC32CCopy, -#if PHP_API_VERSION >= 20200620 - php_hash_serialize, - php_hash_unserialize, - PHP_CRC32_SPEC, -#endif - 4, /* what to say here? */ - 4, - sizeof(PHP_CRC32_CTX), -#if PHP_API_VERSION >= 20170718 - 0 -#endif -}; \ No newline at end of file diff --git a/lib/Google/vendor/google/crc32/ext/install_crc32c.sh b/lib/Google/vendor/google/crc32/ext/install_crc32c.sh deleted file mode 100755 index 96b27c52d..000000000 --- a/lib/Google/vendor/google/crc32/ext/install_crc32c.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh -# Used to build and install the google/crc32c library. - -## -# Copyright 2019 Google Inc. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -## - -git clone https://github.com/google/crc32c - -cd crc32c -git submodule update --init --recursive - -mkdir build -cd build -cmake -DCRC32C_BUILD_TESTS=0 \ - -DCRC32C_BUILD_BENCHMARKS=0 \ - -DCRC32C_USE_GLOG=0 \ - -DBUILD_SHARED_LIBS=0 \ - -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE \ - -DCMAKE_INSTALL_PREFIX:PATH=$PWD \ - .. -cmake --build . --target install diff --git a/lib/Google/vendor/google/crc32/ext/php_crc32c.c b/lib/Google/vendor/google/crc32/ext/php_crc32c.c deleted file mode 100644 index ba08657be..000000000 --- a/lib/Google/vendor/google/crc32/ext/php_crc32c.c +++ /dev/null @@ -1,174 +0,0 @@ -/** - * Copyright 2019 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * crc32c extension for PHP - * - * This file sets up the crc32c module, and provide the 'crc32c' function. - */ - -#include "php_crc32c.h" - -#include "ext/hash/php_hash.h" -#include "ext/standard/info.h" - -#include "crc32c/crc32c.h" - -extern const php_hash_ops crc32_ops; - -static uint32_t byte2int(const uint8_t hash[4]) { - return (hash[0] << 24) | (hash[1] << 16) | (hash[2] << 8) | hash[3]; -} - -/* {{{ int crc32c( string $data [, int $crc ] ) - */ -PHP_FUNCTION(crc32c) -{ - char *data_arg = NULL; - size_t data_len = 0; - char *crc_arg = NULL; - size_t crc_len = 0; - -#if PHP_API_VERSION >= 20151012 /* >= PHP 7.0 */ - // fast_zpp is a faster way to parse paramters. - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STRING(data_arg, data_len) - Z_PARAM_OPTIONAL - Z_PARAM_STRING_EX(crc_arg, crc_len, /* check_null */ 1, 0) - ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); -#else - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!", &data_arg, &data_len, &crc_arg, &crc_len) == FAILURE) { - RETURN_BOOL(false); - } -#endif - - uint32_t crc = 0; - - if (crc_len == 4) { - crc = byte2int((uint8_t *)crc_arg); - - } else if (crc_arg != NULL) { - zend_error(E_WARNING, "crc32c(): Supplied crc must be a 4 byte string"); - RETURN_BOOL(false); - } - - crc = crc32c_extend(crc, (const uint8_t *)data_arg, data_len); - - uint8_t hash[4]; - int2byte(crc, hash); - -#if PHP_API_VERSION >= 20151012 /* >= PHP 7.0 */ - RETURN_STRINGL((const char *)hash, sizeof(hash)); -#else - RETURN_STRINGL((const char *)hash, sizeof(hash), /* dup */ 1); -#endif -} -/* }}}*/ - - -/* {{{ PHP_RINIT_FUNCTION - */ -PHP_RINIT_FUNCTION(crc32c) -{ -#if PHP_VERSION_ID >= 70000 -# if defined(ZTS) && defined(COMPILE_DL_CRC32C) - ZEND_TSRMLS_CACHE_UPDATE(); -# endif -#endif - - return SUCCESS; -} -/* }}} */ - -/* {{{ PHP_MINIT_FUNCTION - */ -PHP_MINIT_FUNCTION(crc32c) -{ - php_hash_register_algo("crc32c", &crc32_ops); - return SUCCESS; -} -/* }}} */ - -/* {{{ PHP_MSHUTDOWN_FUNCTION - */ -PHP_MSHUTDOWN_FUNCTION(crc32c) -{ - // TODO Unregister php_hash_register_algo - return SUCCESS; -} -/* }}} */ - -/* {{{ PHP_MINFO_FUNCTION - */ -PHP_MINFO_FUNCTION(crc32c) -{ - php_info_print_table_start(); - php_info_print_table_header(2, "Google CRC32C support", "enabled"); - php_info_print_table_end(); -} -/* }}} */ - -/* {{{ arginfo - */ -ZEND_BEGIN_ARG_INFO_EX(arginfo_crc32c, 0, 0, 1) - ZEND_ARG_INFO(0, str) - ZEND_ARG_INFO(0, crc) -ZEND_END_ARG_INFO() -/* }}} */ - -/* {{{ crc32c_functions[] - */ -static const zend_function_entry crc32c_functions[] = { - PHP_FE(crc32c, arginfo_crc32c) - PHP_FE_END -}; -/* }}} */ - -/* {{{ crc32c_deps - */ -static const zend_module_dep crc32c_deps[] = { - ZEND_MOD_REQUIRED("hash") - ZEND_MOD_END -}; -/* }}} */ - -/* {{{ crc32c_module_entry - */ -zend_module_entry crc32c_module_entry = { - STANDARD_MODULE_HEADER_EX, NULL, - crc32c_deps, /* Module dependencies */ - "crc32c", /* Extension name */ - crc32c_functions, /* zend_function_entry */ - PHP_MINIT(crc32c), /* PHP_MINIT - Module initialization */ - PHP_MSHUTDOWN(crc32c), /* PHP_MSHUTDOWN - Module shutdown */ - PHP_RINIT(crc32c), /* PHP_RINIT - Request initialization */ - NULL, /* PHP_RSHUTDOWN - Request shutdown */ - PHP_MINFO(crc32c), /* PHP_MINFO - Module info */ - PHP_CRC32C_VERSION, /* Version */ - STANDARD_MODULE_PROPERTIES -}; -/* }}} */ - -#ifdef COMPILE_DL_CRC32C - -# if PHP_VERSION_ID >= 70000 -# ifdef ZTS -ZEND_TSRMLS_CACHE_DEFINE() -# endif -# endif /* PHP_VERSION_ID >= 70000 */ - -ZEND_GET_MODULE(crc32c) -#endif /* COMPILE_DL_CRC32C */ diff --git a/lib/Google/vendor/google/crc32/ext/php_crc32c.h b/lib/Google/vendor/google/crc32/ext/php_crc32c.h deleted file mode 100644 index 661d79f20..000000000 --- a/lib/Google/vendor/google/crc32/ext/php_crc32c.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright 2019 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * crc32c extension for PHP - */ -#ifndef PHP_CRC32C_H -# define PHP_CRC32C_H - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "php.h" - -#include -#include - -#ifdef ZTS -# include "TSRM.h" -#endif - -extern zend_module_entry crc32c_module_entry; - -# define PHP_CRC32C_VERSION "1.0.0" - -# if PHP_VERSION_ID >= 70000 -# if defined(ZTS) && defined(COMPILE_DL_CRC32C) -ZEND_TSRMLS_CACHE_EXTERN() -# endif -# endif - -static void int2byte(uint32_t i, uint8_t b[4]) { - b[0] = (uint8_t) ((i >> 24) & 0xff); - b[1] = (uint8_t) ((i >> 16) & 0xff); - b[2] = (uint8_t) ((i >> 8) & 0xff); - b[3] = (uint8_t) (i & 0xff); -} - -#endif /* PHP_CRC32C_H */ diff --git a/lib/Google/vendor/google/crc32/ext/tests/001_loaded.phpt b/lib/Google/vendor/google/crc32/ext/tests/001_loaded.phpt deleted file mode 100644 index 8787e9d40..000000000 --- a/lib/Google/vendor/google/crc32/ext/tests/001_loaded.phpt +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -crc32c() is loadable ---SKIPIF-- - ---FILE-- - ---EXPECT-- -The extension "crc32c" is available diff --git a/lib/Google/vendor/google/crc32/ext/tests/002_basic.phpt b/lib/Google/vendor/google/crc32/ext/tests/002_basic.phpt deleted file mode 100644 index 9d265b8b9..000000000 --- a/lib/Google/vendor/google/crc32/ext/tests/002_basic.phpt +++ /dev/null @@ -1,93 +0,0 @@ ---TEST-- -crc32c() basic tests ---SKIPIF-- - ---FILE-- -?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"), "\n"; -?> ---EXPECT-- -00000000 -c1d04330 -e2a22936 -364b3fb7 -92c80a31 -c450d697 -53bceff1 -e627f441 -0a9421b7 -2ddc99fc -e6599437 -9ee6ef25 -a245d57d -477a6781 -02bd79d0 -5e405e93 -516ad412 -b2cc01fe -0e28207f -be93f964 -9e3be0c3 -f505ef04 -85d3dc82 -c5142380 -75eb77dd -91ebe9f7 -f0b1168e -572b74e2 -8a58a6d5 -9c426c50 -735400a4 -bec49c95 -a95a2079 -de2e65c5 -297a88ed -66ed1d8b -dcded527 -9c44184b diff --git a/lib/Google/vendor/google/crc32/ext/tests/003_extend.phpt b/lib/Google/vendor/google/crc32/ext/tests/003_extend.phpt deleted file mode 100644 index e1d41046b..000000000 --- a/lib/Google/vendor/google/crc32/ext/tests/003_extend.phpt +++ /dev/null @@ -1,47 +0,0 @@ ---TEST-- -crc32c() extend tests ---SKIPIF-- - ---FILE-- - ---EXPECT-- -2c775665 -2c775665 -5e2b5be5 -319897cd -2f6298bc -86bd0651 -a245d57d -a245d57d \ No newline at end of file diff --git a/lib/Google/vendor/google/crc32/ext/tests/004_error.phpt b/lib/Google/vendor/google/crc32/ext/tests/004_error.phpt deleted file mode 100644 index c5da06410..000000000 --- a/lib/Google/vendor/google/crc32/ext/tests/004_error.phpt +++ /dev/null @@ -1,36 +0,0 @@ ---TEST-- -crc32c() errors test ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -string(4) ",wVe" - -Warning: crc32c(): Supplied crc must be a 4 byte string in %s on line %d -bool(false) - -Warning: crc32c(): Supplied crc must be a 4 byte string in %s on line %d -bool(false) - -Warning: crc32c(): Supplied crc must be a 4 byte string in %s on line %d -bool(false) - -Warning: crc32c(): Supplied crc must be a 4 byte string in %s on line %d -bool(false) \ No newline at end of file diff --git a/lib/Google/vendor/google/crc32/ext/tests/005_hash.phpt b/lib/Google/vendor/google/crc32/ext/tests/005_hash.phpt deleted file mode 100644 index e82f4417d..000000000 --- a/lib/Google/vendor/google/crc32/ext/tests/005_hash.phpt +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -crc32c() hash tests ---SKIPIF-- - ---FILE-- - ---EXPECT-- -bool(true) -a245d57d \ No newline at end of file diff --git a/lib/Google/vendor/google/crc32/ext/tests/006_serialize.phpt b/lib/Google/vendor/google/crc32/ext/tests/006_serialize.phpt deleted file mode 100644 index 7b2b2ac45..000000000 --- a/lib/Google/vendor/google/crc32/ext/tests/006_serialize.phpt +++ /dev/null @@ -1,26 +0,0 @@ ---TEST-- -crc32c() serialize tests ---SKIPIF-- - ---FILE-- - ---EXPECT-- -bool(true) -a245d57d \ No newline at end of file diff --git a/lib/Google/vendor/google/crc32/src/Builtin.php b/lib/Google/vendor/google/crc32/src/Builtin.php deleted file mode 100644 index 9cb10854c..000000000 --- a/lib/Google/vendor/google/crc32/src/Builtin.php +++ /dev/null @@ -1,88 +0,0 @@ - 'crc32b', - CRC32::CASTAGNOLI => 'crc32c', // Added since PHP 7.4 - ]; - - /** - * Returns true if this $polynomial is supported by the builtin PHP hash function. - * - * @param integer $polynomial The polynomial - * - * @return boolean - */ - public static function supports($polynomial) - { - if (!isset(self::$mapping[$polynomial])) { - return false; - } - $algo = self::$mapping[$polynomial]; - return in_array($algo, hash_algos()); - } - - public function __construct($polynomial) - { - if (!self::supports($polynomial)) { - throw new \InvalidArgumentException("hash_algos() does not list this polynomial."); - } - - $this->algo = self::$mapping[$polynomial]; - $this->reset(); - } - - public function reset() - { - $this->hc = hash_init($this->algo); - } - - public function update($data) - { - hash_update($this->hc, $data); - } - - public function hash($raw_output = false) - { - // hash_final will destory the Hash Context resource, so operate on a copy. - $hc = hash_copy($this->hc); - return hash_final($hc, $raw_output); - } - - public function version() - { - return $this->algo . ' PHP HASH'; - } - - public function __clone() - { - $this->hc = hash_copy($this->hc); - } -} diff --git a/lib/Google/vendor/google/crc32/src/CRC32.php b/lib/Google/vendor/google/crc32/src/CRC32.php deleted file mode 100644 index 278283c40..000000000 --- a/lib/Google/vendor/google/crc32/src/CRC32.php +++ /dev/null @@ -1,112 +0,0 @@ -update('hello'); - * - * echo $crc->hash(); - * ``` - */ -class CRC32 -{ - use CRCTrait; - - /** - * IEEE polynomial as used by ethernet (IEEE 802.3), v.42, fddi, gzip, - * zip, png, ... - */ - public const IEEE = 0xedb88320; - - /** - * Castagnoli's polynomial, used in iSCSI, SCTP, Google Cloud Storage, - * Apache Kafka, and has hardware-accelerated in modern intel CPUs. - * https://doi.org/10.1109/26.231911 - */ - public const CASTAGNOLI = 0x82f63b78; - - /** - * Koopman's polynomial. - * https://doi.org/10.1109/DSN.2002.1028931 - */ - public const KOOPMAN = 0xeb31d82e; - - /** - * The size of the checksum in bytes. - */ - public const SIZE = 4; - - private static $mapping = [ - self::IEEE => 'IEEE', - self::CASTAGNOLI => 'Castagnoli', - self::KOOPMAN => 'Koopman', - ]; - - private function __construct() - { - // Prevent instantiation. - } - - /** - * Returns the best CRC implementation available on this machine. - * - * @param integer $polynomial The CRC polynomial. Use a 32-bit number, - * or one of the supplied constants, CRC32::IEEE, - * CRC32::CASTAGNOLI, or CRC32::KOOPMAN. - * - * @return CRC32Interface - */ - public static function create($polynomial) - { - if (Google::supports($polynomial) && function_exists('crc32c')) { - return new Google(); - } - - if (Builtin::supports($polynomial)) { - return new Builtin($polynomial); - } - - // Fallback to the pure PHP version - return new PHP($polynomial); - } - - /** - * Prints the human friendly name for this polynomial. - * - * @param integer $polynomial The CRC polynomial. - * - * @return string - */ - public static function string($polynomial) - { - if (isset(self::$mapping[$polynomial])) { - return self::$mapping[$polynomial]; - } - return '0x' . self::int2hex($polynomial); - } -} diff --git a/lib/Google/vendor/google/crc32/src/CRCInterface.php b/lib/Google/vendor/google/crc32/src/CRCInterface.php deleted file mode 100644 index 1d9c06312..000000000 --- a/lib/Google/vendor/google/crc32/src/CRCInterface.php +++ /dev/null @@ -1,59 +0,0 @@ -reset(); - } - - public function reset() - { - $this->crc = hex2bin('00000000'); - } - - public function update($data) - { - $this->crc = crc32c($data, $this->crc); - } - - public function hash($raw_output = false) - { - if ($raw_output === true) { - return $this->crc; - } - return bin2hex($this->crc); - } - - public function version() - { - return 'Hardware accelerated (https://github.com/google/crc32c)'; - } -} diff --git a/lib/Google/vendor/google/crc32/src/PHP.php b/lib/Google/vendor/google/crc32/src/PHP.php deleted file mode 100644 index 28ee3cf59..000000000 --- a/lib/Google/vendor/google/crc32/src/PHP.php +++ /dev/null @@ -1,80 +0,0 @@ -polynomial = $polynomial; - $this->table = Table::get($polynomial); - $this->reset(); - } - - - public function reset() - { - $this->crc = ~0; - } - - public function update($data) - { - $crc = $this->crc; - $table = $this->table; - $len = strlen($data); - for ($i = 0; $i < $len; ++$i) { - $crc = (($crc >> 8) & 0xffffff) ^ $table[($crc ^ ord($data[$i])) & 0xff]; - } - $this->crc = $crc; - } - - public function hash($raw_output = false) - { - return $this->crcHash(~$this->crc, $raw_output); - } - - public function version() - { - return 'crc32(' . $this->int2hex($this->polynomial) . ') software version'; - } -} diff --git a/lib/Google/vendor/google/crc32/src/PHPSlicedBy4.php b/lib/Google/vendor/google/crc32/src/PHPSlicedBy4.php deleted file mode 100644 index 9a165e725..000000000 --- a/lib/Google/vendor/google/crc32/src/PHPSlicedBy4.php +++ /dev/null @@ -1,108 +0,0 @@ -polynomial = $polynomial; - $this->table = Table::create4($polynomial); - $this->reset(); - } - - public function reset() - { - $this->crc = ~0; - } - - public function update($data) - { - $crc = $this->crc; - $table0 = $this->table[0]; - $table1 = $this->table[1]; - $table2 = $this->table[2]; - $table3 = $this->table[3]; - - $len = strlen($data); - $remain = ($len % 4); - $len1 = $len - $remain; - for ($i = 0; $i < $len1; $i += 4) { - $b = (ord($data[$i+3])<<24) | - (ord($data[$i+2])<<16) | - (ord($data[$i+1])<<8) | - (ord($data[$i])); - - $crc = ($crc ^ $b) & 0xffffffff; - - $crc = $table3[ $crc & 0xff] ^ - $table2[($crc>>8) & 0xff] ^ - $table1[($crc>>16) & 0xff] ^ - $table0[($crc>>24) & 0xff]; - } - - switch ($remain) { - case 3: - $crc = (($crc >> 8) & 0xffffff) ^ $table0[($crc ^ ord($data[$i])) & 0xff]; - $crc = (($crc >> 8) & 0xffffff) ^ $table0[($crc ^ ord($data[$i+1])) & 0xff]; - $crc = (($crc >> 8) & 0xffffff) ^ $table0[($crc ^ ord($data[$i+2])) & 0xff]; - break; - case 2: - $crc = (($crc >> 8) & 0xffffff) ^ $table0[($crc ^ ord($data[$i])) & 0xff]; - $crc = (($crc >> 8) & 0xffffff) ^ $table0[($crc ^ ord($data[$i+1])) & 0xff]; - break; - case 1: - $crc = (($crc >> 8) & 0xffffff) ^ $table0[($crc ^ ord($data[$i])) & 0xff]; - break; - case 0: - } - - $this->crc = $crc; - } - - public function hash($raw_output = false) - { - return $this->crcHash(~$this->crc, $raw_output); - } - - public function version() - { - return 'crc32(' . $this->int2hex($this->polynomial) . ') software version'; - } -} diff --git a/lib/Google/vendor/google/crc32/src/Table.php b/lib/Google/vendor/google/crc32/src/Table.php deleted file mode 100644 index 3dee7c20e..000000000 --- a/lib/Google/vendor/google/crc32/src/Table.php +++ /dev/null @@ -1,113 +0,0 @@ - $value) { - echo "0x" . int2hex($value) . ","; - if ($i % 4 == 3) { - echo "\n"; - } else { - echo " "; - } - } - - echo "\n\n"; - } - - /** - * Gets a CRC table, by creating it, or using a previously cached result. - * - * @param integer $polynomial The polynomial - * - * @return array The table - */ - public static function get($polynomial) - { - if (isset(self::$tables[$polynomial])) { - return self::$tables[$polynomial]; - } - self::$tables[$polynomial] = self::create($polynomial); - return self::$tables[$polynomial]; - } - - /** - * Create a CRC table. - * - * @param integer $polynomial The polynomial. - * - * @return array The table. - */ - public static function create($polynomial) - { - $table = array_fill(0, 256, 0); - - for ($i = 0; $i < 256; $i++) { - $crc = $i; - for ($j = 0; $j < 8; $j++) { - if ($crc & 1 == 1) { - $crc = ($crc >> 1) ^ $polynomial; - } else { - $crc >>= 1; - } - } - $table[$i] = $crc; - } - - return $table; - } - - /** - * Create a CRC table sliced by 4. - * - * @param integer $polynomial The polynomial. - * - * @return array The table. - */ - public static function create4($polynomial) - { - $table = array_fill(0, 4, array_fill(0, 256, 0)); - $table[0] = self::create($polynomial); - - for ($i = 0; $i < 256; $i++) { - // for Slicing-by-4 and Slicing-by-8 - $table[1][$i] = ($table[0][$i] >> 8) ^ $table[0][$table[0][$i] & 0xFF]; - $table[2][$i] = ($table[1][$i] >> 8) ^ $table[0][$table[1][$i] & 0xFF]; - $table[3][$i] = ($table[2][$i] >> 8) ^ $table[0][$table[2][$i] & 0xFF]; - - /* - // only Slicing-by-8 - $table[4][$i] = ($table[3][$i] >> 8) ^ $table[0][$table[3][$i] & 0xFF]; - $table[5][$i] = ($table[4][$i] >> 8) ^ $table[0][$table[4][$i] & 0xFF]; - $table[6][$i] = ($table[5][$i] >> 8) ^ $table[0][$table[5][$i] & 0xFF]; - $table[7][$i] = ($table[6][$i] >> 8) ^ $table[0][$table[6][$i] & 0xFF]; - */ - } - return $table; - } -} diff --git a/lib/Google/vendor/google/crc32/tests/BuiltinTest.php b/lib/Google/vendor/google/crc32/tests/BuiltinTest.php deleted file mode 100644 index af4857ea8..000000000 --- a/lib/Google/vendor/google/crc32/tests/BuiltinTest.php +++ /dev/null @@ -1,50 +0,0 @@ -expectException('InvalidArgumentException'); - - new Builtin(CRC32::KOOPMAN); - } - - /** - * @dataProvider supports - */ - public function testSupports($algo, $expected) - { - $this->assertEquals($expected, Builtin::supports($algo)); - } - - public function supports() - { - return [ - 'IEEE' => [CRC32::IEEE, true], - 'CASTAGNOLI' => [CRC32::CASTAGNOLI, true], - 'KOOPMAN' => [CRC32::KOOPMAN, false], - ]; - } -} diff --git a/lib/Google/vendor/google/crc32/tests/CRC32Test.php b/lib/Google/vendor/google/crc32/tests/CRC32Test.php deleted file mode 100644 index 71bd31544..000000000 --- a/lib/Google/vendor/google/crc32/tests/CRC32Test.php +++ /dev/null @@ -1,158 +0,0 @@ -update($input); - - $this->assertEquals( - $expected, - $crc->hash(false), - 'hash(' . $input . ')' - ); - - $this->assertEquals( - $expected, - $crc->hash(false), - 'hash(' . $input . ') again' - ); - } - - /** - * @dataProvider data - */ - public function testHashRaw($crc_class, $poly, $input, $expected) - { - $crc = new $crc_class($poly); - $crc->update($input); - - $this->assertEquals( - hex2bin($expected), - $crc->hash(true), - 'hash(' . $input . ', true)' - ); - } - - /** - * Extended hashing. Read increasingly sized chunks of input. - * @dataProvider data - */ - public function testExtendedHash($crc_class, $poly, $input, $expected) - { - $crc = new $crc_class($poly); - - $start = 0; - $len = 1; - while ($start < strlen($input)) { - $chunk = substr($input, $start, $len); - $crc->update($chunk); - - $start += $len; - $len *= 2; - } - - $this->assertEquals( - $expected, - $crc->hash(), - 'hash(' . $input . ')' - ); - } - - /** - * @dataProvider crcs - */ - public function testReset($crc_class, $poly) - { - $data = array( - 'abc' => array( - CRC32::IEEE => '352441c2', - CRC32::CASTAGNOLI => '364b3fb7'), - 'abcdef' => array( - CRC32::IEEE => '4b8e39ef', - CRC32::CASTAGNOLI => '53bceff1'), - ); - - $crc = new $crc_class($poly); - $this->assertEquals('00000000', $crc->hash()); - - $crc->update('abc'); - $this->assertEquals($data['abc'][$poly], $crc->hash()); - - $crc->reset(); - $this->assertEquals('00000000', $crc->hash()); - - $crc->update('abcdef'); - $this->assertEquals($data['abcdef'][$poly], $crc->hash()); - } - - /** - * @dataProvider crcs - */ - public function testClone($crc_class, $poly) - { - $data = array( - 'abc' => array( - CRC32::IEEE => '352441c2', - CRC32::CASTAGNOLI => '364b3fb7'), - 'abcdefgh' => array( - CRC32::IEEE => 'aeef2a50', - CRC32::CASTAGNOLI => '0a9421b7'), - ); - - $a = new $crc_class($poly); - $a->update('abc'); - - $b = clone $a; - $b->update('defgh'); - - // $b should be updated, but $a should stay the same. - $this->assertEquals( - $data['abc'][$poly], - $a->hash(), - '$a->update("abc")' - ); - - $this->assertEquals( - $data['abcdefgh'][$poly], - $b->hash(), - 'clone($a)->update("abcdefgh")' - ); - } -} diff --git a/lib/Google/vendor/google/crc32/tests/DataIterator.php b/lib/Google/vendor/google/crc32/tests/DataIterator.php deleted file mode 100644 index 486d83360..000000000 --- a/lib/Google/vendor/google/crc32/tests/DataIterator.php +++ /dev/null @@ -1,204 +0,0 @@ -crcs, 'Google\CRC32\Google'); - } - } - - public function rewind(): void - { - reset($this->crcs); - reset($this->algos); - } - - public function valid(): bool - { - return current($this->crcs) !== false && - current($this->algos) !== false; - } - - #[\ReturnTypeWillChange] - public function key() - { - return $this->count; - } - - #[\ReturnTypeWillChange] - public function current() - { - return [current($this->crcs), current($this->algos)]; - } - - public function next(): void - { - $this->count++; - if (next($this->algos) === false) { - reset($this->algos); - next($this->crcs); - } - - // Skip unsupported polynomials - if ($this->valid()) { - $crc_class = current($this->crcs); - $poly = current($this->algos); - if (!$crc_class::supports($poly)) { - $this->next(); - } - } - } -} - -class DataIterator implements Iterator -{ - protected $crcs = [ - 'Google\CRC32\PHP', - 'Google\CRC32\PHPSlicedBy4', - 'Google\CRC32\Builtin', - ]; - - protected $algos = [ - CRC32::IEEE, - CRC32::CASTAGNOLI - ]; - - /** - * Various test data, taken from: - * * https://github.com/php/php-src/blob/master/ext/hash/tests/crc32.phpt - * * https://golang.org/src/hash/crc32/crc32_test.go - * * https://tools.ietf.org/html/rfc3720#appendix-B.4 - * - * @var array Hashes for CRC32::IEEE and CRC32::CASTAGNOLI - */ - protected $data = [ - '' => array('00000000', '00000000'), - 'a' => array('e8b7be43', 'c1d04330'), - 'ab' => array('9e83486d', 'e2a22936'), - 'abc' => array('352441c2', '364b3fb7'), - 'abcd' => array('ed82cd11', '92c80a31'), - 'abcde' => array('8587d865', 'c450d697'), - 'abcdef' => array('4b8e39ef', '53bceff1'), - 'abcdefg' => array('312a6aa6', 'e627f441'), - 'abcdefgh' => array('aeef2a50', '0a9421b7'), - 'abcdefghi' => array('8da988af', '2ddc99fc'), - 'abcdefghij' => array('3981703a', 'e6599437'), - 'abcdefghijklmnopqrstuvwxyz' => array('4c2750bd', '9ee6ef25'), - 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' => array('1fc2e6d2', 'a245d57d'), - '12345678901234567890123456789012345678901234567890123456789012345678901234567890' => array('7ca94a72', '477a6781'), - 'message digest' => array('20159d7f', '02bd79d0'), - "I can't remember anything" => array('69147a4e', '5e405e93'), - "I can't remember anythingCan’t tell if this is true or dream" => array('3ee63999', '516ad412'), - 'Discard medicine more than two years old.' => array('6b9cdfe7', 'b2cc01fe'), - 'He who has a shady past knows that nice guys finish last.' => array('c90ef73f', '0e28207f'), - "I wouldn't marry him with a ten foot pole." => array('b902341f', 'be93f964'), - "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave" => array('042080e8', '9e3be0c3'), - "The days of the digital watch are numbered. -Tom Stoppard" => array('154c6d11', 'f505ef04'), - "Nepal premier won't resign." => array('4c418325', '85d3dc82'), - "For every action there is an equal and opposite government program." => array('33955150', 'c5142380'), - "His money is twice tainted: 'taint yours and 'taint mine." => array('26216a4b', '75eb77dd'), - "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977" => array('1abbe45e', '91ebe9f7'), - "It's a tiny change to the code and not completely disgusting. - Bob Manchek" => array('c89a94f7', 'f0b1168e'), - "size: a.out: bad magic" => array('ab3abe14', '572b74e2'), - "The major problem is with sendmail. -Mark Horton" => array('bab102b6', '8a58a6d5'), - "Give me a rock, paper and scissors and I will move the world. CCFestoon" => array('999149d7', '9c426c50'), - "If the enemy is within range, then so are you." => array('6d52a33c', '735400a4'), - "It's well we cannot hear the screams/That we create in others' dreams." => array('90631e8d', 'bec49c95'), - "You remind me of a TV show, but that's all right: I watch it anyway." => array('78309130', 'a95a2079'), - "C is as portable as Stonehedge!!" => array('7d0a377f', 'de2e65c5'), - "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley" => array('8c79fd79', '297a88ed'), - "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule" => array('a20b7167', '66ed1d8b'), - "How can you write a big system without C++? -Paul Glick" => array('8e0bb443', 'dcded527'), - "\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#\$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" => array('29058c73', '9c44184b') - ]; - - protected $count = 0; - - public function __construct() - { - if (extension_loaded('crc32c')) { - array_push($this->crcs, 'Google\CRC32\Google'); - } - } - - public function rewind(): void - { - reset($this->crcs); - reset($this->algos); - reset($this->data); - } - - public function valid(): bool - { - return current($this->crcs) !== false && - current($this->algos) !== false && - current($this->data) !== false; - } - - #[\ReturnTypeWillChange] - public function key() - { - return $this->count; - } - - #[\ReturnTypeWillChange] - public function current() - { - return [current($this->crcs), current($this->algos), key($this->data), current($this->data)[key($this->algos)]]; - } - - public function next(): void - { - $this->count++; - if (next($this->data) === false) { - reset($this->data); - if (next($this->algos) === false) { - reset($this->algos); - next($this->crcs); - } - } - - // Skip unsupported polynomials - if ($this->valid()) { - $crc_class = current($this->crcs); - $poly = current($this->algos); - if (!$crc_class::supports($poly)) { - $this->next(); - } - } - } -} diff --git a/lib/Google/vendor/google/crc32/tests/GoogleTest.php b/lib/Google/vendor/google/crc32/tests/GoogleTest.php deleted file mode 100644 index b27f7b73c..000000000 --- a/lib/Google/vendor/google/crc32/tests/GoogleTest.php +++ /dev/null @@ -1,56 +0,0 @@ -markTestSkipped(); - return; - } - - $this->expectException('InvalidArgumentException'); - - new Google(); - } - - /** - * @dataProvider supports - */ - public function testSupports($algo, $expected) - { - $this->assertEquals($expected, Google::supports($algo)); - } - - public function supports() - { - return [ - 'IEEE' => [CRC32::IEEE, false], - 'CASTAGNOLI' => [CRC32::CASTAGNOLI, true], - 'KOOPMAN' => [CRC32::KOOPMAN, false], - ]; - } -} diff --git a/lib/Google/vendor/guzzlehttp/guzzle/CHANGELOG.md b/lib/Google/vendor/guzzlehttp/guzzle/CHANGELOG.md index 1144eb763..13709d1b8 100644 --- a/lib/Google/vendor/guzzlehttp/guzzle/CHANGELOG.md +++ b/lib/Google/vendor/guzzlehttp/guzzle/CHANGELOG.md @@ -3,6 +3,29 @@ Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version. +## 7.8.1 - 2023-12-03 + +### Changed + +- Updated links in docs to their canonical versions +- Replaced `call_user_func*` with native calls + + +## 7.8.0 - 2023-08-27 + +### Added + +- Support for PHP 8.3 +- Added automatic closing of handles on `CurlFactory` object destruction + + +## 7.7.1 - 2023-08-27 + +### Changed + +- Remove the need for `AllowDynamicProperties` in `CurlMultiHandler` + + ## 7.7.0 - 2023-05-21 ### Added @@ -628,7 +651,8 @@ object). * Note: This has been changed in 5.0.3 to now encode query string values by default unless the `rawString` argument is provided when setting the query string on a URL: Now allowing many more characters to be present in the - query string without being percent encoded. See https://tools.ietf.org/html/rfc3986#appendix-A + query string without being percent encoded. See + https://datatracker.ietf.org/doc/html/rfc3986#appendix-A ## 5.0.1 - 2014-10-16 @@ -1167,7 +1191,7 @@ interfaces. ## 3.4.0 - 2013-04-11 -* Bug fix: URLs are now resolved correctly based on https://tools.ietf.org/html/rfc3986#section-5.2. #289 +* Bug fix: URLs are now resolved correctly based on https://datatracker.ietf.org/doc/html/rfc3986#section-5.2. #289 * Bug fix: Absolute URLs with a path in a service description will now properly override the base URL. #289 * Bug fix: Parsing a query string with a single PHP array value will now result in an array. #263 * Bug fix: Better normalization of the User-Agent header to prevent duplicate headers. #264. diff --git a/lib/Google/vendor/guzzlehttp/guzzle/README.md b/lib/Google/vendor/guzzlehttp/guzzle/README.md index 0786462b3..6d78a9309 100644 --- a/lib/Google/vendor/guzzlehttp/guzzle/README.md +++ b/lib/Google/vendor/guzzlehttp/guzzle/README.md @@ -3,7 +3,7 @@ # Guzzle, PHP HTTP client [![Latest Version](https://img.shields.io/github/release/guzzle/guzzle.svg?style=flat-square)](https://github.com/guzzle/guzzle/releases) -[![Build Status](https://img.shields.io/github/workflow/status/guzzle/guzzle/CI?label=ci%20build&style=flat-square)](https://github.com/guzzle/guzzle/actions?query=workflow%3ACI) +[![Build Status](https://img.shields.io/github/actions/workflow/status/guzzle/guzzle/ci.yml?label=ci%20build&style=flat-square)](https://github.com/guzzle/guzzle/actions?query=workflow%3ACI) [![Total Downloads](https://img.shields.io/packagist/dt/guzzlehttp/guzzle.svg?style=flat-square)](https://packagist.org/packages/guzzlehttp/guzzle) Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and @@ -66,7 +66,7 @@ composer require guzzlehttp/guzzle | 4.x | EOL | `guzzlehttp/guzzle` | `GuzzleHttp` | [v4][guzzle-4-repo] | N/A | No | >=5.4,<7.0 | | 5.x | EOL | `guzzlehttp/guzzle` | `GuzzleHttp` | [v5][guzzle-5-repo] | [v5][guzzle-5-docs] | No | >=5.4,<7.4 | | 6.x | Security fixes only | `guzzlehttp/guzzle` | `GuzzleHttp` | [v6][guzzle-6-repo] | [v6][guzzle-6-docs] | Yes | >=5.5,<8.0 | -| 7.x | Latest | `guzzlehttp/guzzle` | `GuzzleHttp` | [v7][guzzle-7-repo] | [v7][guzzle-7-docs] | Yes | >=7.2.5,<8.3 | +| 7.x | Latest | `guzzlehttp/guzzle` | `GuzzleHttp` | [v7][guzzle-7-repo] | [v7][guzzle-7-docs] | Yes | >=7.2.5,<8.4 | [guzzle-3-repo]: https://github.com/guzzle/guzzle3 [guzzle-4-repo]: https://github.com/guzzle/guzzle/tree/4.x diff --git a/lib/Google/vendor/guzzlehttp/guzzle/UPGRADING.md b/lib/Google/vendor/guzzlehttp/guzzle/UPGRADING.md index 45417a7e1..4efbb5962 100644 --- a/lib/Google/vendor/guzzlehttp/guzzle/UPGRADING.md +++ b/lib/Google/vendor/guzzlehttp/guzzle/UPGRADING.md @@ -27,7 +27,7 @@ Please make sure: - Function `GuzzleHttp\Exception\RequestException::getResponseBodySummary` is removed. Use `\GuzzleHttp\Psr7\get_message_body_summary` as an alternative. - Function `GuzzleHttp\Cookie\CookieJar::getCookieValue` is removed. -- Request option `exception` is removed. Please use `http_errors`. +- Request option `exceptions` is removed. Please use `http_errors`. - Request option `save_to` is removed. Please use `sink`. - Pool option `pool_size` is removed. Please use `concurrency`. - We now look for environment variables in the `$_SERVER` super global, due to thread safety issues with `getenv`. We continue to fallback to `getenv` in CLI environments, for maximum compatibility. @@ -189,11 +189,11 @@ $client = new GuzzleHttp\Client(['handler' => $handler]); ## POST Requests -This version added the [`form_params`](http://guzzle.readthedocs.org/en/latest/request-options.html#form_params) +This version added the [`form_params`](https://docs.guzzlephp.org/en/latest/request-options.html#form_params) and `multipart` request options. `form_params` is an associative array of strings or array of strings and is used to serialize an `application/x-www-form-urlencoded` POST request. The -[`multipart`](http://guzzle.readthedocs.org/en/latest/request-options.html#multipart) +[`multipart`](https://docs.guzzlephp.org/en/latest/request-options.html#multipart) option is now used to send a multipart/form-data POST request. `GuzzleHttp\Post\PostFile` has been removed. Use the `multipart` option to add @@ -209,7 +209,7 @@ The `base_url` option has been renamed to `base_uri`. ## Rewritten Adapter Layer -Guzzle now uses [RingPHP](http://ringphp.readthedocs.org/en/latest) to send +Guzzle now uses [RingPHP](https://ringphp.readthedocs.org/en/latest) to send HTTP requests. The `adapter` option in a `GuzzleHttp\Client` constructor is still supported, but it has now been renamed to `handler`. Instead of passing a `GuzzleHttp\Adapter\AdapterInterface`, you must now pass a PHP @@ -575,7 +575,7 @@ You can intercept a request and inject a response using the `intercept()` event of a `GuzzleHttp\Event\BeforeEvent`, `GuzzleHttp\Event\CompleteEvent`, and `GuzzleHttp\Event\ErrorEvent` event. -See: http://docs.guzzlephp.org/en/latest/events.html +See: https://docs.guzzlephp.org/en/latest/events.html ## Inflection @@ -668,9 +668,9 @@ in separate repositories: The service description layer of Guzzle has moved into two separate packages: -- http://github.com/guzzle/command Provides a high level abstraction over web +- https://github.com/guzzle/command Provides a high level abstraction over web services by representing web service operations using commands. -- http://github.com/guzzle/guzzle-services Provides an implementation of +- https://github.com/guzzle/guzzle-services Provides an implementation of guzzle/command that provides request serialization and response parsing using Guzzle service descriptions. @@ -870,7 +870,7 @@ HeaderInterface (e.g. toArray(), getAll(), etc.). 3.3 to 3.4 ---------- -Base URLs of a client now follow the rules of https://tools.ietf.org/html/rfc3986#section-5.2.2 when merging URLs. +Base URLs of a client now follow the rules of https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.2 when merging URLs. 3.2 to 3.3 ---------- diff --git a/lib/Google/vendor/guzzlehttp/guzzle/composer.json b/lib/Google/vendor/guzzlehttp/guzzle/composer.json index 3207f8c3a..69583d7cc 100644 --- a/lib/Google/vendor/guzzlehttp/guzzle/composer.json +++ b/lib/Google/vendor/guzzlehttp/guzzle/composer.json @@ -53,8 +53,8 @@ "require": { "php": "^7.2.5 || ^8.0", "ext-json": "*", - "guzzlehttp/promises": "^1.5.3 || ^2.0", - "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", + "guzzlehttp/promises": "^1.5.3 || ^2.0.1", + "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" }, @@ -63,10 +63,10 @@ }, "require-dev": { "ext-curl": "*", - "bamarni/composer-bin-plugin": "^1.8.1", + "bamarni/composer-bin-plugin": "^1.8.2", "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", "php-http/message-factory": "^1.1", - "phpunit/phpunit": "^8.5.29 || ^9.5.23", + "phpunit/phpunit": "^8.5.36 || ^9.6.15", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { diff --git a/lib/Google/vendor/guzzlehttp/guzzle/src/Client.php b/lib/Google/vendor/guzzlehttp/guzzle/src/Client.php index 9b0d71070..bc6efc90f 100644 --- a/lib/Google/vendor/guzzlehttp/guzzle/src/Client.php +++ b/lib/Google/vendor/guzzlehttp/guzzle/src/Client.php @@ -202,7 +202,7 @@ public function request(string $method, $uri = '', array $options = []): Respons * * @deprecated Client::getConfig will be removed in guzzlehttp/guzzle:8.0. */ - public function getConfig(?string $option = null) + public function getConfig(string $option = null) { return $option === null ? $this->config diff --git a/lib/Google/vendor/guzzlehttp/guzzle/src/ClientInterface.php b/lib/Google/vendor/guzzlehttp/guzzle/src/ClientInterface.php index 6aaee61af..1788e16ab 100644 --- a/lib/Google/vendor/guzzlehttp/guzzle/src/ClientInterface.php +++ b/lib/Google/vendor/guzzlehttp/guzzle/src/ClientInterface.php @@ -80,5 +80,5 @@ public function requestAsync(string $method, $uri, array $options = []): Promise * * @deprecated ClientInterface::getConfig will be removed in guzzlehttp/guzzle:8.0. */ - public function getConfig(?string $option = null); + public function getConfig(string $option = null); } diff --git a/lib/Google/vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php b/lib/Google/vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php index b4ced5a1a..c29b4b7e9 100644 --- a/lib/Google/vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php +++ b/lib/Google/vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php @@ -96,9 +96,6 @@ public function getCookieByName(string $name): ?SetCookie return null; } - /** - * {@inheritDoc} - */ public function toArray(): array { return \array_map(static function (SetCookie $cookie): array { @@ -106,10 +103,7 @@ public function toArray(): array }, $this->getIterator()->getArrayCopy()); } - /** - * {@inheritDoc} - */ - public function clear(?string $domain = null, ?string $path = null, ?string $name = null): void + public function clear(string $domain = null, string $path = null, string $name = null): void { if (!$domain) { $this->cookies = []; @@ -126,25 +120,22 @@ static function (SetCookie $cookie) use ($domain): bool { $this->cookies = \array_filter( $this->cookies, static function (SetCookie $cookie) use ($path, $domain): bool { - return !($cookie->matchesPath($path) && - $cookie->matchesDomain($domain)); + return !($cookie->matchesPath($path) + && $cookie->matchesDomain($domain)); } ); } else { $this->cookies = \array_filter( $this->cookies, static function (SetCookie $cookie) use ($path, $domain, $name) { - return !($cookie->getName() == $name && - $cookie->matchesPath($path) && - $cookie->matchesDomain($domain)); + return !($cookie->getName() == $name + && $cookie->matchesPath($path) + && $cookie->matchesDomain($domain)); } ); } } - /** - * {@inheritDoc} - */ public function clearSessionCookies(): void { $this->cookies = \array_filter( @@ -155,9 +146,6 @@ static function (SetCookie $cookie): bool { ); } - /** - * {@inheritDoc} - */ public function setCookie(SetCookie $cookie): bool { // If the name string is empty (but not 0), ignore the set-cookie @@ -182,9 +170,9 @@ public function setCookie(SetCookie $cookie): bool foreach ($this->cookies as $i => $c) { // Two cookies are identical, when their path, and domain are // identical. - if ($c->getPath() != $cookie->getPath() || - $c->getDomain() != $cookie->getDomain() || - $c->getName() != $cookie->getName() + if ($c->getPath() != $cookie->getPath() + || $c->getDomain() != $cookie->getDomain() + || $c->getName() != $cookie->getName() ) { continue; } @@ -255,7 +243,7 @@ public function extractCookies(RequestInterface $request, ResponseInterface $res /** * Computes cookie path following RFC 6265 section 5.1.4 * - * @see https://tools.ietf.org/html/rfc6265#section-5.1.4 + * @see https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4 */ private function getCookiePathFromRequest(RequestInterface $request): string { @@ -286,10 +274,10 @@ public function withCookieHeader(RequestInterface $request): RequestInterface $path = $uri->getPath() ?: '/'; foreach ($this->cookies as $cookie) { - if ($cookie->matchesPath($path) && - $cookie->matchesDomain($host) && - !$cookie->isExpired() && - (!$cookie->getSecure() || $scheme === 'https') + if ($cookie->matchesPath($path) + && $cookie->matchesDomain($host) + && !$cookie->isExpired() + && (!$cookie->getSecure() || $scheme === 'https') ) { $values[] = $cookie->getName().'=' .$cookie->getValue(); diff --git a/lib/Google/vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php b/lib/Google/vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php index 50bc36398..8c55cc6f7 100644 --- a/lib/Google/vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php +++ b/lib/Google/vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php @@ -14,6 +14,7 @@ * cookies from a file, database, etc. * * @see https://docs.python.org/2/library/cookielib.html Inspiration + * * @extends \IteratorAggregate */ interface CookieJarInterface extends \Countable, \IteratorAggregate @@ -61,7 +62,7 @@ public function setCookie(SetCookie $cookie): bool; * @param string|null $path Clears cookies matching a domain and path * @param string|null $name Clears cookies matching a domain, path, and name */ - public function clear(?string $domain = null, ?string $path = null, ?string $name = null): void; + public function clear(string $domain = null, string $path = null, string $name = null): void; /** * Discard all sessions cookies. diff --git a/lib/Google/vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php b/lib/Google/vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php index d74915bed..c9806da88 100644 --- a/lib/Google/vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php +++ b/lib/Google/vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php @@ -420,7 +420,7 @@ public function matchesDomain(string $domain): bool } // Remove the leading '.' as per spec in RFC 6265. - // https://tools.ietf.org/html/rfc6265#section-5.2.3 + // https://datatracker.ietf.org/doc/html/rfc6265#section-5.2.3 $cookieDomain = \ltrim(\strtolower($cookieDomain), '.'); $domain = \strtolower($domain); @@ -431,7 +431,7 @@ public function matchesDomain(string $domain): bool } // Matching the subdomain according to RFC 6265. - // https://tools.ietf.org/html/rfc6265#section-5.1.3 + // https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.3 if (\filter_var($domain, \FILTER_VALIDATE_IP)) { return false; } diff --git a/lib/Google/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php b/lib/Google/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php index 3a6a8db26..16a942232 100644 --- a/lib/Google/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php +++ b/lib/Google/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php @@ -256,7 +256,7 @@ private function applyMethod(EasyHandle $easy, array &$conf): void $method = $easy->request->getMethod(); if ($method === 'PUT' || $method === 'POST') { - // See https://tools.ietf.org/html/rfc7230#section-3.3.2 + // See https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2 if (!$easy->request->hasHeader('Content-Length')) { $conf[\CURLOPT_HTTPHEADER][] = 'Content-Length: 0'; } @@ -367,11 +367,11 @@ private function applyHandlerOptions(EasyHandle $easy, array &$conf): void // If it's a directory or a link to a directory use CURLOPT_CAPATH. // If not, it's probably a file, or a link to a file, so use CURLOPT_CAINFO. if ( - \is_dir($options['verify']) || - ( - \is_link($options['verify']) === true && - ($verifyLink = \readlink($options['verify'])) !== false && - \is_dir($verifyLink) + \is_dir($options['verify']) + || ( + \is_link($options['verify']) === true + && ($verifyLink = \readlink($options['verify'])) !== false + && \is_dir($verifyLink) ) ) { $conf[\CURLOPT_CAPATH] = $options['verify']; @@ -627,4 +627,12 @@ private function createHeaderFn(EasyHandle $easy): callable return \strlen($h); }; } + + public function __destruct() + { + foreach ($this->handles as $id => $handle) { + \curl_close($handle); + unset($this->handles[$id]); + } + } } diff --git a/lib/Google/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php b/lib/Google/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php index f0acde145..a64e1821a 100644 --- a/lib/Google/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php +++ b/lib/Google/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php @@ -15,11 +15,8 @@ * associative array of curl option constants mapping to values in the * **curl** key of the provided request options. * - * @property resource|\CurlMultiHandle $_mh Internal use only. Lazy loaded multi-handle. - * * @final */ -#[\AllowDynamicProperties] class CurlMultiHandler { /** @@ -56,6 +53,9 @@ class CurlMultiHandler */ private $options = []; + /** @var resource|\CurlMultiHandle */ + private $_mh; + /** * This handler accepts the following options: * @@ -79,6 +79,10 @@ public function __construct(array $options = []) } $this->options = $options['options'] ?? []; + + // unsetting the property forces the first access to go through + // __get(). + unset($this->_mh); } /** diff --git a/lib/Google/vendor/guzzlehttp/guzzle/src/HandlerStack.php b/lib/Google/vendor/guzzlehttp/guzzle/src/HandlerStack.php index 1ce9c4b19..6cb12f07a 100644 --- a/lib/Google/vendor/guzzlehttp/guzzle/src/HandlerStack.php +++ b/lib/Google/vendor/guzzlehttp/guzzle/src/HandlerStack.php @@ -44,7 +44,7 @@ class HandlerStack * handler is provided, the best handler for your * system will be utilized. */ - public static function create(?callable $handler = null): self + public static function create(callable $handler = null): self { $stack = new self($handler ?: Utils::chooseHandler()); $stack->push(Middleware::httpErrors(), 'http_errors'); @@ -131,7 +131,7 @@ public function hasHandler(): bool * @param callable(callable): callable $middleware Middleware function * @param string $name Name to register for this middleware. */ - public function unshift(callable $middleware, ?string $name = null): void + public function unshift(callable $middleware, string $name = null): void { \array_unshift($this->stack, [$middleware, $name]); $this->cached = null; diff --git a/lib/Google/vendor/guzzlehttp/guzzle/src/MessageFormatter.php b/lib/Google/vendor/guzzlehttp/guzzle/src/MessageFormatter.php index 9b77eee83..04e9eb37a 100644 --- a/lib/Google/vendor/guzzlehttp/guzzle/src/MessageFormatter.php +++ b/lib/Google/vendor/guzzlehttp/guzzle/src/MessageFormatter.php @@ -68,7 +68,7 @@ public function __construct(?string $template = self::CLF) * @param ResponseInterface|null $response Response that was received * @param \Throwable|null $error Exception that was received */ - public function format(RequestInterface $request, ?ResponseInterface $response = null, ?\Throwable $error = null): string + public function format(RequestInterface $request, ResponseInterface $response = null, \Throwable $error = null): string { $cache = []; diff --git a/lib/Google/vendor/guzzlehttp/guzzle/src/MessageFormatterInterface.php b/lib/Google/vendor/guzzlehttp/guzzle/src/MessageFormatterInterface.php index a39ac248e..47934614a 100644 --- a/lib/Google/vendor/guzzlehttp/guzzle/src/MessageFormatterInterface.php +++ b/lib/Google/vendor/guzzlehttp/guzzle/src/MessageFormatterInterface.php @@ -14,5 +14,5 @@ interface MessageFormatterInterface * @param ResponseInterface|null $response Response that was received * @param \Throwable|null $error Exception that was received */ - public function format(RequestInterface $request, ?ResponseInterface $response = null, ?\Throwable $error = null): string; + public function format(RequestInterface $request, ResponseInterface $response = null, \Throwable $error = null): string; } diff --git a/lib/Google/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php b/lib/Google/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php index f32808a75..7aa21a623 100644 --- a/lib/Google/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php +++ b/lib/Google/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php @@ -166,8 +166,8 @@ public function modifyRequest(RequestInterface $request, array $options, Respons // not forcing RFC compliance, but rather emulating what all browsers // would do. $statusCode = $response->getStatusCode(); - if ($statusCode == 303 || - ($statusCode <= 302 && !$options['allow_redirects']['strict']) + if ($statusCode == 303 + || ($statusCode <= 302 && !$options['allow_redirects']['strict']) ) { $safeMethods = ['GET', 'HEAD', 'OPTIONS']; $requestMethod = $request->getMethod(); diff --git a/lib/Google/vendor/guzzlehttp/guzzle/src/RequestOptions.php b/lib/Google/vendor/guzzlehttp/guzzle/src/RequestOptions.php index bf3b02b6b..a38768c0c 100644 --- a/lib/Google/vendor/guzzlehttp/guzzle/src/RequestOptions.php +++ b/lib/Google/vendor/guzzlehttp/guzzle/src/RequestOptions.php @@ -5,9 +5,7 @@ /** * This class contains a list of built-in Guzzle request options. * - * More documentation for each option can be found at http://guzzlephp.org/. - * - * @see http://docs.guzzlephp.org/en/v6/request-options.html + * @see https://docs.guzzlephp.org/en/latest/request-options.html */ final class RequestOptions { diff --git a/lib/Google/vendor/guzzlehttp/guzzle/src/TransferStats.php b/lib/Google/vendor/guzzlehttp/guzzle/src/TransferStats.php index 93fa334c8..2ce9e38f2 100644 --- a/lib/Google/vendor/guzzlehttp/guzzle/src/TransferStats.php +++ b/lib/Google/vendor/guzzlehttp/guzzle/src/TransferStats.php @@ -46,8 +46,8 @@ final class TransferStats */ public function __construct( RequestInterface $request, - ?ResponseInterface $response = null, - ?float $transferTime = null, + ResponseInterface $response = null, + float $transferTime = null, $handlerErrorData = null, array $handlerStats = [] ) { diff --git a/lib/Google/vendor/guzzlehttp/guzzle/src/Utils.php b/lib/Google/vendor/guzzlehttp/guzzle/src/Utils.php index fcf571d6b..93d6d39cd 100644 --- a/lib/Google/vendor/guzzlehttp/guzzle/src/Utils.php +++ b/lib/Google/vendor/guzzlehttp/guzzle/src/Utils.php @@ -176,14 +176,13 @@ public static function defaultCaBundle(): string PHP versions earlier than 5.6 are not properly configured to use the system's CA bundle by default. In order to verify peer certificates, you will need to supply the path on disk to a certificate bundle to the 'verify' request -option: http://docs.guzzlephp.org/en/latest/clients.html#verify. If you do not -need a specific certificate bundle, then Mozilla provides a commonly used CA -bundle which can be downloaded here (provided by the maintainer of cURL): -https://curl.haxx.se/ca/cacert.pem. Once -you have a CA bundle available on disk, you can set the 'openssl.cafile' PHP -ini setting to point to the path to the file, allowing you to omit the 'verify' -request option. See https://curl.haxx.se/docs/sslcerts.html for more -information. +option: https://docs.guzzlephp.org/en/latest/request-options.html#verify. If +you do not need a specific certificate bundle, then Mozilla provides a commonly +used CA bundle which can be downloaded here (provided by the maintainer of +cURL): https://curl.haxx.se/ca/cacert.pem. Once you have a CA bundle available +on disk, you can set the 'openssl.cafile' PHP ini setting to point to the path +to the file, allowing you to omit the 'verify' request option. See +https://curl.haxx.se/docs/sslcerts.html for more information. EOT ); } diff --git a/lib/Google/vendor/guzzlehttp/promises/.editorconfig b/lib/Google/vendor/guzzlehttp/promises/.editorconfig deleted file mode 100644 index 677e36e29..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/.editorconfig +++ /dev/null @@ -1,9 +0,0 @@ -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_size = 4 -indent_style = space -insert_final_newline = true -trim_trailing_whitespace = true diff --git a/lib/Google/vendor/guzzlehttp/promises/.gitattributes b/lib/Google/vendor/guzzlehttp/promises/.gitattributes deleted file mode 100644 index 4a4b968ca..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/.gitattributes +++ /dev/null @@ -1,12 +0,0 @@ -.editorconfig export-ignore -.gitattributes export-ignore -/.github/ export-ignore -.gitignore export-ignore -/.travis.yml export-ignore -/.php-cs-fixer.dist.php export-ignore -/phpstan-baseline.neon export-ignore -/phpstan.neon.dist export-ignore -/phpunit.xml.dist export-ignore -/psalm.xml export-ignore -/tests/ export-ignore -/Makefile export-ignore diff --git a/lib/Google/vendor/guzzlehttp/promises/.github/.editorconfig b/lib/Google/vendor/guzzlehttp/promises/.github/.editorconfig deleted file mode 100644 index 7bd3346f2..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/.github/.editorconfig +++ /dev/null @@ -1,2 +0,0 @@ -[*.yml] -indent_size = 2 diff --git a/lib/Google/vendor/guzzlehttp/promises/.github/FUNDING.yml b/lib/Google/vendor/guzzlehttp/promises/.github/FUNDING.yml deleted file mode 100644 index d00f85ddd..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/.github/FUNDING.yml +++ /dev/null @@ -1,2 +0,0 @@ -github: [Nyholm, GrahamCampbell] -tidelift: "packagist/guzzlehttp/promises" diff --git a/lib/Google/vendor/guzzlehttp/promises/.github/stale.yml b/lib/Google/vendor/guzzlehttp/promises/.github/stale.yml deleted file mode 100644 index 53faa71bd..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/.github/stale.yml +++ /dev/null @@ -1,14 +0,0 @@ -daysUntilStale: 120 -daysUntilClose: 14 -exemptLabels: - - lifecycle/keep-open - - lifecycle/ready-for-merge -# Label to use when marking an issue as stale -staleLabel: lifecycle/stale -# Comment to post when marking an issue as stale. Set to `false` to disable -markComment: > - This issue has been automatically marked as stale because it has not had - recent activity. It will be closed after 2 weeks if no further activity occurs. Thank you - for your contributions. -# Comment to post when closing a stale issue. Set to `false` to disable -closeComment: false diff --git a/lib/Google/vendor/guzzlehttp/promises/.github/workflows/checks.yml b/lib/Google/vendor/guzzlehttp/promises/.github/workflows/checks.yml deleted file mode 100644 index ec10a83e9..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/.github/workflows/checks.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Checks - -on: - push: - branches: - pull_request: - -permissions: - contents: read - -jobs: - composer-normalize: - name: Composer Normalize - runs-on: ubuntu-22.04 - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Composer normalize - uses: docker://ergebnis/composer-normalize-action diff --git a/lib/Google/vendor/guzzlehttp/promises/.github/workflows/ci.yml b/lib/Google/vendor/guzzlehttp/promises/.github/workflows/ci.yml deleted file mode 100644 index bb80fb57e..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/.github/workflows/ci.yml +++ /dev/null @@ -1,65 +0,0 @@ -name: CI - -on: - push: - branches: - pull_request: - -permissions: - contents: read - -jobs: - build: - name: Build - runs-on: ubuntu-22.04 - strategy: - max-parallel: 10 - matrix: - php: ['5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2'] - - steps: - - name: Set up PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - ini-values: error_reporting=E_ALL - coverage: none - tools: flex - - - name: Checkout code - uses: actions/checkout@v3 - - - name: Download dependencies - run: composer update --no-interaction --optimize-autoloader --prefer-stable - - - name: Run PHP < 8 tests - run: ./vendor/bin/simple-phpunit - if: matrix.php < 8 - - - name: Run PHP >= 8 tests - run: ./vendor/bin/simple-phpunit - env: - SYMFONY_PHPUNIT_VERSION: 9.5 - if: matrix.php >= 8 - - lowest: - name: Lowest deps - runs-on: ubuntu-22.04 - steps: - - name: Set up PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 7.3 - ini-values: error_reporting=E_ALL - coverage: pcov - - - name: Checkout code - uses: actions/checkout@v3 - - - name: Download dependencies - run: composer update --no-interaction --optimize-autoloader --prefer-stable --prefer-lowest - - - name: Run tests - env: - SYMFONY_DEPRECATIONS_HELPER: "max[self]=0" - run: ./vendor/bin/simple-phpunit --coverage-text diff --git a/lib/Google/vendor/guzzlehttp/promises/.github/workflows/static.yml b/lib/Google/vendor/guzzlehttp/promises/.github/workflows/static.yml deleted file mode 100644 index 9e6e1e0a0..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/.github/workflows/static.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: Static analysis - -on: - push: - branches: - pull_request: - -permissions: - contents: read - -jobs: - phpstan: - name: PHPStan - runs-on: ubuntu-22.04 - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Download dependencies - run: | - composer update --no-interaction --optimize-autoloader - - - name: PHPStan - uses: docker://oskarstark/phpstan-ga:1.6.0 - with: - entrypoint: /composer/vendor/bin/phpstan - args: analyze --no-progress - - php-cs-fixer: - name: PHP-CS-Fixer - runs-on: ubuntu-22.04 - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '7.4' - coverage: none - extensions: mbstring - - - name: Download dependencies - run: composer update --no-interaction --no-progress - - - name: Download PHP CS Fixer - run: composer require "friendsofphp/php-cs-fixer:3.10.0" - - - name: Execute PHP CS Fixer - run: vendor/bin/php-cs-fixer fix --diff --dry-run - - psalm: - name: Psalm - runs-on: ubuntu-22.04 - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Psalm - uses: docker://vimeo/psalm-github-actions diff --git a/lib/Google/vendor/guzzlehttp/promises/.gitignore b/lib/Google/vendor/guzzlehttp/promises/.gitignore deleted file mode 100644 index 09d91da6e..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -artifacts/ -vendor/ -composer.lock -phpunit.xml -.php-cs-fixer.php -.php-cs-fixer.cache -.phpunit.result.cache diff --git a/lib/Google/vendor/guzzlehttp/promises/.php-cs-fixer.dist.php b/lib/Google/vendor/guzzlehttp/promises/.php-cs-fixer.dist.php deleted file mode 100644 index fcfbd02b8..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/.php-cs-fixer.dist.php +++ /dev/null @@ -1,87 +0,0 @@ -setRiskyAllowed(true) - ->setRules([ - '@PSR2' => true, - 'array_syntax' => ['syntax' => 'short'], - 'binary_operator_spaces' => ['operators' => ['=>' => null]], - 'blank_line_after_opening_tag' => true, - 'class_attributes_separation' => ['elements' => ['method' => 'one']], - 'compact_nullable_typehint' => true, - 'concat_space' => ['spacing' => 'one'], - 'declare_equal_normalize' => ['space' => 'none'], - 'declare_strict_types' => false, - 'dir_constant' => true, - 'fully_qualified_strict_types' => true, - 'function_to_constant' => true, - 'function_typehint_space' => true, - 'header_comment' => false, - 'list_syntax' => ['syntax' => 'short'], - 'lowercase_cast' => true, - 'magic_method_casing' => true, - 'modernize_types_casting' => true, - 'multiline_comment_opening_closing' => true, - //'native_constant_invocation' => true, - 'no_alias_functions' => true, - 'no_alternative_syntax' => true, - 'no_blank_lines_after_phpdoc' => true, - 'no_empty_comment' => true, - 'no_empty_phpdoc' => true, - 'no_extra_blank_lines' => true, - 'no_leading_import_slash' => true, - 'no_leading_namespace_whitespace' => true, - 'no_spaces_around_offset' => true, - 'no_superfluous_phpdoc_tags' => ['allow_mixed' => true], - 'no_trailing_comma_in_singleline_array' => true, - 'no_unneeded_control_parentheses' => true, - 'no_unset_cast' => true, - 'no_unused_imports' => true, - 'no_useless_else' => true, - 'no_useless_return' => true, - 'no_whitespace_in_blank_line' => true, - 'normalize_index_brace' => true, - 'ordered_imports' => true, - 'php_unit_construct' => true, - 'php_unit_dedicate_assert' => ['target' => 'newest'], - 'php_unit_dedicate_assert_internal_type' => ['target' => 'newest'], - 'php_unit_expectation' => ['target' => 'newest'], - 'php_unit_mock' => ['target' => 'newest'], - 'php_unit_mock_short_will_return' => true, - 'php_unit_no_expectation_annotation' => ['target' => 'newest'], - 'php_unit_test_annotation' => ['style' => 'prefix'], - //'php_unit_test_case_static_method_calls' => ['call_type' => 'self'], - 'phpdoc_align' => ['align' => 'vertical'], - //'phpdoc_line_span' => ['method' => 'multi', 'property' => 'multi'], - 'phpdoc_no_package' => true, - 'phpdoc_no_useless_inheritdoc' => true, - 'phpdoc_scalar' => true, - 'phpdoc_separation' => true, - 'phpdoc_single_line_var_spacing' => true, - 'phpdoc_trim' => true, - 'phpdoc_trim_consecutive_blank_line_separation' => true, - 'phpdoc_types' => true, - 'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'], - 'phpdoc_var_without_name' => true, - 'return_assignment' => true, - 'self_static_accessor' => true, - 'short_scalar_cast' => true, - 'single_trait_insert_per_statement' => true, - 'standardize_not_equals' => true, - //'static_lambda' => true, - 'ternary_to_null_coalescing' => true, - 'trim_array_spaces' => true, - 'visibility_required' => ['elements' => ['property', 'method']], - 'yoda_style' => false, - // 'native_function_invocation' => true, - 'braces' => ['allow_single_line_closure'=>true], - ]) - ->setFinder( - PhpCsFixer\Finder::create() - ->in(__DIR__.'/src') - ->in(__DIR__.'/tests') - ->name('*.php') - ) -; - -return $config; diff --git a/lib/Google/vendor/guzzlehttp/promises/.travis.yml b/lib/Google/vendor/guzzlehttp/promises/.travis.yml deleted file mode 100644 index 04735a674..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/.travis.yml +++ /dev/null @@ -1,19 +0,0 @@ -language: php - -dist: trusty - -matrix: - include: - - php: 5.5.9 - - php: hhvm-3.24 - fast_finish: true - -before_install: - - if [[ "$TRAVIS_PHP_VERSION" != "hhvm-3.24" ]]; then echo "xdebug.overload_var_dump = 1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi - -install: - - travis_retry composer update - - travis_retry ./vendor/bin/simple-phpunit install - -script: - - ./vendor/bin/simple-phpunit diff --git a/lib/Google/vendor/guzzlehttp/promises/CHANGELOG.md b/lib/Google/vendor/guzzlehttp/promises/CHANGELOG.md index 2e1a2f384..c73afb903 100644 --- a/lib/Google/vendor/guzzlehttp/promises/CHANGELOG.md +++ b/lib/Google/vendor/guzzlehttp/promises/CHANGELOG.md @@ -1,17 +1,50 @@ # CHANGELOG + +## 2.0.2 - 2023-12-03 + +### Changed + +- Replaced `call_user_func*` with native calls + + +## 2.0.1 - 2023-08-03 + +### Changed + +- PHP 8.3 support + + +## 2.0.0 - 2023-05-21 + +### Added + +- Added PHP 7 type hints + +### Changed + +- All previously non-final non-exception classes have been marked as soft-final + +### Removed + +- Dropped PHP < 7.2 support +- All functions in the `GuzzleHttp\Promise` namespace + + ## 1.5.3 - 2023-05-21 ### Changed - Removed remaining usage of deprecated functions + ## 1.5.2 - 2022-08-07 ### Changed - Officially support PHP 8.2 + ## 1.5.1 - 2021-10-22 ### Fixed @@ -19,6 +52,7 @@ - Revert "Call handler when waiting on fulfilled/rejected Promise" - Fix pool memory leak when empty array of promises provided + ## 1.5.0 - 2021-10-07 ### Changed @@ -30,12 +64,14 @@ - Fix manually settle promises generated with `Utils::task` + ## 1.4.1 - 2021-02-18 ### Fixed - Fixed `each_limit` skipping promises and failing + ## 1.4.0 - 2020-09-30 ### Added diff --git a/lib/Google/vendor/guzzlehttp/promises/Makefile b/lib/Google/vendor/guzzlehttp/promises/Makefile deleted file mode 100644 index 8d5b3ef95..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -all: clean test - -test: - vendor/bin/phpunit - -coverage: - vendor/bin/phpunit --coverage-html=artifacts/coverage - -view-coverage: - open artifacts/coverage/index.html - -clean: - rm -rf artifacts/* diff --git a/lib/Google/vendor/guzzlehttp/promises/README.md b/lib/Google/vendor/guzzlehttp/promises/README.md index 1ea667ab9..a32d3d29c 100644 --- a/lib/Google/vendor/guzzlehttp/promises/README.md +++ b/lib/Google/vendor/guzzlehttp/promises/README.md @@ -29,6 +29,21 @@ for a general introduction to promises. `GuzzleHttp\Promise\Coroutine::of()`. +## Installation + +```shell +composer require guzzlehttp/promises +``` + + +## Version Guidance + +| Version | Status | PHP Version | +|---------|------------------------|--------------| +| 1.x | Bug and security fixes | >=5.5,<8.3 | +| 2.x | Latest | >=7.2.5,<8.4 | + + ## Quick Start A *promise* represents the eventual result of an asynchronous operation. The @@ -430,8 +445,6 @@ $loop = React\EventLoop\Factory::create(); $loop->addPeriodicTimer(0, [$queue, 'run']); ``` -*TODO*: Perhaps adding a `futureTick()` on each tick would be faster? - ## Implementation Notes @@ -501,8 +514,8 @@ $promise->resolve('foo'); A static API was first introduced in 1.4.0, in order to mitigate problems with functions conflicting between global and local copies of the package. The -function API will be removed in 2.0.0. A migration table has been provided here -for your convenience: +function API was removed in 2.0.0. A migration table has been provided here for +your convenience: | Original Function | Replacement Method | |----------------|----------------| diff --git a/lib/Google/vendor/guzzlehttp/promises/composer.json b/lib/Google/vendor/guzzlehttp/promises/composer.json index 966e3e3a8..6c5bdd662 100644 --- a/lib/Google/vendor/guzzlehttp/promises/composer.json +++ b/lib/Google/vendor/guzzlehttp/promises/composer.json @@ -26,27 +26,32 @@ } ], "require": { - "php": ">=5.5" + "php": "^7.2.5 || ^8.0" }, "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.1" + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" }, "autoload": { "psr-4": { "GuzzleHttp\\Promise\\": "src/" - }, - "files": ["src/functions_include.php"] + } }, "autoload-dev": { "psr-4": { "GuzzleHttp\\Promise\\Tests\\": "tests/" } }, - "scripts": { - "test": "vendor/bin/simple-phpunit", - "test-ci": "vendor/bin/simple-phpunit --coverage-text" + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } }, "config": { + "allow-plugins": { + "bamarni/composer-bin-plugin": true + }, "preferred-install": "dist", "sort-packages": true } diff --git a/lib/Google/vendor/guzzlehttp/promises/phpstan-baseline.neon b/lib/Google/vendor/guzzlehttp/promises/phpstan-baseline.neon deleted file mode 100644 index 6e99b21b2..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/phpstan-baseline.neon +++ /dev/null @@ -1,37 +0,0 @@ -parameters: - ignoreErrors: - - - message: "#^Cannot call method reject\\(\\) on null\\.$#" - count: 1 - path: src/EachPromise.php - - - - message: "#^Dead catch \\- Exception is already caught above\\.$#" - count: 2 - path: src/EachPromise.php - - - - message: "#^Dead catch \\- Exception is already caught above\\.$#" - count: 1 - path: src/FulfilledPromise.php - - - - message: "#^Dead catch \\- Exception is already caught above\\.$#" - count: 2 - path: src/Promise.php - - - - message: "#^Dead catch \\- Exception is already caught above\\.$#" - count: 1 - path: src/RejectedPromise.php - - - - message: "#^Dead catch \\- Exception is already caught above\\.$#" - count: 2 - path: src/Utils.php - - - - message: "#^Dead catch \\- GuzzleHttp\\\\Promise\\\\RejectionException is never thrown in the try block\\.$#" - count: 1 - path: src/Utils.php - diff --git a/lib/Google/vendor/guzzlehttp/promises/phpstan.neon.dist b/lib/Google/vendor/guzzlehttp/promises/phpstan.neon.dist deleted file mode 100644 index bc0f2c3a4..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/phpstan.neon.dist +++ /dev/null @@ -1,7 +0,0 @@ -includes: - - phpstan-baseline.neon - -parameters: - level: 5 - paths: - - src diff --git a/lib/Google/vendor/guzzlehttp/promises/phpunit.xml.dist b/lib/Google/vendor/guzzlehttp/promises/phpunit.xml.dist deleted file mode 100644 index 6163dba5b..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/phpunit.xml.dist +++ /dev/null @@ -1,21 +0,0 @@ - - - - - tests/ - - - - - src/ - - src/ - - - - diff --git a/lib/Google/vendor/guzzlehttp/promises/psalm.xml b/lib/Google/vendor/guzzlehttp/promises/psalm.xml deleted file mode 100644 index 3e4e3d085..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/psalm.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - diff --git a/lib/Google/vendor/guzzlehttp/promises/src/AggregateException.php b/lib/Google/vendor/guzzlehttp/promises/src/AggregateException.php index d2b5712b9..40ffdbcf1 100644 --- a/lib/Google/vendor/guzzlehttp/promises/src/AggregateException.php +++ b/lib/Google/vendor/guzzlehttp/promises/src/AggregateException.php @@ -1,5 +1,7 @@ generator = $generatorFn(); - $this->result = new Promise(function () { + $this->result = new Promise(function (): void { while (isset($this->currentPromise)) { $this->currentPromise->wait(); } }); try { $this->nextCoroutine($this->generator->current()); - } catch (\Exception $exception) { - $this->result->reject($exception); } catch (Throwable $throwable) { $this->result->reject($throwable); } @@ -78,10 +77,8 @@ public function __construct(callable $generatorFn) /** * Create a new coroutine. - * - * @return self */ - public static function of(callable $generatorFn) + public static function of(callable $generatorFn): self { return new self($generatorFn); } @@ -89,42 +86,42 @@ public static function of(callable $generatorFn) public function then( callable $onFulfilled = null, callable $onRejected = null - ) { + ): PromiseInterface { return $this->result->then($onFulfilled, $onRejected); } - public function otherwise(callable $onRejected) + public function otherwise(callable $onRejected): PromiseInterface { return $this->result->otherwise($onRejected); } - public function wait($unwrap = true) + public function wait(bool $unwrap = true) { return $this->result->wait($unwrap); } - public function getState() + public function getState(): string { return $this->result->getState(); } - public function resolve($value) + public function resolve($value): void { $this->result->resolve($value); } - public function reject($reason) + public function reject($reason): void { $this->result->reject($reason); } - public function cancel() + public function cancel(): void { $this->currentPromise->cancel(); $this->result->cancel(); } - private function nextCoroutine($yielded) + private function nextCoroutine($yielded): void { $this->currentPromise = Create::promiseFor($yielded) ->then([$this, '_handleSuccess'], [$this, '_handleFailure']); @@ -133,7 +130,7 @@ private function nextCoroutine($yielded) /** * @internal */ - public function _handleSuccess($value) + public function _handleSuccess($value): void { unset($this->currentPromise); try { @@ -143,8 +140,6 @@ public function _handleSuccess($value) } else { $this->result->resolve($value); } - } catch (Exception $exception) { - $this->result->reject($exception); } catch (Throwable $throwable) { $this->result->reject($throwable); } @@ -153,15 +148,13 @@ public function _handleSuccess($value) /** * @internal */ - public function _handleFailure($reason) + public function _handleFailure($reason): void { unset($this->currentPromise); try { $nextYield = $this->generator->throw(Create::exceptionFor($reason)); // The throw was caught, so keep iterating on the coroutine $this->nextCoroutine($nextYield); - } catch (Exception $exception) { - $this->result->reject($exception); } catch (Throwable $throwable) { $this->result->reject($throwable); } diff --git a/lib/Google/vendor/guzzlehttp/promises/src/Create.php b/lib/Google/vendor/guzzlehttp/promises/src/Create.php index 8d038e9c1..9d3fc4a1e 100644 --- a/lib/Google/vendor/guzzlehttp/promises/src/Create.php +++ b/lib/Google/vendor/guzzlehttp/promises/src/Create.php @@ -1,5 +1,7 @@ then([$promise, 'resolve'], [$promise, 'reject']); + return $promise; } @@ -34,10 +35,8 @@ public static function promiseFor($value) * If the provided reason is a promise, then it is returned as-is. * * @param mixed $reason Promise or reason. - * - * @return PromiseInterface */ - public static function rejectionFor($reason) + public static function rejectionFor($reason): PromiseInterface { if ($reason instanceof PromiseInterface) { return $reason; @@ -50,12 +49,10 @@ public static function rejectionFor($reason) * Create an exception for a rejected promise value. * * @param mixed $reason - * - * @return \Exception|\Throwable */ - public static function exceptionFor($reason) + public static function exceptionFor($reason): \Throwable { - if ($reason instanceof \Exception || $reason instanceof \Throwable) { + if ($reason instanceof \Throwable) { return $reason; } @@ -66,10 +63,8 @@ public static function exceptionFor($reason) * Returns an iterator for the given value. * * @param mixed $value - * - * @return \Iterator */ - public static function iterFor($value) + public static function iterFor($value): \Iterator { if ($value instanceof \Iterator) { return $value; diff --git a/lib/Google/vendor/guzzlehttp/promises/src/Each.php b/lib/Google/vendor/guzzlehttp/promises/src/Each.php index ff8efd734..c09d23c60 100644 --- a/lib/Google/vendor/guzzlehttp/promises/src/Each.php +++ b/lib/Google/vendor/guzzlehttp/promises/src/Each.php @@ -1,5 +1,7 @@ $onFulfilled, - 'rejected' => $onRejected + 'rejected' => $onRejected, ]))->promise(); } @@ -44,21 +42,17 @@ public static function of( * * @param mixed $iterable * @param int|callable $concurrency - * @param callable $onFulfilled - * @param callable $onRejected - * - * @return PromiseInterface */ public static function ofLimit( $iterable, $concurrency, callable $onFulfilled = null, callable $onRejected = null - ) { + ): PromiseInterface { return (new EachPromise($iterable, [ - 'fulfilled' => $onFulfilled, - 'rejected' => $onRejected, - 'concurrency' => $concurrency + 'fulfilled' => $onFulfilled, + 'rejected' => $onRejected, + 'concurrency' => $concurrency, ]))->promise(); } @@ -69,20 +63,17 @@ public static function ofLimit( * * @param mixed $iterable * @param int|callable $concurrency - * @param callable $onFulfilled - * - * @return PromiseInterface */ public static function ofLimitAll( $iterable, $concurrency, callable $onFulfilled = null - ) { + ): PromiseInterface { return self::ofLimit( $iterable, $concurrency, $onFulfilled, - function ($reason, $idx, PromiseInterface $aggregate) { + function ($reason, $idx, PromiseInterface $aggregate): void { $aggregate->reject($reason); } ); diff --git a/lib/Google/vendor/guzzlehttp/promises/src/EachPromise.php b/lib/Google/vendor/guzzlehttp/promises/src/EachPromise.php index 280d79950..e12389818 100644 --- a/lib/Google/vendor/guzzlehttp/promises/src/EachPromise.php +++ b/lib/Google/vendor/guzzlehttp/promises/src/EachPromise.php @@ -1,10 +1,14 @@ aggregate) { return $this->aggregate; @@ -82,21 +86,18 @@ public function promise() $this->refillPending(); } catch (\Throwable $e) { $this->aggregate->reject($e); - } catch (\Exception $e) { - $this->aggregate->reject($e); } /** * @psalm-suppress NullableReturnStatement - * @phpstan-ignore-next-line */ return $this->aggregate; } - private function createPromise() + private function createPromise(): void { $this->mutex = false; - $this->aggregate = new Promise(function () { + $this->aggregate = new Promise(function (): void { if ($this->checkIfFinished()) { return; } @@ -113,7 +114,7 @@ private function createPromise() }); // Clear the references when the promise is resolved. - $clearFn = function () { + $clearFn = function (): void { $this->iterable = $this->concurrency = $this->pending = null; $this->onFulfilled = $this->onRejected = null; $this->nextPendingIndex = 0; @@ -122,17 +123,19 @@ private function createPromise() $this->aggregate->then($clearFn, $clearFn); } - private function refillPending() + private function refillPending(): void { if (!$this->concurrency) { // Add all pending promises. - while ($this->addPending() && $this->advanceIterator()); + while ($this->addPending() && $this->advanceIterator()) { + } + return; } // Add only up to N pending promises. $concurrency = is_callable($this->concurrency) - ? call_user_func($this->concurrency, count($this->pending)) + ? ($this->concurrency)(count($this->pending)) : $this->concurrency; $concurrency = max($concurrency - count($this->pending), 0); // Concurrency may be set to 0 to disallow new promises. @@ -147,10 +150,11 @@ private function refillPending() // next value to yield until promise callbacks are called. while (--$concurrency && $this->advanceIterator() - && $this->addPending()); + && $this->addPending()) { + } } - private function addPending() + private function addPending(): bool { if (!$this->iterable || !$this->iterable->valid()) { return false; @@ -164,10 +168,9 @@ private function addPending() $idx = $this->nextPendingIndex++; $this->pending[$idx] = $promise->then( - function ($value) use ($idx, $key) { + function ($value) use ($idx, $key): void { if ($this->onFulfilled) { - call_user_func( - $this->onFulfilled, + ($this->onFulfilled)( $value, $key, $this->aggregate @@ -175,10 +178,9 @@ function ($value) use ($idx, $key) { } $this->step($idx); }, - function ($reason) use ($idx, $key) { + function ($reason) use ($idx, $key): void { if ($this->onRejected) { - call_user_func( - $this->onRejected, + ($this->onRejected)( $reason, $key, $this->aggregate @@ -191,7 +193,7 @@ function ($reason) use ($idx, $key) { return true; } - private function advanceIterator() + private function advanceIterator(): bool { // Place a lock on the iterator so that we ensure to not recurse, // preventing fatal generator errors. @@ -204,19 +206,17 @@ private function advanceIterator() try { $this->iterable->next(); $this->mutex = false; + return true; } catch (\Throwable $e) { $this->aggregate->reject($e); $this->mutex = false; - return false; - } catch (\Exception $e) { - $this->aggregate->reject($e); - $this->mutex = false; + return false; } } - private function step($idx) + private function step(int $idx): void { // If the promise was already resolved, then ignore this step. if (Is::settled($this->aggregate)) { @@ -234,11 +234,12 @@ private function step($idx) } } - private function checkIfFinished() + private function checkIfFinished(): bool { if (!$this->pending && !$this->iterable->valid()) { // Resolve the promise if there's nothing left to do. $this->aggregate->resolve(null); + return true; } diff --git a/lib/Google/vendor/guzzlehttp/promises/src/FulfilledPromise.php b/lib/Google/vendor/guzzlehttp/promises/src/FulfilledPromise.php index 98f72a62a..ab7129659 100644 --- a/lib/Google/vendor/guzzlehttp/promises/src/FulfilledPromise.php +++ b/lib/Google/vendor/guzzlehttp/promises/src/FulfilledPromise.php @@ -1,5 +1,7 @@ value; - $queue->add(static function () use ($p, $value, $onFulfilled) { + $queue->add(static function () use ($p, $value, $onFulfilled): void { if (Is::pending($p)) { try { $p->resolve($onFulfilled($value)); } catch (\Throwable $e) { $p->reject($e); - } catch (\Exception $e) { - $p->reject($e); } } }); @@ -50,34 +55,34 @@ public function then( return $p; } - public function otherwise(callable $onRejected) + public function otherwise(callable $onRejected): PromiseInterface { return $this->then(null, $onRejected); } - public function wait($unwrap = true, $defaultDelivery = null) + public function wait(bool $unwrap = true) { return $unwrap ? $this->value : null; } - public function getState() + public function getState(): string { return self::FULFILLED; } - public function resolve($value) + public function resolve($value): void { if ($value !== $this->value) { - throw new \LogicException("Cannot resolve a fulfilled promise"); + throw new \LogicException('Cannot resolve a fulfilled promise'); } } - public function reject($reason) + public function reject($reason): void { - throw new \LogicException("Cannot reject a fulfilled promise"); + throw new \LogicException('Cannot reject a fulfilled promise'); } - public function cancel() + public function cancel(): void { // pass } diff --git a/lib/Google/vendor/guzzlehttp/promises/src/Is.php b/lib/Google/vendor/guzzlehttp/promises/src/Is.php index c3ed8d014..f3f050384 100644 --- a/lib/Google/vendor/guzzlehttp/promises/src/Is.php +++ b/lib/Google/vendor/guzzlehttp/promises/src/Is.php @@ -1,45 +1,39 @@ getState() === PromiseInterface::PENDING; } /** * Returns true if a promise is fulfilled or rejected. - * - * @return bool */ - public static function settled(PromiseInterface $promise) + public static function settled(PromiseInterface $promise): bool { return $promise->getState() !== PromiseInterface::PENDING; } /** * Returns true if a promise is fulfilled. - * - * @return bool */ - public static function fulfilled(PromiseInterface $promise) + public static function fulfilled(PromiseInterface $promise): bool { return $promise->getState() === PromiseInterface::FULFILLED; } /** * Returns true if a promise is rejected. - * - * @return bool */ - public static function rejected(PromiseInterface $promise) + public static function rejected(PromiseInterface $promise): bool { return $promise->getState() === PromiseInterface::REJECTED; } diff --git a/lib/Google/vendor/guzzlehttp/promises/src/Promise.php b/lib/Google/vendor/guzzlehttp/promises/src/Promise.php index 75939057b..1b07bdc9a 100644 --- a/lib/Google/vendor/guzzlehttp/promises/src/Promise.php +++ b/lib/Google/vendor/guzzlehttp/promises/src/Promise.php @@ -1,11 +1,15 @@ state === self::PENDING) { $p = new Promise(null, [$this, 'cancel']); $this->handlers[] = [$p, $onFulfilled, $onRejected]; $p->waitList = $this->waitList; $p->waitList[] = $this; + return $p; } // Return a fulfilled promise and immediately invoke any callbacks. if ($this->state === self::FULFILLED) { $promise = Create::promiseFor($this->result); + return $onFulfilled ? $promise->then($onFulfilled) : $promise; } // It's either cancelled or rejected, so return a rejected promise // and immediately invoke any callbacks. $rejection = Create::rejectionFor($this->result); + return $onRejected ? $rejection->then(null, $onRejected) : $rejection; } - public function otherwise(callable $onRejected) + public function otherwise(callable $onRejected): PromiseInterface { return $this->then(null, $onRejected); } - public function wait($unwrap = true) + public function wait(bool $unwrap = true) { $this->waitIfPending(); @@ -73,12 +80,12 @@ public function wait($unwrap = true) } } - public function getState() + public function getState(): string { return $this->state; } - public function cancel() + public function cancel(): void { if ($this->state !== self::PENDING) { return; @@ -93,8 +100,6 @@ public function cancel() $fn(); } catch (\Throwable $e) { $this->reject($e); - } catch (\Exception $e) { - $this->reject($e); } } @@ -105,17 +110,17 @@ public function cancel() } } - public function resolve($value) + public function resolve($value): void { $this->settle(self::FULFILLED, $value); } - public function reject($reason) + public function reject($reason): void { $this->settle(self::REJECTED, $reason); } - private function settle($state, $value) + private function settle(string $state, $value): void { if ($this->state !== self::PENDING) { // Ignore calls with the same resolution. @@ -148,7 +153,7 @@ private function settle($state, $value) if (!is_object($value) || !method_exists($value, 'then')) { $id = $state === self::FULFILLED ? 1 : 2; // It's a success, so resolve the handlers in the queue. - Utils::queue()->add(static function () use ($id, $value, $handlers) { + Utils::queue()->add(static function () use ($id, $value, $handlers): void { foreach ($handlers as $handler) { self::callHandler($id, $value, $handler); } @@ -159,12 +164,12 @@ private function settle($state, $value) } else { // Resolve the handlers when the forwarded promise is resolved. $value->then( - static function ($value) use ($handlers) { + static function ($value) use ($handlers): void { foreach ($handlers as $handler) { self::callHandler(1, $value, $handler); } }, - static function ($reason) use ($handlers) { + static function ($reason) use ($handlers): void { foreach ($handlers as $handler) { self::callHandler(2, $reason, $handler); } @@ -180,7 +185,7 @@ static function ($reason) use ($handlers) { * @param mixed $value Value to pass to the callback. * @param array $handler Array of handler data (promise and callbacks). */ - private static function callHandler($index, $value, array $handler) + private static function callHandler(int $index, $value, array $handler): void { /** @var PromiseInterface $promise */ $promise = $handler[0]; @@ -211,12 +216,10 @@ private static function callHandler($index, $value, array $handler) } } catch (\Throwable $reason) { $promise->reject($reason); - } catch (\Exception $reason) { - $promise->reject($reason); } } - private function waitIfPending() + private function waitIfPending(): void { if ($this->state !== self::PENDING) { return; @@ -227,9 +230,9 @@ private function waitIfPending() } else { // If there's no wait function, then reject the promise. $this->reject('Cannot wait on a promise that has ' - . 'no internal wait function. You must provide a wait ' - . 'function when constructing the promise to be able to ' - . 'wait on a promise.'); + .'no internal wait function. You must provide a wait ' + .'function when constructing the promise to be able to ' + .'wait on a promise.'); } Utils::queue()->run(); @@ -240,13 +243,13 @@ private function waitIfPending() } } - private function invokeWaitFn() + private function invokeWaitFn(): void { try { $wfn = $this->waitFn; $this->waitFn = null; $wfn(true); - } catch (\Exception $reason) { + } catch (\Throwable $reason) { if ($this->state === self::PENDING) { // The promise has not been resolved yet, so reject the promise // with the exception. @@ -259,7 +262,7 @@ private function invokeWaitFn() } } - private function invokeWaitList() + private function invokeWaitList(): void { $waitList = $this->waitList; $this->waitList = null; diff --git a/lib/Google/vendor/guzzlehttp/promises/src/PromiseInterface.php b/lib/Google/vendor/guzzlehttp/promises/src/PromiseInterface.php index e59833143..2824802bb 100644 --- a/lib/Google/vendor/guzzlehttp/promises/src/PromiseInterface.php +++ b/lib/Google/vendor/guzzlehttp/promises/src/PromiseInterface.php @@ -1,5 +1,7 @@ reason; $p = new Promise([$queue, 'run']); - $queue->add(static function () use ($p, $reason, $onRejected) { + $queue->add(static function () use ($p, $reason, $onRejected): void { if (Is::pending($p)) { try { // Return a resolved promise if onRejected does not throw. @@ -43,9 +50,6 @@ public function then( } catch (\Throwable $e) { // onRejected threw, so return a rejected promise. $p->reject($e); - } catch (\Exception $e) { - // onRejected threw, so return a rejected promise. - $p->reject($e); } } }); @@ -53,12 +57,12 @@ public function then( return $p; } - public function otherwise(callable $onRejected) + public function otherwise(callable $onRejected): PromiseInterface { return $this->then(null, $onRejected); } - public function wait($unwrap = true, $defaultDelivery = null) + public function wait(bool $unwrap = true) { if ($unwrap) { throw Create::exceptionFor($this->reason); @@ -67,24 +71,24 @@ public function wait($unwrap = true, $defaultDelivery = null) return null; } - public function getState() + public function getState(): string { return self::REJECTED; } - public function resolve($value) + public function resolve($value): void { - throw new \LogicException("Cannot resolve a rejected promise"); + throw new \LogicException('Cannot resolve a rejected promise'); } - public function reject($reason) + public function reject($reason): void { if ($reason !== $this->reason) { - throw new \LogicException("Cannot reject a rejected promise"); + throw new \LogicException('Cannot reject a rejected promise'); } } - public function cancel() + public function cancel(): void { // pass } diff --git a/lib/Google/vendor/guzzlehttp/promises/src/RejectionException.php b/lib/Google/vendor/guzzlehttp/promises/src/RejectionException.php index e2f137707..72a81ba20 100644 --- a/lib/Google/vendor/guzzlehttp/promises/src/RejectionException.php +++ b/lib/Google/vendor/guzzlehttp/promises/src/RejectionException.php @@ -1,5 +1,7 @@ reason = $reason; $message = 'The promise was rejected'; if ($description) { - $message .= ' with reason: ' . $description; + $message .= ' with reason: '.$description; } elseif (is_string($reason) || (is_object($reason) && method_exists($reason, '__toString')) ) { - $message .= ' with reason: ' . $this->reason; + $message .= ' with reason: '.$this->reason; } elseif ($reason instanceof \JsonSerializable) { - $message .= ' with reason: ' - . json_encode($this->reason, JSON_PRETTY_PRINT); + $message .= ' with reason: '.json_encode($this->reason, JSON_PRETTY_PRINT); } parent::__construct($message); diff --git a/lib/Google/vendor/guzzlehttp/promises/src/TaskQueue.php b/lib/Google/vendor/guzzlehttp/promises/src/TaskQueue.php index f0fba2c59..503e0b2da 100644 --- a/lib/Google/vendor/guzzlehttp/promises/src/TaskQueue.php +++ b/lib/Google/vendor/guzzlehttp/promises/src/TaskQueue.php @@ -1,5 +1,7 @@ run(); + * + * @final */ class TaskQueue implements TaskQueueInterface { private $enableShutdown = true; private $queue = []; - public function __construct($withShutdown = true) + public function __construct(bool $withShutdown = true) { if ($withShutdown) { - register_shutdown_function(function () { + register_shutdown_function(function (): void { if ($this->enableShutdown) { // Only run the tasks if an E_ERROR didn't occur. $err = error_get_last(); @@ -31,17 +35,17 @@ public function __construct($withShutdown = true) } } - public function isEmpty() + public function isEmpty(): bool { return !$this->queue; } - public function add(callable $task) + public function add(callable $task): void { $this->queue[] = $task; } - public function run() + public function run(): void { while ($task = array_shift($this->queue)) { /** @var callable $task */ @@ -60,7 +64,7 @@ public function run() * * Note: This shutdown will occur before any destructors are triggered. */ - public function disableShutdown() + public function disableShutdown(): void { $this->enableShutdown = false; } diff --git a/lib/Google/vendor/guzzlehttp/promises/src/TaskQueueInterface.php b/lib/Google/vendor/guzzlehttp/promises/src/TaskQueueInterface.php index 723d4d54e..34c561a48 100644 --- a/lib/Google/vendor/guzzlehttp/promises/src/TaskQueueInterface.php +++ b/lib/Google/vendor/guzzlehttp/promises/src/TaskQueueInterface.php @@ -1,24 +1,24 @@ * - * @param TaskQueueInterface $assign Optionally specify a new queue instance. - * - * @return TaskQueueInterface + * @param TaskQueueInterface|null $assign Optionally specify a new queue instance. */ - public static function queue(TaskQueueInterface $assign = null) + public static function queue(TaskQueueInterface $assign = null): TaskQueueInterface { static $queue; @@ -39,22 +39,18 @@ public static function queue(TaskQueueInterface $assign = null) * returns a promise that is fulfilled or rejected with the result. * * @param callable $task Task function to run. - * - * @return PromiseInterface */ - public static function task(callable $task) + public static function task(callable $task): PromiseInterface { $queue = self::queue(); $promise = new Promise([$queue, 'run']); - $queue->add(function () use ($task, $promise) { + $queue->add(function () use ($task, $promise): void { try { if (Is::pending($promise)) { $promise->resolve($task()); } } catch (\Throwable $e) { $promise->reject($e); - } catch (\Exception $e) { - $promise->reject($e); } }); @@ -72,22 +68,18 @@ public static function task(callable $task) * key mapping to the rejection reason of the promise. * * @param PromiseInterface $promise Promise or value. - * - * @return array */ - public static function inspect(PromiseInterface $promise) + public static function inspect(PromiseInterface $promise): array { try { return [ 'state' => PromiseInterface::FULFILLED, - 'value' => $promise->wait() + 'value' => $promise->wait(), ]; } catch (RejectionException $e) { return ['state' => PromiseInterface::REJECTED, 'reason' => $e->getReason()]; } catch (\Throwable $e) { return ['state' => PromiseInterface::REJECTED, 'reason' => $e]; - } catch (\Exception $e) { - return ['state' => PromiseInterface::REJECTED, 'reason' => $e]; } } @@ -100,10 +92,8 @@ public static function inspect(PromiseInterface $promise) * @see inspect for the inspection state array format. * * @param PromiseInterface[] $promises Traversable of promises to wait upon. - * - * @return array */ - public static function inspectAll($promises) + public static function inspectAll($promises): array { $results = []; foreach ($promises as $key => $promise) { @@ -122,12 +112,9 @@ public static function inspectAll($promises) * * @param iterable $promises Iterable of PromiseInterface objects to wait on. * - * @return array - * - * @throws \Exception on error - * @throws \Throwable on error in PHP >=7 + * @throws \Throwable on error */ - public static function unwrap($promises) + public static function unwrap($promises): array { $results = []; foreach ($promises as $key => $promise) { @@ -147,22 +134,21 @@ public static function unwrap($promises) * * @param mixed $promises Promises or values. * @param bool $recursive If true, resolves new promises that might have been added to the stack during its own resolution. - * - * @return PromiseInterface */ - public static function all($promises, $recursive = false) + public static function all($promises, bool $recursive = false): PromiseInterface { $results = []; $promise = Each::of( $promises, - function ($value, $idx) use (&$results) { + function ($value, $idx) use (&$results): void { $results[$idx] = $value; }, - function ($reason, $idx, Promise $aggregate) { + function ($reason, $idx, Promise $aggregate): void { $aggregate->reject($reason); } )->then(function () use (&$results) { ksort($results); + return $results; }); @@ -173,6 +159,7 @@ function ($reason, $idx, Promise $aggregate) { return self::all($promises, $recursive); } } + return $results; }); } @@ -193,17 +180,15 @@ function ($reason, $idx, Promise $aggregate) { * * @param int $count Total number of promises. * @param mixed $promises Promises or values. - * - * @return PromiseInterface */ - public static function some($count, $promises) + public static function some(int $count, $promises): PromiseInterface { $results = []; $rejections = []; return Each::of( $promises, - function ($value, $idx, PromiseInterface $p) use (&$results, $count) { + function ($value, $idx, PromiseInterface $p) use (&$results, $count): void { if (Is::settled($p)) { return; } @@ -212,7 +197,7 @@ function ($value, $idx, PromiseInterface $p) use (&$results, $count) { $p->resolve(null); } }, - function ($reason) use (&$rejections) { + function ($reason) use (&$rejections): void { $rejections[] = $reason; } )->then( @@ -224,6 +209,7 @@ function () use (&$results, &$rejections, $count) { ); } ksort($results); + return array_values($results); } ); @@ -234,10 +220,8 @@ function () use (&$results, &$rejections, $count) { * fulfillment value is not an array of 1 but the value directly. * * @param mixed $promises Promises or values. - * - * @return PromiseInterface */ - public static function any($promises) + public static function any($promises): PromiseInterface { return self::some(1, $promises)->then(function ($values) { return $values[0]; @@ -253,23 +237,22 @@ public static function any($promises) * @see inspect for the inspection state array format. * * @param mixed $promises Promises or values. - * - * @return PromiseInterface */ - public static function settle($promises) + public static function settle($promises): PromiseInterface { $results = []; return Each::of( $promises, - function ($value, $idx) use (&$results) { + function ($value, $idx) use (&$results): void { $results[$idx] = ['state' => PromiseInterface::FULFILLED, 'value' => $value]; }, - function ($reason, $idx) use (&$results) { + function ($reason, $idx) use (&$results): void { $results[$idx] = ['state' => PromiseInterface::REJECTED, 'reason' => $reason]; } )->then(function () use (&$results) { ksort($results); + return $results; }); } diff --git a/lib/Google/vendor/guzzlehttp/promises/src/functions.php b/lib/Google/vendor/guzzlehttp/promises/src/functions.php deleted file mode 100644 index c03d39d02..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/src/functions.php +++ /dev/null @@ -1,363 +0,0 @@ - - * while ($eventLoop->isRunning()) { - * GuzzleHttp\Promise\queue()->run(); - * } - * - * - * @param TaskQueueInterface $assign Optionally specify a new queue instance. - * - * @return TaskQueueInterface - * - * @deprecated queue will be removed in guzzlehttp/promises:2.0. Use Utils::queue instead. - */ -function queue(TaskQueueInterface $assign = null) -{ - return Utils::queue($assign); -} - -/** - * Adds a function to run in the task queue when it is next `run()` and returns - * a promise that is fulfilled or rejected with the result. - * - * @param callable $task Task function to run. - * - * @return PromiseInterface - * - * @deprecated task will be removed in guzzlehttp/promises:2.0. Use Utils::task instead. - */ -function task(callable $task) -{ - return Utils::task($task); -} - -/** - * Creates a promise for a value if the value is not a promise. - * - * @param mixed $value Promise or value. - * - * @return PromiseInterface - * - * @deprecated promise_for will be removed in guzzlehttp/promises:2.0. Use Create::promiseFor instead. - */ -function promise_for($value) -{ - return Create::promiseFor($value); -} - -/** - * Creates a rejected promise for a reason if the reason is not a promise. If - * the provided reason is a promise, then it is returned as-is. - * - * @param mixed $reason Promise or reason. - * - * @return PromiseInterface - * - * @deprecated rejection_for will be removed in guzzlehttp/promises:2.0. Use Create::rejectionFor instead. - */ -function rejection_for($reason) -{ - return Create::rejectionFor($reason); -} - -/** - * Create an exception for a rejected promise value. - * - * @param mixed $reason - * - * @return \Exception|\Throwable - * - * @deprecated exception_for will be removed in guzzlehttp/promises:2.0. Use Create::exceptionFor instead. - */ -function exception_for($reason) -{ - return Create::exceptionFor($reason); -} - -/** - * Returns an iterator for the given value. - * - * @param mixed $value - * - * @return \Iterator - * - * @deprecated iter_for will be removed in guzzlehttp/promises:2.0. Use Create::iterFor instead. - */ -function iter_for($value) -{ - return Create::iterFor($value); -} - -/** - * Synchronously waits on a promise to resolve and returns an inspection state - * array. - * - * Returns a state associative array containing a "state" key mapping to a - * valid promise state. If the state of the promise is "fulfilled", the array - * will contain a "value" key mapping to the fulfilled value of the promise. If - * the promise is rejected, the array will contain a "reason" key mapping to - * the rejection reason of the promise. - * - * @param PromiseInterface $promise Promise or value. - * - * @return array - * - * @deprecated inspect will be removed in guzzlehttp/promises:2.0. Use Utils::inspect instead. - */ -function inspect(PromiseInterface $promise) -{ - return Utils::inspect($promise); -} - -/** - * Waits on all of the provided promises, but does not unwrap rejected promises - * as thrown exception. - * - * Returns an array of inspection state arrays. - * - * @see inspect for the inspection state array format. - * - * @param PromiseInterface[] $promises Traversable of promises to wait upon. - * - * @return array - * - * @deprecated inspect will be removed in guzzlehttp/promises:2.0. Use Utils::inspectAll instead. - */ -function inspect_all($promises) -{ - return Utils::inspectAll($promises); -} - -/** - * Waits on all of the provided promises and returns the fulfilled values. - * - * Returns an array that contains the value of each promise (in the same order - * the promises were provided). An exception is thrown if any of the promises - * are rejected. - * - * @param iterable $promises Iterable of PromiseInterface objects to wait on. - * - * @return array - * - * @throws \Exception on error - * @throws \Throwable on error in PHP >=7 - * - * @deprecated unwrap will be removed in guzzlehttp/promises:2.0. Use Utils::unwrap instead. - */ -function unwrap($promises) -{ - return Utils::unwrap($promises); -} - -/** - * Given an array of promises, return a promise that is fulfilled when all the - * items in the array are fulfilled. - * - * The promise's fulfillment value is an array with fulfillment values at - * respective positions to the original array. If any promise in the array - * rejects, the returned promise is rejected with the rejection reason. - * - * @param mixed $promises Promises or values. - * @param bool $recursive If true, resolves new promises that might have been added to the stack during its own resolution. - * - * @return PromiseInterface - * - * @deprecated all will be removed in guzzlehttp/promises:2.0. Use Utils::all instead. - */ -function all($promises, $recursive = false) -{ - return Utils::all($promises, $recursive); -} - -/** - * Initiate a competitive race between multiple promises or values (values will - * become immediately fulfilled promises). - * - * When count amount of promises have been fulfilled, the returned promise is - * fulfilled with an array that contains the fulfillment values of the winners - * in order of resolution. - * - * This promise is rejected with a {@see AggregateException} if the number of - * fulfilled promises is less than the desired $count. - * - * @param int $count Total number of promises. - * @param mixed $promises Promises or values. - * - * @return PromiseInterface - * - * @deprecated some will be removed in guzzlehttp/promises:2.0. Use Utils::some instead. - */ -function some($count, $promises) -{ - return Utils::some($count, $promises); -} - -/** - * Like some(), with 1 as count. However, if the promise fulfills, the - * fulfillment value is not an array of 1 but the value directly. - * - * @param mixed $promises Promises or values. - * - * @return PromiseInterface - * - * @deprecated any will be removed in guzzlehttp/promises:2.0. Use Utils::any instead. - */ -function any($promises) -{ - return Utils::any($promises); -} - -/** - * Returns a promise that is fulfilled when all of the provided promises have - * been fulfilled or rejected. - * - * The returned promise is fulfilled with an array of inspection state arrays. - * - * @see inspect for the inspection state array format. - * - * @param mixed $promises Promises or values. - * - * @return PromiseInterface - * - * @deprecated settle will be removed in guzzlehttp/promises:2.0. Use Utils::settle instead. - */ -function settle($promises) -{ - return Utils::settle($promises); -} - -/** - * Given an iterator that yields promises or values, returns a promise that is - * fulfilled with a null value when the iterator has been consumed or the - * aggregate promise has been fulfilled or rejected. - * - * $onFulfilled is a function that accepts the fulfilled value, iterator index, - * and the aggregate promise. The callback can invoke any necessary side - * effects and choose to resolve or reject the aggregate if needed. - * - * $onRejected is a function that accepts the rejection reason, iterator index, - * and the aggregate promise. The callback can invoke any necessary side - * effects and choose to resolve or reject the aggregate if needed. - * - * @param mixed $iterable Iterator or array to iterate over. - * @param callable $onFulfilled - * @param callable $onRejected - * - * @return PromiseInterface - * - * @deprecated each will be removed in guzzlehttp/promises:2.0. Use Each::of instead. - */ -function each( - $iterable, - callable $onFulfilled = null, - callable $onRejected = null -) { - return Each::of($iterable, $onFulfilled, $onRejected); -} - -/** - * Like each, but only allows a certain number of outstanding promises at any - * given time. - * - * $concurrency may be an integer or a function that accepts the number of - * pending promises and returns a numeric concurrency limit value to allow for - * dynamic a concurrency size. - * - * @param mixed $iterable - * @param int|callable $concurrency - * @param callable $onFulfilled - * @param callable $onRejected - * - * @return PromiseInterface - * - * @deprecated each_limit will be removed in guzzlehttp/promises:2.0. Use Each::ofLimit instead. - */ -function each_limit( - $iterable, - $concurrency, - callable $onFulfilled = null, - callable $onRejected = null -) { - return Each::ofLimit($iterable, $concurrency, $onFulfilled, $onRejected); -} - -/** - * Like each_limit, but ensures that no promise in the given $iterable argument - * is rejected. If any promise is rejected, then the aggregate promise is - * rejected with the encountered rejection. - * - * @param mixed $iterable - * @param int|callable $concurrency - * @param callable $onFulfilled - * - * @return PromiseInterface - * - * @deprecated each_limit_all will be removed in guzzlehttp/promises:2.0. Use Each::ofLimitAll instead. - */ -function each_limit_all( - $iterable, - $concurrency, - callable $onFulfilled = null -) { - return Each::ofLimitAll($iterable, $concurrency, $onFulfilled); -} - -/** - * Returns true if a promise is fulfilled. - * - * @return bool - * - * @deprecated is_fulfilled will be removed in guzzlehttp/promises:2.0. Use Is::fulfilled instead. - */ -function is_fulfilled(PromiseInterface $promise) -{ - return Is::fulfilled($promise); -} - -/** - * Returns true if a promise is rejected. - * - * @return bool - * - * @deprecated is_rejected will be removed in guzzlehttp/promises:2.0. Use Is::rejected instead. - */ -function is_rejected(PromiseInterface $promise) -{ - return Is::rejected($promise); -} - -/** - * Returns true if a promise is fulfilled or rejected. - * - * @return bool - * - * @deprecated is_settled will be removed in guzzlehttp/promises:2.0. Use Is::settled instead. - */ -function is_settled(PromiseInterface $promise) -{ - return Is::settled($promise); -} - -/** - * Create a new coroutine. - * - * @see Coroutine - * - * @return PromiseInterface - * - * @deprecated coroutine will be removed in guzzlehttp/promises:2.0. Use Coroutine::of instead. - */ -function coroutine(callable $generatorFn) -{ - return Coroutine::of($generatorFn); -} diff --git a/lib/Google/vendor/guzzlehttp/promises/src/functions_include.php b/lib/Google/vendor/guzzlehttp/promises/src/functions_include.php deleted file mode 100644 index 34cd1710a..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/src/functions_include.php +++ /dev/null @@ -1,6 +0,0 @@ -assertStringContainsString('foo', $e->getMessage()); - $this->assertSame(['baz', 'bar'], $e->getReason()); - } -} diff --git a/lib/Google/vendor/guzzlehttp/promises/tests/CoroutineTest.php b/lib/Google/vendor/guzzlehttp/promises/tests/CoroutineTest.php deleted file mode 100644 index ed91a8cc4..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/tests/CoroutineTest.php +++ /dev/null @@ -1,113 +0,0 @@ -assertInstanceOf(P\Coroutine::class, P\Coroutine::of($fn)); - } - - /** - * @dataProvider promiseInterfaceMethodProvider - * - * @param string $method - * @param array $args - */ - public function testShouldProxyPromiseMethodsToResultPromise($method, $args = []) - { - $coroutine = new Coroutine(function () { yield 0; }); - $mockPromise = $this->getMockForAbstractClass(PromiseInterface::class); - call_user_func_array([$mockPromise->expects($this->once())->method($method), 'with'], $args); - - $resultPromiseProp = (new ReflectionClass(Coroutine::class))->getProperty('result'); - $resultPromiseProp->setAccessible(true); - $resultPromiseProp->setValue($coroutine, $mockPromise); - - call_user_func_array([$coroutine, $method], $args); - } - - public function promiseInterfaceMethodProvider() - { - return [ - ['then', [null, null]], - ['otherwise', [function () {}]], - ['wait', [true]], - ['getState', []], - ['resolve', [null]], - ['reject', [null]], - ]; - } - - public function testShouldCancelResultPromiseAndOutsideCurrentPromise() - { - $coroutine = new Coroutine(function () { yield 0; }); - - $mockPromises = [ - 'result' => $this->getMockForAbstractClass(PromiseInterface::class), - 'currentPromise' => $this->getMockForAbstractClass(PromiseInterface::class), - ]; - foreach ($mockPromises as $propName => $mockPromise) { - /** - * @var $mockPromise \PHPUnit_Framework_MockObject_MockObject - */ - $mockPromise->expects($this->once()) - ->method('cancel') - ->with(); - - $promiseProp = (new ReflectionClass(Coroutine::class))->getProperty($propName); - $promiseProp->setAccessible(true); - $promiseProp->setValue($coroutine, $mockPromise); - } - - $coroutine->cancel(); - } - - public function testWaitShouldResolveChainedCoroutines() - { - $promisor = function () { - return P\Coroutine::of(function () { - yield $promise = new Promise(function () use (&$promise) { - $promise->resolve(1); - }); - }); - }; - - $promise = $promisor()->then($promisor)->then($promisor); - - $this->assertSame(1, $promise->wait()); - } - - public function testWaitShouldHandleIntermediateErrors() - { - $promise = P\Coroutine::of(function () { - yield $promise = new Promise(function () use (&$promise) { - $promise->resolve(1); - }); - }) - ->then(function () { - return P\Coroutine::of(function () { - yield $promise = new Promise(function () use (&$promise) { - $promise->reject(new \Exception); - }); - }); - }) - ->otherwise(function (\Exception $error = null) { - if (!$error) { - self::fail('Error did not propagate.'); - } - return 3; - }); - - $this->assertSame(3, $promise->wait()); - } -} diff --git a/lib/Google/vendor/guzzlehttp/promises/tests/CreateTest.php b/lib/Google/vendor/guzzlehttp/promises/tests/CreateTest.php deleted file mode 100644 index a4cc9317d..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/tests/CreateTest.php +++ /dev/null @@ -1,56 +0,0 @@ -assertInstanceOf(FulfilledPromise::class, $p); - } - - public function testReturnsPromiseForPromise() - { - $p = new Promise(); - $this->assertSame($p, P\Create::promiseFor($p)); - } - - public function testReturnsPromiseForThennable() - { - $p = new Thennable(); - $wrapped = P\Create::promiseFor($p); - $this->assertNotSame($p, $wrapped); - $this->assertInstanceOf(PromiseInterface::class, $wrapped); - $p->resolve('foo'); - P\Utils::queue()->run(); - $this->assertSame('foo', $wrapped->wait()); - } - - public function testReturnsRejection() - { - $p = P\Create::rejectionFor('fail'); - $this->assertInstanceOf(RejectedPromise::class, $p); - $this->assertSame('fail', PropertyHelper::get($p, 'reason')); - } - - public function testReturnsPromisesAsIsInRejectionFor() - { - $a = new Promise(); - $b = P\Create::rejectionFor($a); - $this->assertSame($a, $b); - } - - public function testIterForReturnsIterator() - { - $iter = new \ArrayIterator(); - $this->assertSame($iter, P\Create::iterFor($iter)); - } -} diff --git a/lib/Google/vendor/guzzlehttp/promises/tests/EachPromiseTest.php b/lib/Google/vendor/guzzlehttp/promises/tests/EachPromiseTest.php deleted file mode 100644 index d5dc9cfea..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/tests/EachPromiseTest.php +++ /dev/null @@ -1,430 +0,0 @@ - 100]); - $this->assertSame($each->promise(), $each->promise()); - } - - public function testResolvesInCaseOfAnEmptyList() - { - $promises = []; - $each = new EachPromise($promises); - $p = $each->promise(); - $this->assertNull($p->wait()); - $this->assertTrue(P\Is::fulfilled($p)); - } - - public function testResolvesInCaseOfAnEmptyListAndInvokesFulfilled() - { - $promises = []; - $each = new EachPromise($promises); - $p = $each->promise(); - $onFulfilledCalled = false; - $onRejectedCalled = false; - $p->then( - function () use (&$onFulfilledCalled) { - $onFulfilledCalled = true; - }, - function () use (&$onRejectedCalled) { - $onRejectedCalled = true; - } - ); - $this->assertNull($p->wait()); - $this->assertTrue(P\Is::fulfilled($p)); - $this->assertTrue($onFulfilledCalled); - $this->assertFalse($onRejectedCalled); - } - - public function testInvokesAllPromises() - { - $promises = [new Promise(), new Promise(), new Promise()]; - $called = []; - $each = new EachPromise($promises, [ - 'fulfilled' => function ($value) use (&$called) { - $called[] = $value; - } - ]); - $p = $each->promise(); - $promises[0]->resolve('a'); - $promises[1]->resolve('c'); - $promises[2]->resolve('b'); - P\Utils::queue()->run(); - $this->assertSame(['a', 'c', 'b'], $called); - $this->assertTrue(P\Is::fulfilled($p)); - } - - public function testIsWaitable() - { - $a = $this->createSelfResolvingPromise('a'); - $b = $this->createSelfResolvingPromise('b'); - $called = []; - $each = new EachPromise([$a, $b], [ - 'fulfilled' => function ($value) use (&$called) { $called[] = $value; } - ]); - $p = $each->promise(); - $this->assertNull($p->wait()); - $this->assertTrue(P\Is::fulfilled($p)); - $this->assertSame(['a', 'b'], $called); - } - - public function testCanResolveBeforeConsumingAll() - { - $called = 0; - $a = $this->createSelfResolvingPromise('a'); - $b = new Promise(function () { $this->fail(); }); - $each = new EachPromise([$a, $b], [ - 'fulfilled' => function ($value, $idx, Promise $aggregate) use (&$called) { - $this->assertSame($idx, 0); - $this->assertSame('a', $value); - $aggregate->resolve(null); - $called++; - }, - 'rejected' => function (\Exception $reason) { - $this->fail($reason->getMessage()); - } - ]); - $p = $each->promise(); - $p->wait(); - $this->assertNull($p->wait()); - $this->assertSame(1, $called); - $this->assertTrue(P\Is::fulfilled($a)); - $this->assertTrue(P\Is::pending($b)); - // Resolving $b has no effect on the aggregate promise. - $b->resolve('foo'); - $this->assertSame(1, $called); - } - - public function testLimitsPendingPromises() - { - $pending = [new Promise(), new Promise(), new Promise(), new Promise()]; - $promises = new \ArrayIterator($pending); - $each = new EachPromise($promises, ['concurrency' => 2]); - $p = $each->promise(); - $this->assertCount(2, PropertyHelper::get($each, 'pending')); - $pending[0]->resolve('a'); - $this->assertCount(2, PropertyHelper::get($each, 'pending')); - $this->assertTrue($promises->valid()); - $pending[1]->resolve('b'); - P\Utils::queue()->run(); - $this->assertCount(2, PropertyHelper::get($each, 'pending')); - $this->assertTrue($promises->valid()); - $promises[2]->resolve('c'); - P\Utils::queue()->run(); - $this->assertCount(1, PropertyHelper::get($each, 'pending')); - $this->assertTrue(P\Is::pending($p)); - $promises[3]->resolve('d'); - P\Utils::queue()->run(); - $this->assertNull(PropertyHelper::get($each, 'pending')); - $this->assertTrue(P\Is::fulfilled($p)); - $this->assertFalse($promises->valid()); - } - - public function testDynamicallyLimitsPendingPromises() - { - $calls = []; - $pendingFn = function ($count) use (&$calls) { - $calls[] = $count; - return 2; - }; - $pending = [new Promise(), new Promise(), new Promise(), new Promise()]; - $promises = new \ArrayIterator($pending); - $each = new EachPromise($promises, ['concurrency' => $pendingFn]); - $p = $each->promise(); - $this->assertCount(2, PropertyHelper::get($each, 'pending')); - $pending[0]->resolve('a'); - $this->assertCount(2, PropertyHelper::get($each, 'pending')); - $this->assertTrue($promises->valid()); - $pending[1]->resolve('b'); - $this->assertCount(2, PropertyHelper::get($each, 'pending')); - P\Utils::queue()->run(); - $this->assertTrue($promises->valid()); - $promises[2]->resolve('c'); - P\Utils::queue()->run(); - $this->assertCount(1, PropertyHelper::get($each, 'pending')); - $this->assertTrue(P\Is::pending($p)); - $promises[3]->resolve('d'); - P\Utils::queue()->run(); - $this->assertNull(PropertyHelper::get($each, 'pending')); - $this->assertTrue(P\Is::fulfilled($p)); - $this->assertSame([0, 1, 1, 1], $calls); - $this->assertFalse($promises->valid()); - } - - public function testClearsReferencesWhenResolved() - { - $called = false; - $a = new Promise(function () use (&$a, &$called) { - $a->resolve('a'); - $called = true; - }); - $each = new EachPromise([$a], [ - 'concurrency' => function () { return 1; }, - 'fulfilled' => function () {}, - 'rejected' => function () {} - ]); - $each->promise()->wait(); - $this->assertNull(PropertyHelper::get($each, 'onFulfilled')); - $this->assertNull(PropertyHelper::get($each, 'onRejected')); - $this->assertNull(PropertyHelper::get($each, 'iterable')); - $this->assertNull(PropertyHelper::get($each, 'pending')); - $this->assertNull(PropertyHelper::get($each, 'concurrency')); - $this->assertTrue($called); - } - - public function testCanBeCancelled() - { - $called = false; - $a = new FulfilledPromise('a'); - $b = new Promise(function () use (&$called) { $called = true; }); - $each = new EachPromise([$a, $b], [ - 'fulfilled' => function ($value, $idx, Promise $aggregate) { - $aggregate->cancel(); - }, - 'rejected' => function ($reason) use (&$called) { - $called = true; - }, - ]); - $p = $each->promise(); - $p->wait(false); - $this->assertTrue(P\Is::fulfilled($a)); - $this->assertTrue(P\Is::pending($b)); - $this->assertTrue(P\Is::rejected($p)); - $this->assertFalse($called); - } - - public function testDoesNotBlowStackWithFulfilledPromises() - { - $pending = []; - for ($i = 0; $i < 100; $i++) { - $pending[] = new FulfilledPromise($i); - } - $values = []; - $each = new EachPromise($pending, [ - 'fulfilled' => function ($value) use (&$values) { - $values[] = $value; - } - ]); - $called = false; - $each->promise()->then(function () use (&$called) { - $called = true; - }); - $this->assertFalse($called); - P\Utils::queue()->run(); - $this->assertTrue($called); - $this->assertSame(range(0, 99), $values); - } - - public function testDoesNotBlowStackWithRejectedPromises() - { - $pending = []; - for ($i = 0; $i < 100; $i++) { - $pending[] = new RejectedPromise($i); - } - $values = []; - $each = new EachPromise($pending, [ - 'rejected' => function ($value) use (&$values) { - $values[] = $value; - } - ]); - $called = false; - $each->promise()->then( - function () use (&$called) { $called = true; }, - function () { $this->fail('Should not have rejected.'); } - ); - $this->assertFalse($called); - P\Utils::queue()->run(); - $this->assertTrue($called); - $this->assertSame(range(0, 99), $values); - } - - public function testReturnsPromiseForWhatever() - { - $called = []; - $arr = ['a', 'b']; - $each = new EachPromise($arr, [ - 'fulfilled' => function ($v) use (&$called) { $called[] = $v; } - ]); - $p = $each->promise(); - $this->assertNull($p->wait()); - $this->assertSame(['a', 'b'], $called); - } - - public function testRejectsAggregateWhenNextThrows() - { - $iter = function () { - yield 'a'; - throw new \Exception('Failure'); - }; - $each = new EachPromise($iter()); - $p = $each->promise(); - $e = null; - $received = null; - $p->then(null, function ($reason) use (&$e) { $e = $reason; }); - P\Utils::queue()->run(); - $this->assertInstanceOf(\Exception::class, $e); - $this->assertSame('Failure', $e->getMessage()); - } - - public function testDoesNotCallNextOnIteratorUntilNeededWhenWaiting() - { - $results = []; - $values = [10]; - $remaining = 9; - $iter = function () use (&$values) { - while ($value = array_pop($values)) { - yield $value; - } - }; - $each = new EachPromise($iter(), [ - 'concurrency' => 1, - 'fulfilled' => function ($r) use (&$results, &$values, &$remaining) { - $results[] = $r; - if ($remaining > 0) { - $values[] = $remaining--; - } - } - ]); - $each->promise()->wait(); - $this->assertSame(range(10, 1), $results); - } - - public function testDoesNotCallNextOnIteratorUntilNeededWhenAsync() - { - $firstPromise = new Promise(); - $pending = [$firstPromise]; - $values = [$firstPromise]; - $results = []; - $remaining = 9; - $iter = function () use (&$values) { - while ($value = array_pop($values)) { - yield $value; - } - }; - $each = new EachPromise($iter(), [ - 'concurrency' => 1, - 'fulfilled' => function ($r) use (&$results, &$values, &$remaining, &$pending) { - $results[] = $r; - if ($remaining-- > 0) { - $pending[] = $values[] = new Promise(); - } - } - ]); - $i = 0; - $each->promise(); - while ($promise = array_pop($pending)) { - $promise->resolve($i++); - P\Utils::queue()->run(); - } - $this->assertSame(range(0, 9), $results); - } - - private function createSelfResolvingPromise($value) - { - $p = new Promise(function () use (&$p, $value) { - $p->resolve($value); - }); - $trickCsFixer = true; - - return $p; - } - - public function testMutexPreventsGeneratorRecursion() - { - if (defined('HHVM_VERSION')) { - $this->markTestIncomplete('Broken on HHVM.'); - } - - $results = $promises = []; - for ($i = 0; $i < 20; $i++) { - $p = $this->createSelfResolvingPromise($i); - $pending[] = $p; - $promises[] = $p; - } - - $iter = function () use (&$promises, &$pending) { - foreach ($promises as $promise) { - // Resolve a promises, which will trigger the then() function, - // which would cause the EachPromise to try to add more - // promises to the queue. Without a lock, this would trigger - // a "Cannot resume an already running generator" fatal error. - if ($p = array_pop($pending)) { - $p->wait(); - } - yield $promise; - } - }; - - $each = new EachPromise($iter(), [ - 'concurrency' => 5, - 'fulfilled' => function ($r) use (&$results, &$pending) { - $results[] = $r; - } - ]); - - $each->promise()->wait(); - $this->assertCount(20, $results); - } - - public function testIteratorWithSameKey() - { - if (defined('HHVM_VERSION')) { - $this->markTestIncomplete('Broken on HHVM.'); - } - - $iter = function () { - yield 'foo' => $this->createSelfResolvingPromise(1); - yield 'foo' => $this->createSelfResolvingPromise(2); - yield 1 => $this->createSelfResolvingPromise(3); - yield 1 => $this->createSelfResolvingPromise(4); - }; - $called = 0; - $each = new EachPromise($iter(), [ - 'fulfilled' => function ($value, $idx, Promise $aggregate) use (&$called) { - $called++; - if ($value < 3) { - $this->assertSame('foo', $idx); - } else { - $this->assertSame(1, $idx); - } - }, - ]); - $each->promise()->wait(); - $this->assertSame(4, $called); - } - - public function testIsWaitableWhenLimited() - { - $promises = [ - $this->createSelfResolvingPromise('a'), - $this->createSelfResolvingPromise('c'), - $this->createSelfResolvingPromise('b'), - $this->createSelfResolvingPromise('d') - ]; - $called = []; - $each = new EachPromise($promises, [ - 'concurrency' => 2, - 'fulfilled' => function ($value) use (&$called) { - $called[] = $value; - } - ]); - $p = $each->promise(); - $this->assertNull($p->wait()); - $this->assertSame(['a', 'c', 'b', 'd'], $called); - $this->assertTrue(P\Is::fulfilled($p)); - } -} diff --git a/lib/Google/vendor/guzzlehttp/promises/tests/EachTest.php b/lib/Google/vendor/guzzlehttp/promises/tests/EachTest.php deleted file mode 100644 index b6473b866..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/tests/EachTest.php +++ /dev/null @@ -1,34 +0,0 @@ -resolve('a'); - P\Utils::queue()->run(); - $this->assertTrue(P\Is::fulfilled($aggregate)); - } - - public function testEachLimitAllRejectsOnFailure() - { - $p = [new FulfilledPromise('a'), new RejectedPromise('b')]; - $aggregate = P\Each::ofLimitAll($p, 2); - - P\Utils::queue()->run(); - $this->assertTrue(P\Is::rejected($aggregate)); - - $result = P\Utils::inspect($aggregate); - $this->assertSame('b', $result['reason']); - } -} diff --git a/lib/Google/vendor/guzzlehttp/promises/tests/FulfilledPromiseTest.php b/lib/Google/vendor/guzzlehttp/promises/tests/FulfilledPromiseTest.php deleted file mode 100644 index 2bbc6a8d6..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/tests/FulfilledPromiseTest.php +++ /dev/null @@ -1,113 +0,0 @@ -assertTrue(P\Is::fulfilled($p)); - $this->assertSame('foo', $p->wait(true)); - } - - public function testCannotCancel() - { - $p = new FulfilledPromise('foo'); - $this->assertTrue(P\Is::fulfilled($p)); - $p->cancel(); - $this->assertSame('foo', $p->wait()); - } - - /** - * @expectedExceptionMessage Cannot resolve a fulfilled promise - */ - public function testCannotResolve() - { - $this->expectException(\LogicException::class); - - $p = new FulfilledPromise('foo'); - $p->resolve('bar'); - } - - /** - * @expectedExceptionMessage Cannot reject a fulfilled promise - */ - public function testCannotReject() - { - $this->expectException(\LogicException::class); - - $p = new FulfilledPromise('foo'); - $p->reject('bar'); - } - - public function testCanResolveWithSameValue() - { - $p = new FulfilledPromise('foo'); - $p->resolve('foo'); - $this->assertSame('foo', $p->wait()); - } - - public function testCannotResolveWithPromise() - { - $this->expectException(\InvalidArgumentException::class); - - new FulfilledPromise(new Promise()); - } - - public function testReturnsSelfWhenNoOnFulfilled() - { - $p = new FulfilledPromise('a'); - $this->assertSame($p, $p->then()); - } - - public function testAsynchronouslyInvokesOnFulfilled() - { - $p = new FulfilledPromise('a'); - $r = null; - $f = function ($d) use (&$r) { $r = $d; }; - $p2 = $p->then($f); - $this->assertNotSame($p, $p2); - $this->assertNull($r); - P\Utils::queue()->run(); - $this->assertSame('a', $r); - } - - public function testReturnsNewRejectedWhenOnFulfilledFails() - { - $p = new FulfilledPromise('a'); - $f = function () { throw new \Exception('b'); }; - $p2 = $p->then($f); - $this->assertNotSame($p, $p2); - try { - $p2->wait(); - $this->fail(); - } catch (\Exception $e) { - $this->assertSame('b', $e->getMessage()); - } - } - - public function testOtherwiseIsSugarForRejections() - { - $c = null; - $p = new FulfilledPromise('foo'); - $p->otherwise(function ($v) use (&$c) { $c = $v; }); - $this->assertNull($c); - } - - public function testDoesNotTryToFulfillTwiceDuringTrampoline() - { - $fp = new FulfilledPromise('a'); - $t1 = $fp->then(function ($v) { return $v . ' b'; }); - $t1->resolve('why!'); - $this->assertSame('why!', $t1->wait()); - } -} diff --git a/lib/Google/vendor/guzzlehttp/promises/tests/IsTest.php b/lib/Google/vendor/guzzlehttp/promises/tests/IsTest.php deleted file mode 100644 index 0a7ade3fd..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/tests/IsTest.php +++ /dev/null @@ -1,40 +0,0 @@ -assertTrue(P\Is::fulfilled($p)); - $this->assertFalse(P\Is::rejected($p)); - } - - public function testKnowsIfRejected() - { - $p = new RejectedPromise(null); - $this->assertTrue(P\Is::rejected($p)); - $this->assertFalse(P\Is::fulfilled($p)); - } - - public function testKnowsIfSettled() - { - $p = new RejectedPromise(null); - $this->assertTrue(P\Is::settled($p)); - $this->assertFalse(P\Is::pending($p)); - } - - public function testKnowsIfPending() - { - $p = new Promise(); - $this->assertFalse(P\Is::settled($p)); - $this->assertTrue(P\Is::pending($p)); - } -} diff --git a/lib/Google/vendor/guzzlehttp/promises/tests/NotPromiseInstance.php b/lib/Google/vendor/guzzlehttp/promises/tests/NotPromiseInstance.php deleted file mode 100644 index bb1bc763e..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/tests/NotPromiseInstance.php +++ /dev/null @@ -1,49 +0,0 @@ -nextPromise = new Promise(); - } - - public function then(callable $res = null, callable $rej = null) - { - return $this->nextPromise->then($res, $rej); - } - - public function otherwise(callable $onRejected) - { - return $this->then($onRejected); - } - - public function resolve($value) - { - $this->nextPromise->resolve($value); - } - - public function reject($reason) - { - $this->nextPromise->reject($reason); - } - - public function wait($unwrap = true, $defaultResolution = null) - { - } - - public function cancel() - { - } - - public function getState() - { - return $this->nextPromise->getState(); - } -} diff --git a/lib/Google/vendor/guzzlehttp/promises/tests/PromiseTest.php b/lib/Google/vendor/guzzlehttp/promises/tests/PromiseTest.php deleted file mode 100644 index 7e4e91428..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/tests/PromiseTest.php +++ /dev/null @@ -1,761 +0,0 @@ -expectException(\LogicException::class); - $this->expectExceptionMessage('The promise is already fulfilled'); - - $p = new Promise(); - $p->resolve('foo'); - $p->resolve('bar'); - $this->assertSame('foo', $p->wait()); - } - - public function testCanResolveWithSameValue() - { - $p = new Promise(); - $p->resolve('foo'); - $p->resolve('foo'); - $this->assertSame('foo', $p->wait()); - } - - public function testCannotRejectNonPendingPromise() - { - $this->expectException(\LogicException::class); - $this->expectExceptionMessage('Cannot change a fulfilled promise to rejected'); - - $p = new Promise(); - $p->resolve('foo'); - $p->reject('bar'); - $this->assertSame('foo', $p->wait()); - } - - public function testCanRejectWithSameValue() - { - $p = new Promise(); - $p->reject('foo'); - $p->reject('foo'); - $this->assertTrue(P\Is::rejected($p)); - } - - public function testCannotRejectResolveWithSameValue() - { - $this->expectException(\LogicException::class); - $this->expectExceptionMessage('Cannot change a fulfilled promise to rejected'); - - $p = new Promise(); - $p->resolve('foo'); - $p->reject('foo'); - } - - public function testInvokesWaitFunction() - { - $p = new Promise(function () use (&$p) { - $p->resolve('10'); - }); - $this->assertSame('10', $p->wait()); - } - - public function testRejectsAndThrowsWhenWaitFailsToResolve() - { - $this->expectException(\GuzzleHttp\Promise\RejectionException::class); - $this->expectExceptionMessage('The promise was rejected with reason: Invoking the wait callback did not resolve the promise'); - - $p = new Promise(function () {}); - $p->wait(); - } - - public function testThrowsWhenUnwrapIsRejectedWithNonException() - { - $this->expectException(\GuzzleHttp\Promise\RejectionException::class); - $this->expectExceptionMessage('The promise was rejected with reason: foo'); - - $p = new Promise(function () use (&$p) { - $p->reject('foo'); - }); - $p->wait(); - } - - public function testThrowsWhenUnwrapIsRejectedWithException() - { - $this->expectException(\UnexpectedValueException::class); - $this->expectExceptionMessage('foo'); - - $e = new \UnexpectedValueException('foo'); - $p = new Promise(function () use (&$p, $e) { - $p->reject($e); - }); - $p->wait(); - } - - public function testDoesNotUnwrapExceptionsWhenDisabled() - { - $p = new Promise(function () use (&$p) { - $p->reject('foo'); - }); - $this->assertTrue(P\Is::pending($p)); - $p->wait(false); - $this->assertTrue(P\Is::rejected($p)); - } - - public function testRejectsSelfWhenWaitThrows() - { - $e = new \UnexpectedValueException('foo'); - $p = new Promise(function () use ($e) { - throw $e; - }); - try { - $p->wait(); - $this->fail(); - } catch (\UnexpectedValueException $e) { - $this->assertTrue(P\Is::rejected($p)); - } - } - - public function testWaitsOnNestedPromises() - { - $p = new Promise(function () use (&$p) { - $p->resolve('_'); - }); - $p2 = new Promise(function () use (&$p2) { - $p2->resolve('foo'); - }); - $p3 = $p->then(function () use ($p2) { - return $p2; - }); - $this->assertSame('foo', $p3->wait()); - } - - public function testThrowsWhenWaitingOnPromiseWithNoWaitFunction() - { - $this->expectException(\GuzzleHttp\Promise\RejectionException::class); - - $p = new Promise(); - $p->wait(); - } - - public function testThrowsWaitExceptionAfterPromiseIsResolved() - { - $p = new Promise(function () use (&$p) { - $p->reject('Foo!'); - throw new \Exception('Bar?'); - }); - - try { - $p->wait(); - $this->fail(); - } catch (\Exception $e) { - $this->assertSame('Bar?', $e->getMessage()); - } - } - - public function testGetsActualWaitValueFromThen() - { - $p = new Promise(function () use (&$p) { - $p->reject('Foo!'); - }); - $p2 = $p->then(null, function ($reason) { - return new RejectedPromise([$reason]); - }); - - try { - $p2->wait(); - $this->fail('Should have thrown'); - } catch (RejectionException $e) { - $this->assertSame(['Foo!'], $e->getReason()); - } - } - - public function testWaitBehaviorIsBasedOnLastPromiseInChain() - { - $p3 = new Promise(function () use (&$p3) { - $p3->resolve('Whoop'); - }); - $p2 = new Promise(function () use (&$p2, $p3) { - $p2->reject($p3); - }); - $p = new Promise(function () use (&$p, $p2) { - $p->reject($p2); - }); - $this->assertSame('Whoop', $p->wait()); - } - - public function testWaitsOnAPromiseChainEvenWhenNotUnwrapped() - { - $p2 = new Promise(function () use (&$p2) { - $p2->reject('Fail'); - }); - $p = new Promise(function () use ($p2, &$p) { - $p->resolve($p2); - }); - $p->wait(false); - $this->assertTrue(P\Is::rejected($p2)); - } - - public function testCannotCancelNonPending() - { - $p = new Promise(); - $p->resolve('foo'); - $p->cancel(); - $this->assertTrue(P\Is::fulfilled($p)); - } - - public function testCancelsPromiseWhenNoCancelFunction() - { - $this->expectException(\GuzzleHttp\Promise\CancellationException::class); - - $p = new Promise(); - $p->cancel(); - $this->assertTrue(P\Is::rejected($p)); - $p->wait(); - } - - public function testCancelsPromiseWithCancelFunction() - { - $called = false; - $p = new Promise(null, function () use (&$called) { - $called = true; - }); - $p->cancel(); - $this->assertTrue(P\Is::rejected($p)); - $this->assertTrue($called); - } - - public function testCancelsUppermostPendingPromise() - { - $called = false; - $p1 = new Promise(null, function () use (&$called) { - $called = true; - }); - $p2 = $p1->then(function () {}); - $p3 = $p2->then(function () {}); - $p4 = $p3->then(function () {}); - $p3->cancel(); - $this->assertTrue(P\Is::rejected($p1)); - $this->assertTrue(P\Is::rejected($p2)); - $this->assertTrue(P\Is::rejected($p3)); - $this->assertTrue(P\Is::pending($p4)); - $this->assertTrue($called); - - try { - $p3->wait(); - $this->fail(); - } catch (CancellationException $e) { - $this->assertStringContainsString('cancelled', $e->getMessage()); - } - - try { - $p4->wait(); - $this->fail(); - } catch (CancellationException $e) { - $this->assertStringContainsString('cancelled', $e->getMessage()); - } - - $this->assertTrue(P\Is::rejected($p4)); - } - - public function testCancelsChildPromises() - { - $called1 = $called2 = $called3 = false; - $p1 = new Promise(null, function () use (&$called1) { - $called1 = true; - }); - $p2 = new Promise(null, function () use (&$called2) { - $called2 = true; - }); - $p3 = new Promise(null, function () use (&$called3) { - $called3 = true; - }); - $p4 = $p2->then(function () use ($p3) { - return $p3; - }); - $p5 = $p4->then(function () { - $this->fail(); - }); - $p4->cancel(); - $this->assertTrue(P\Is::pending($p1)); - $this->assertTrue(P\Is::rejected($p2)); - $this->assertTrue(P\Is::pending($p3)); - $this->assertTrue(P\Is::rejected($p4)); - $this->assertTrue(P\Is::pending($p5)); - $this->assertFalse($called1); - $this->assertTrue($called2); - $this->assertFalse($called3); - } - - public function testRejectsPromiseWhenCancelFails() - { - $called = false; - $p = new Promise(null, function () use (&$called) { - $called = true; - throw new \Exception('e'); - }); - $p->cancel(); - $this->assertTrue(P\Is::rejected($p)); - $this->assertTrue($called); - try { - $p->wait(); - $this->fail(); - } catch (\Exception $e) { - $this->assertSame('e', $e->getMessage()); - } - } - - public function testCreatesPromiseWhenFulfilledAfterThen() - { - $p = new Promise(); - $carry = null; - $p2 = $p->then(function ($v) use (&$carry) { - $carry = $v; - }); - $this->assertNotSame($p, $p2); - $p->resolve('foo'); - P\Utils::queue()->run(); - - $this->assertSame('foo', $carry); - } - - public function testCreatesPromiseWhenFulfilledBeforeThen() - { - $p = new Promise(); - $p->resolve('foo'); - $carry = null; - $p2 = $p->then(function ($v) use (&$carry) { - $carry = $v; - }); - $this->assertNotSame($p, $p2); - $this->assertNull($carry); - P\Utils::queue()->run(); - $this->assertSame('foo', $carry); - } - - public function testCreatesPromiseWhenFulfilledWithNoCallback() - { - $p = new Promise(); - $p->resolve('foo'); - $p2 = $p->then(); - $this->assertNotSame($p, $p2); - $this->assertInstanceOf(FulfilledPromise::class, $p2); - } - - public function testCreatesPromiseWhenRejectedAfterThen() - { - $p = new Promise(); - $carry = null; - $p2 = $p->then(null, function ($v) use (&$carry) { - $carry = $v; - }); - $this->assertNotSame($p, $p2); - $p->reject('foo'); - P\Utils::queue()->run(); - $this->assertSame('foo', $carry); - } - - public function testCreatesPromiseWhenRejectedBeforeThen() - { - $p = new Promise(); - $p->reject('foo'); - $carry = null; - $p2 = $p->then(null, function ($v) use (&$carry) { - $carry = $v; - }); - $this->assertNotSame($p, $p2); - $this->assertNull($carry); - P\Utils::queue()->run(); - $this->assertSame('foo', $carry); - } - - public function testCreatesPromiseWhenRejectedWithNoCallback() - { - $p = new Promise(); - $p->reject('foo'); - $p2 = $p->then(); - $this->assertNotSame($p, $p2); - $this->assertInstanceOf(RejectedPromise::class, $p2); - } - - public function testInvokesWaitFnsForThens() - { - $p = new Promise(function () use (&$p) { - $p->resolve('a'); - }); - $p2 = $p - ->then(function ($v) { - return $v . '-1-'; - }) - ->then(function ($v) { - return $v . '2'; - }); - $this->assertSame('a-1-2', $p2->wait()); - } - - public function testStacksThenWaitFunctions() - { - $p1 = new Promise(function () use (&$p1) { - $p1->resolve('a'); - }); - $p2 = new Promise(function () use (&$p2) { - $p2->resolve('b'); - }); - $p3 = new Promise(function () use (&$p3) { - $p3->resolve('c'); - }); - $p4 = $p1 - ->then(function () use ($p2) { - return $p2; - }) - ->then(function () use ($p3) { - return $p3; - }); - $this->assertSame('c', $p4->wait()); - } - - public function testForwardsFulfilledDownChainBetweenGaps() - { - $p = new Promise(); - $r = $r2 = null; - $p->then(null, null) - ->then(function ($v) use (&$r) { - $r = $v; - return $v . '2'; - }) - ->then(function ($v) use (&$r2) { - $r2 = $v; - }); - $p->resolve('foo'); - P\Utils::queue()->run(); - $this->assertSame('foo', $r); - $this->assertSame('foo2', $r2); - } - - public function testForwardsRejectedPromisesDownChainBetweenGaps() - { - $p = new Promise(); - $r = $r2 = null; - $p->then(null, null) - ->then(null, function ($v) use (&$r) { - $r = $v; - return $v . '2'; - }) - ->then(function ($v) use (&$r2) { - $r2 = $v; - }); - $p->reject('foo'); - P\Utils::queue()->run(); - $this->assertSame('foo', $r); - $this->assertSame('foo2', $r2); - } - - public function testForwardsThrownPromisesDownChainBetweenGaps() - { - $e = new \Exception(); - $p = new Promise(); - $r = $r2 = null; - $p->then(null, null) - ->then(null, function ($v) use (&$r, $e) { - $r = $v; - throw $e; - }) - ->then( - null, - function ($v) use (&$r2) { - $r2 = $v; - } - ); - $p->reject('foo'); - P\Utils::queue()->run(); - $this->assertSame('foo', $r); - $this->assertSame($e, $r2); - } - - public function testForwardsReturnedRejectedPromisesDownChainBetweenGaps() - { - $p = new Promise(); - $rejected = new RejectedPromise('bar'); - $r = $r2 = null; - $p->then(null, null) - ->then(null, function ($v) use (&$r, $rejected) { - $r = $v; - return $rejected; - }) - ->then( - null, - function ($v) use (&$r2) { - $r2 = $v; - } - ); - $p->reject('foo'); - P\Utils::queue()->run(); - $this->assertSame('foo', $r); - $this->assertSame('bar', $r2); - try { - $p->wait(); - } catch (RejectionException $e) { - $this->assertSame('foo', $e->getReason()); - } - } - - public function testForwardsHandlersToNextPromise() - { - $p = new Promise(); - $p2 = new Promise(); - $resolved = null; - $p - ->then(function ($v) use ($p2) { - return $p2; - }) - ->then(function ($value) use (&$resolved) { - $resolved = $value; - }); - $p->resolve('a'); - $p2->resolve('b'); - P\Utils::queue()->run(); - $this->assertSame('b', $resolved); - } - - public function testRemovesReferenceFromChildWhenParentWaitedUpon() - { - $r = null; - $p = new Promise(function () use (&$p) { - $p->resolve('a'); - }); - $p2 = new Promise(function () use (&$p2) { - $p2->resolve('b'); - }); - $pb = $p->then( - function ($v) use ($p2, &$r) { - $r = $v; - return $p2; - } - ) - ->then(function ($v) { - return $v . '.'; - }); - $this->assertSame('a', $p->wait()); - $this->assertSame('b', $p2->wait()); - $this->assertSame('b.', $pb->wait()); - $this->assertSame('a', $r); - } - - public function testForwardsHandlersWhenFulfilledPromiseIsReturned() - { - $res = []; - $p = new Promise(); - $p2 = new Promise(); - $p2->resolve('foo'); - $p2->then(function ($v) use (&$res) { - $res[] = 'A:' . $v; - }); - // $res is A:foo - $p - ->then(function () use ($p2, &$res) { - $res[] = 'B'; - return $p2; - }) - ->then(function ($v) use (&$res) { - $res[] = 'C:' . $v; - }); - $p->resolve('a'); - $p->then(function ($v) use (&$res) { - $res[] = 'D:' . $v; - }); - P\Utils::queue()->run(); - $this->assertSame(['A:foo', 'B', 'D:a', 'C:foo'], $res); - } - - public function testForwardsHandlersWhenRejectedPromiseIsReturned() - { - $res = []; - $p = new Promise(); - $p2 = new Promise(); - $p2->reject('foo'); - $p2->then(null, function ($v) use (&$res) { - $res[] = 'A:' . $v; - }); - $p->then(null, function () use ($p2, &$res) { - $res[] = 'B'; - return $p2; - }) - ->then(null, function ($v) use (&$res) { - $res[] = 'C:' . $v; - }); - $p->reject('a'); - $p->then(null, function ($v) use (&$res) { - $res[] = 'D:' . $v; - }); - P\Utils::queue()->run(); - $this->assertSame(['A:foo', 'B', 'D:a', 'C:foo'], $res); - } - - public function testDoesNotForwardRejectedPromise() - { - $res = []; - $p = new Promise(); - $p2 = new Promise(); - $p2->cancel(); - $p2->then(function ($v) use (&$res) { - $res[] = "B:$v"; - return $v; - }); - $p->then(function ($v) use ($p2, &$res) { - $res[] = "B:$v"; - return $p2; - }) - ->then(function ($v) use (&$res) { - $res[] = 'C:' . $v; - }); - $p->resolve('a'); - $p->then(function ($v) use (&$res) { - $res[] = 'D:' . $v; - }); - P\Utils::queue()->run(); - $this->assertSame(['B:a', 'D:a'], $res); - } - - public function testRecursivelyForwardsWhenOnlyThennable() - { - $res = []; - $p = new Promise(); - $p2 = new Thennable(); - $p2->resolve('foo'); - $p2->then(function ($v) use (&$res) { - $res[] = 'A:' . $v; - }); - $p->then(function () use ($p2, &$res) { - $res[] = 'B'; - return $p2; - }) - ->then(function ($v) use (&$res) { - $res[] = 'C:' . $v; - }); - $p->resolve('a'); - $p->then(function ($v) use (&$res) { - $res[] = 'D:' . $v; - }); - P\Utils::queue()->run(); - $this->assertSame(['A:foo', 'B', 'D:a', 'C:foo'], $res); - } - - public function testRecursivelyForwardsWhenNotInstanceOfPromise() - { - $res = []; - $p = new Promise(); - $p2 = new NotPromiseInstance(); - $p2->then(function ($v) use (&$res) { - $res[] = 'A:' . $v; - }); - $p->then(function () use ($p2, &$res) { - $res[] = 'B'; - return $p2; - }) - ->then(function ($v) use (&$res) { - $res[] = 'C:' . $v; - }); - $p->resolve('a'); - $p->then(function ($v) use (&$res) { - $res[] = 'D:' . $v; - }); - P\Utils::queue()->run(); - $this->assertSame(['B', 'D:a'], $res); - $p2->resolve('foo'); - P\Utils::queue()->run(); - $this->assertSame(['B', 'D:a', 'A:foo', 'C:foo'], $res); - } - - public function testCannotResolveWithSelf() - { - $this->expectException(\LogicException::class); - $this->expectExceptionMessage('Cannot fulfill or reject a promise with itself'); - - $p = new Promise(); - $p->resolve($p); - } - - public function testCannotRejectWithSelf() - { - $this->expectException(\LogicException::class); - $this->expectExceptionMessage('Cannot fulfill or reject a promise with itself'); - - $p = new Promise(); - $p->reject($p); - } - - public function testDoesNotBlowStackWhenWaitingOnNestedThens() - { - $inner = new Promise(function () use (&$inner) { - $inner->resolve(0); - }); - $prev = $inner; - for ($i = 1; $i < 100; $i++) { - $prev = $prev->then(function ($i) { - return $i + 1; - }); - } - - $parent = new Promise(function () use (&$parent, $prev) { - $parent->resolve($prev); - }); - - $this->assertSame(99, $parent->wait()); - } - - public function testOtherwiseIsSugarForRejections() - { - $p = new Promise(); - $p->reject('foo'); - $p->otherwise(function ($v) use (&$c) { - $c = $v; - }); - P\Utils::queue()->run(); - $this->assertSame($c, 'foo'); - } - - public function testRepeatedWaitFulfilled() - { - $promise = new Promise(function () use (&$promise) { - $promise->resolve('foo'); - }); - - $this->assertSame('foo', $promise->wait()); - $this->assertSame('foo', $promise->wait()); - } - - public function testRepeatedWaitRejected() - { - $promise = new Promise(function () use (&$promise) { - $promise->reject(new \RuntimeException('foo')); - }); - - $exceptionCount = 0; - try { - $promise->wait(); - } catch (\Exception $e) { - $this->assertSame('foo', $e->getMessage()); - $exceptionCount++; - } - - try { - $promise->wait(); - } catch (\Exception $e) { - $this->assertSame('foo', $e->getMessage()); - $exceptionCount++; - } - - $this->assertSame(2, $exceptionCount); - } -} diff --git a/lib/Google/vendor/guzzlehttp/promises/tests/PropertyHelper.php b/lib/Google/vendor/guzzlehttp/promises/tests/PropertyHelper.php deleted file mode 100644 index d7757b09a..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/tests/PropertyHelper.php +++ /dev/null @@ -1,27 +0,0 @@ - - */ -class PropertyHelper -{ - /** - * @param object $object - * @param string $property - * - * @throws \ReflectionException - */ - public static function get($object, $property) - { - $property = (new \ReflectionObject($object))->getProperty($property); - $property->setAccessible(true); - - return $property->getValue($object); - } -} diff --git a/lib/Google/vendor/guzzlehttp/promises/tests/RejectedPromiseTest.php b/lib/Google/vendor/guzzlehttp/promises/tests/RejectedPromiseTest.php deleted file mode 100644 index 78b72cec1..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/tests/RejectedPromiseTest.php +++ /dev/null @@ -1,149 +0,0 @@ -assertTrue(P\Is::rejected($p)); - try { - $p->wait(true); - $this->fail(); - } catch (\Exception $e) { - $this->assertTrue(P\Is::rejected($p)); - $this->assertStringContainsString('foo', $e->getMessage()); - } - } - - public function testCannotCancel() - { - $p = new RejectedPromise('foo'); - $p->cancel(); - $this->assertTrue(P\Is::rejected($p)); - } - - /** - * @exepctedExceptionMessage Cannot resolve a rejected promise - */ - public function testCannotResolve() - { - $this->expectException(\LogicException::class); - - $p = new RejectedPromise('foo'); - $p->resolve('bar'); - } - - /** - * @expectedExceptionMessage Cannot reject a rejected promise - */ - public function testCannotReject() - { - $this->expectException(\LogicException::class); - - $p = new RejectedPromise('foo'); - $p->reject('bar'); - } - - public function testCanRejectWithSameValue() - { - $p = new RejectedPromise('foo'); - $p->reject('foo'); - $this->assertTrue(P\Is::rejected($p)); - } - - public function testThrowsSpecificException() - { - $e = new \Exception(); - $p = new RejectedPromise($e); - try { - $p->wait(true); - $this->fail(); - } catch (\Exception $e2) { - $this->assertSame($e, $e2); - } - } - - public function testCannotResolveWithPromise() - { - $this->expectException(\InvalidArgumentException::class); - - new RejectedPromise(new Promise()); - } - - public function testReturnsSelfWhenNoOnReject() - { - $p = new RejectedPromise('a'); - $this->assertSame($p, $p->then()); - } - - public function testInvokesOnRejectedAsynchronously() - { - $p = new RejectedPromise('a'); - $r = null; - $f = function ($reason) use (&$r) { $r = $reason; }; - $p->then(null, $f); - $this->assertNull($r); - P\Utils::queue()->run(); - $this->assertSame('a', $r); - } - - public function testReturnsNewRejectedWhenOnRejectedFails() - { - $p = new RejectedPromise('a'); - $f = function () { throw new \Exception('b'); }; - $p2 = $p->then(null, $f); - $this->assertNotSame($p, $p2); - try { - $p2->wait(); - $this->fail(); - } catch (\Exception $e) { - $this->assertSame('b', $e->getMessage()); - } - } - - public function testWaitingIsNoOp() - { - $p = new RejectedPromise('a'); - $p->wait(false); - $this->assertTrue(P\Is::rejected($p)); - } - - public function testOtherwiseIsSugarForRejections() - { - $p = new RejectedPromise('foo'); - $p->otherwise(function ($v) use (&$c) { $c = $v; }); - P\Utils::queue()->run(); - $this->assertSame('foo', $c); - } - - public function testCanResolveThenWithSuccess() - { - $actual = null; - $p = new RejectedPromise('foo'); - $p->otherwise(function ($v) { - return $v . ' bar'; - })->then(function ($v) use (&$actual) { - $actual = $v; - }); - P\Utils::queue()->run(); - $this->assertSame('foo bar', $actual); - } - - public function testDoesNotTryToRejectTwiceDuringTrampoline() - { - $fp = new RejectedPromise('a'); - $t1 = $fp->then(null, function ($v) { return $v . ' b'; }); - $t1->resolve('why!'); - $this->assertSame('why!', $t1->wait()); - } -} diff --git a/lib/Google/vendor/guzzlehttp/promises/tests/RejectionExceptionTest.php b/lib/Google/vendor/guzzlehttp/promises/tests/RejectionExceptionTest.php deleted file mode 100644 index 0d2e9730e..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/tests/RejectionExceptionTest.php +++ /dev/null @@ -1,28 +0,0 @@ -assertSame($thing, $e->getReason()); - $this->assertSame('The promise was rejected with reason: foo', $e->getMessage()); - } - - public function testCanGetReasonMessageFromJson() - { - $reason = new Thing2(); - $e = new RejectionException($reason); - $this->assertStringContainsString("{}", $e->getMessage()); - } -} diff --git a/lib/Google/vendor/guzzlehttp/promises/tests/TaskQueueTest.php b/lib/Google/vendor/guzzlehttp/promises/tests/TaskQueueTest.php deleted file mode 100644 index ad8be7722..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/tests/TaskQueueTest.php +++ /dev/null @@ -1,33 +0,0 @@ -assertTrue($tq->isEmpty()); - } - - public function testKnowsIfFull() - { - $tq = new TaskQueue(false); - $tq->add(function () {}); - $this->assertFalse($tq->isEmpty()); - } - - public function testExecutesTasksInOrder() - { - $tq = new TaskQueue(false); - $called = []; - $tq->add(function () use (&$called) { $called[] = 'a'; }); - $tq->add(function () use (&$called) { $called[] = 'b'; }); - $tq->add(function () use (&$called) { $called[] = 'c'; }); - $tq->run(); - $this->assertSame(['a', 'b', 'c'], $called); - } -} diff --git a/lib/Google/vendor/guzzlehttp/promises/tests/Thennable.php b/lib/Google/vendor/guzzlehttp/promises/tests/Thennable.php deleted file mode 100644 index d3f326521..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/tests/Thennable.php +++ /dev/null @@ -1,25 +0,0 @@ -nextPromise = new Promise(); - } - - public function then(callable $res = null, callable $rej = null) - { - return $this->nextPromise->then($res, $rej); - } - - public function resolve($value) - { - $this->nextPromise->resolve($value); - } -} diff --git a/lib/Google/vendor/guzzlehttp/promises/tests/Thing1.php b/lib/Google/vendor/guzzlehttp/promises/tests/Thing1.php deleted file mode 100644 index 6902cbd6c..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/tests/Thing1.php +++ /dev/null @@ -1,18 +0,0 @@ -message = $message; - } - - public function __toString() - { - return $this->message; - } -} diff --git a/lib/Google/vendor/guzzlehttp/promises/tests/Thing2.php b/lib/Google/vendor/guzzlehttp/promises/tests/Thing2.php deleted file mode 100644 index c762ea974..000000000 --- a/lib/Google/vendor/guzzlehttp/promises/tests/Thing2.php +++ /dev/null @@ -1,12 +0,0 @@ -resolve('a'); }); - $b = new Promise(function () use (&$b) { $b->reject('b'); }); - $c = new Promise(function () use (&$c, $e) { $c->reject($e); }); - $results = P\Utils::inspectAll([$a, $b, $c]); - $this->assertSame([ - ['state' => 'fulfilled', 'value' => 'a'], - ['state' => 'rejected', 'reason' => 'b'], - ['state' => 'rejected', 'reason' => $e] - ], $results); - } - - public function testUnwrapsPromisesWithNoDefaultAndFailure() - { - $this->expectException(\GuzzleHttp\Promise\RejectionException::class); - - $promises = [new FulfilledPromise('a'), new Promise()]; - P\Utils::unwrap($promises); - } - - public function testUnwrapsPromisesWithNoDefault() - { - $promises = [new FulfilledPromise('a')]; - $this->assertSame(['a'], P\Utils::unwrap($promises)); - } - - public function testUnwrapsPromisesWithKeys() - { - $promises = [ - 'foo' => new FulfilledPromise('a'), - 'bar' => new FulfilledPromise('b'), - ]; - $this->assertSame([ - 'foo' => 'a', - 'bar' => 'b' - ], P\Utils::unwrap($promises)); - } - - public function testAllAggregatesSortedArray() - { - $a = new Promise(); - $b = new Promise(); - $c = new Promise(); - $d = P\Utils::all([$a, $b, $c]); - $b->resolve('b'); - $a->resolve('a'); - $c->resolve('c'); - $d->then( - function ($value) use (&$result) { $result = $value; }, - function ($reason) use (&$result) { $result = $reason; } - ); - P\Utils::queue()->run(); - $this->assertSame(['a', 'b', 'c'], $result); - } - - public function testPromisesDynamicallyAddedToStack() - { - $promises = new \ArrayIterator(); - $counter = 0; - $promises['a'] = new FulfilledPromise('a'); - $promises['b'] = $promise = new Promise(function () use (&$promise, &$promises, &$counter) { - $counter++; // Make sure the wait function is called only once - $promise->resolve('b'); - $promises['c'] = $subPromise = new Promise(function () use (&$subPromise) { - $subPromise->resolve('c'); - }); - }); - $result = P\Utils::all($promises, true)->wait(); - $this->assertCount(3, $promises); - $this->assertCount(3, $result); - $this->assertSame($result['c'], 'c'); - $this->assertSame(1, $counter); - } - - public function testAllThrowsWhenAnyRejected() - { - $a = new Promise(); - $b = new Promise(); - $c = new Promise(); - $d = P\Utils::all([$a, $b, $c]); - $b->resolve('b'); - $a->reject('fail'); - $c->resolve('c'); - $d->then( - function ($value) use (&$result) { $result = $value; }, - function ($reason) use (&$result) { $result = $reason; } - ); - P\Utils::queue()->run(); - $this->assertSame('fail', $result); - } - - public function testSomeAggregatesSortedArrayWithMax() - { - $a = new Promise(); - $b = new Promise(); - $c = new Promise(); - $d = P\Utils::some(2, [$a, $b, $c]); - $b->resolve('b'); - $c->resolve('c'); - $a->resolve('a'); - $d->then(function ($value) use (&$result) { $result = $value; }); - P\Utils::queue()->run(); - $this->assertSame(['b', 'c'], $result); - } - - public function testSomeRejectsWhenTooManyRejections() - { - $a = new Promise(); - $b = new Promise(); - $d = P\Utils::some(2, [$a, $b]); - $a->reject('bad'); - $b->resolve('good'); - P\Utils::queue()->run(); - $this->assertTrue(P\Is::rejected($d)); - $d->then(null, function ($reason) use (&$called) { - $called = $reason; - }); - P\Utils::queue()->run(); - $this->assertInstanceOf(AggregateException::class, $called); - $this->assertContains('bad', $called->getReason()); - } - - public function testCanWaitUntilSomeCountIsSatisfied() - { - $a = new Promise(function () use (&$a) { $a->resolve('a'); }); - $b = new Promise(function () use (&$b) { $b->resolve('b'); }); - $c = new Promise(function () use (&$c) { $c->resolve('c'); }); - $d = P\Utils::some(2, [$a, $b, $c]); - $this->assertSame(['a', 'b'], $d->wait()); - } - - public function testThrowsIfImpossibleToWaitForSomeCount() - { - $this->expectException(\GuzzleHttp\Promise\AggregateException::class); - $this->expectExceptionMessage('Not enough promises to fulfill count'); - - $a = new Promise(function () use (&$a) { $a->resolve('a'); }); - $d = P\Utils::some(2, [$a]); - $d->wait(); - } - - public function testThrowsIfResolvedWithoutCountTotalResults() - { - $this->expectException(\GuzzleHttp\Promise\AggregateException::class); - $this->expectExceptionMessage('Not enough promises to fulfill count'); - - $a = new Promise(); - $b = new Promise(); - $d = P\Utils::some(3, [$a, $b]); - $a->resolve('a'); - $b->resolve('b'); - $d->wait(); - } - - public function testAnyReturnsFirstMatch() - { - $a = new Promise(); - $b = new Promise(); - $c = P\Utils::any([$a, $b]); - $b->resolve('b'); - $a->resolve('a'); - $c->then(function ($value) use (&$result) { $result = $value; }); - P\Utils::queue()->run(); - $this->assertSame('b', $result); - } - - public function testSettleFulfillsWithFulfilledAndRejected() - { - $a = new Promise(); - $b = new Promise(); - $c = new Promise(); - $d = P\Utils::settle([$a, $b, $c]); - $b->resolve('b'); - $c->resolve('c'); - $a->reject('a'); - P\Utils::queue()->run(); - $this->assertTrue(P\Is::fulfilled($d)); - $d->then(function ($value) use (&$result) { $result = $value; }); - P\Utils::queue()->run(); - $this->assertSame([ - ['state' => 'rejected', 'reason' => 'a'], - ['state' => 'fulfilled', 'value' => 'b'], - ['state' => 'fulfilled', 'value' => 'c'] - ], $result); - } - - public function testCanInspectFulfilledPromise() - { - $p = new FulfilledPromise('foo'); - $this->assertSame([ - 'state' => 'fulfilled', - 'value' => 'foo' - ], P\Utils::inspect($p)); - } - - public function testCanInspectRejectedPromise() - { - $p = new RejectedPromise('foo'); - $this->assertSame([ - 'state' => 'rejected', - 'reason' => 'foo' - ], P\Utils::inspect($p)); - } - - public function testCanInspectRejectedPromiseWithNormalException() - { - $e = new \Exception('foo'); - $p = new RejectedPromise($e); - $this->assertSame([ - 'state' => 'rejected', - 'reason' => $e - ], P\Utils::inspect($p)); - } - - public function testReturnsTrampoline() - { - $this->assertInstanceOf(TaskQueue::class, P\Utils::queue()); - $this->assertSame(P\Utils::queue(), P\Utils::queue()); - } - - public function testCanScheduleThunk() - { - $tramp = P\Utils::queue(); - $promise = P\Utils::task(function () { return 'Hi!'; }); - $c = null; - $promise->then(function ($v) use (&$c) { $c = $v; }); - $this->assertNull($c); - $tramp->run(); - $this->assertSame('Hi!', $c); - } - - public function testCanScheduleThunkWithRejection() - { - $tramp = P\Utils::queue(); - $promise = P\Utils::task(function () { throw new \Exception('Hi!'); }); - $c = null; - $promise->otherwise(function ($v) use (&$c) { $c = $v; }); - $this->assertNull($c); - $tramp->run(); - $this->assertSame('Hi!', $c->getMessage()); - } - - public function testCanScheduleThunkWithWait() - { - $tramp = P\Utils::queue(); - $promise = P\Utils::task(function () { return 'a'; }); - $this->assertSame('a', $promise->wait()); - $tramp->run(); - } - - public function testYieldsFromCoroutine() - { - if (defined('HHVM_VERSION')) { - $this->markTestIncomplete('Broken on HHVM.'); - } - - $promise = P\Coroutine::of(function () { - $value = (yield new FulfilledPromise('a')); - yield $value . 'b'; - }); - $promise->then(function ($value) use (&$result) { $result = $value; }); - P\Utils::queue()->run(); - $this->assertSame('ab', $result); - } - - public function testCanCatchExceptionsInCoroutine() - { - if (defined('HHVM_VERSION')) { - $this->markTestIncomplete('Broken on HHVM.'); - } - - $promise = P\Coroutine::of(function () { - try { - yield new RejectedPromise('a'); - $this->fail('Should have thrown into the coroutine!'); - } catch (RejectionException $e) { - $value = (yield new FulfilledPromise($e->getReason())); - yield $value . 'b'; - } - }); - $promise->then(function ($value) use (&$result) { $result = $value; }); - P\Utils::queue()->run(); - $this->assertTrue(P\Is::fulfilled($promise)); - $this->assertSame('ab', $result); - } - - /** - * @dataProvider rejectsParentExceptionProvider - */ - public function testRejectsParentExceptionWhenException(PromiseInterface $promise) - { - $promise->then( - function () { $this->fail(); }, - function ($reason) use (&$result) { $result = $reason; } - ); - P\Utils::queue()->run(); - $this->assertInstanceOf(\Exception::class, $result); - $this->assertSame('a', $result->getMessage()); - } - - public function rejectsParentExceptionProvider() - { - return [ - [P\Coroutine::of(function () { - yield new FulfilledPromise(0); - throw new \Exception('a'); - })], - [P\Coroutine::of(function () { - throw new \Exception('a'); - yield new FulfilledPromise(0); - })], - ]; - } - - public function testCanRejectFromRejectionCallback() - { - if (defined('HHVM_VERSION')) { - $this->markTestIncomplete('Broken on HHVM.'); - } - - $promise = P\Coroutine::of(function () { - yield new FulfilledPromise(0); - yield new RejectedPromise('no!'); - }); - $promise->then( - function () { $this->fail(); }, - function ($reason) use (&$result) { $result = $reason; } - ); - P\Utils::queue()->run(); - $this->assertInstanceOf(RejectionException::class, $result); - $this->assertSame('no!', $result->getReason()); - } - - public function testCanAsyncReject() - { - if (defined('HHVM_VERSION')) { - $this->markTestIncomplete('Broken on HHVM.'); - } - - $rej = new Promise(); - $promise = P\Coroutine::of(function () use ($rej) { - yield new FulfilledPromise(0); - yield $rej; - }); - $promise->then( - function () { $this->fail(); }, - function ($reason) use (&$result) { $result = $reason; } - ); - $rej->reject('no!'); - P\Utils::queue()->run(); - $this->assertInstanceOf(RejectionException::class, $result); - $this->assertSame('no!', $result->getReason()); - } - - public function testCanCatchAndThrowOtherException() - { - $promise = P\Coroutine::of(function () { - try { - yield new RejectedPromise('a'); - $this->fail('Should have thrown into the coroutine!'); - } catch (RejectionException $e) { - throw new \Exception('foo'); - } - }); - $promise->otherwise(function ($value) use (&$result) { $result = $value; }); - P\Utils::queue()->run(); - $this->assertTrue(P\Is::rejected($promise)); - $this->assertStringContainsString('foo', $result->getMessage()); - } - - public function testCanCatchAndYieldOtherException() - { - if (defined('HHVM_VERSION')) { - $this->markTestIncomplete('Broken on HHVM.'); - } - - $promise = P\Coroutine::of(function () { - try { - yield new RejectedPromise('a'); - $this->fail('Should have thrown into the coroutine!'); - } catch (RejectionException $e) { - yield new RejectedPromise('foo'); - } - }); - $promise->otherwise(function ($value) use (&$result) { $result = $value; }); - P\Utils::queue()->run(); - $this->assertTrue(P\Is::rejected($promise)); - $this->assertStringContainsString('foo', $result->getMessage()); - } - - public function createLotsOfSynchronousPromise() - { - return P\Coroutine::of(function () { - $value = 0; - for ($i = 0; $i < 1000; $i++) { - $value = (yield new FulfilledPromise($i)); - } - yield $value; - }); - } - - public function testLotsOfSynchronousDoesNotBlowStack() - { - if (defined('HHVM_VERSION')) { - $this->markTestIncomplete('Broken on HHVM.'); - } - - $promise = $this->createLotsOfSynchronousPromise(); - $promise->then(function ($v) use (&$r) { $r = $v; }); - P\Utils::queue()->run(); - $this->assertSame(999, $r); - } - - public function testLotsOfSynchronousWaitDoesNotBlowStack() - { - if (defined('HHVM_VERSION')) { - $this->markTestIncomplete('Broken on HHVM.'); - } - - $promise = $this->createLotsOfSynchronousPromise(); - $promise->then(function ($v) use (&$r) { $r = $v; }); - $this->assertSame(999, $promise->wait()); - $this->assertSame(999, $r); - } - - private function createLotsOfFlappingPromise() - { - return P\Coroutine::of(function () { - $value = 0; - for ($i = 0; $i < 1000; $i++) { - try { - if ($i % 2) { - $value = (yield new FulfilledPromise($i)); - } else { - $value = (yield new RejectedPromise($i)); - } - } catch (\Exception $e) { - $value = (yield new FulfilledPromise($i)); - } - } - yield $value; - }); - } - - public function testLotsOfTryCatchingDoesNotBlowStack() - { - if (defined('HHVM_VERSION')) { - $this->markTestIncomplete('Broken on HHVM.'); - } - - $promise = $this->createLotsOfFlappingPromise(); - $promise->then(function ($v) use (&$r) { $r = $v; }); - P\Utils::queue()->run(); - $this->assertSame(999, $r); - } - - public function testLotsOfTryCatchingWaitingDoesNotBlowStack() - { - if (defined('HHVM_VERSION')) { - $this->markTestIncomplete('Broken on HHVM.'); - } - - $promise = $this->createLotsOfFlappingPromise(); - $promise->then(function ($v) use (&$r) { $r = $v; }); - $this->assertSame(999, $promise->wait()); - $this->assertSame(999, $r); - } - - public function testAsyncPromisesWithCorrectlyYieldedValues() - { - if (defined('HHVM_VERSION')) { - $this->markTestIncomplete('Broken on HHVM.'); - } - - $promises = [ - new Promise(), - new Promise(), - new Promise(), - ]; - - eval(' - $promise = \GuzzleHttp\Promise\Coroutine::of(function () use ($promises) { - $value = null; - $this->assertSame(\'skip\', (yield new \GuzzleHttp\Promise\FulfilledPromise(\'skip\'))); - foreach ($promises as $idx => $p) { - $value = (yield $p); - $this->assertSame($idx, $value); - $this->assertSame(\'skip\', (yield new \GuzzleHttp\Promise\FulfilledPromise(\'skip\'))); - } - $this->assertSame(\'skip\', (yield new \GuzzleHttp\Promise\FulfilledPromise(\'skip\'))); - yield $value; - }); -'); - - $promises[0]->resolve(0); - $promises[1]->resolve(1); - $promises[2]->resolve(2); - - $promise->then(function ($v) use (&$r) { $r = $v; }); - P\Utils::queue()->run(); - $this->assertSame(2, $r); - } - - public function testYieldFinalWaitablePromise() - { - if (defined('HHVM_VERSION')) { - $this->markTestIncomplete('Broken on HHVM.'); - } - - $p1 = new Promise(function () use (&$p1) { - $p1->resolve('skip me'); - }); - $p2 = new Promise(function () use (&$p2) { - $p2->resolve('hello!'); - }); - $co = P\Coroutine::of(function () use ($p1, $p2) { - yield $p1; - yield $p2; - }); - P\Utils::queue()->run(); - $this->assertSame('hello!', $co->wait()); - } - - public function testCanYieldFinalPendingPromise() - { - if (defined('HHVM_VERSION')) { - $this->markTestIncomplete('Broken on HHVM.'); - } - - $p1 = new Promise(); - $p2 = new Promise(); - $co = P\Coroutine::of(function () use ($p1, $p2) { - yield $p1; - yield $p2; - }); - $p1->resolve('a'); - $p2->resolve('b'); - $co->then(function ($value) use (&$result) { $result = $value; }); - P\Utils::queue()->run(); - $this->assertSame('b', $result); - } - - public function testCanNestYieldsAndFailures() - { - if (defined('HHVM_VERSION')) { - $this->markTestIncomplete('Broken on HHVM.'); - } - - $p1 = new Promise(); - $p2 = new Promise(); - $p3 = new Promise(); - $p4 = new Promise(); - $p5 = new Promise(); - $co = P\Coroutine::of(function () use ($p1, $p2, $p3, $p4, $p5) { - try { - yield $p1; - } catch (\Exception $e) { - yield $p2; - try { - yield $p3; - yield $p4; - } catch (\Exception $e) { - yield $p5; - } - } - }); - $p1->reject('a'); - $p2->resolve('b'); - $p3->resolve('c'); - $p4->reject('d'); - $p5->resolve('e'); - $co->then(function ($value) use (&$result) { $result = $value; }); - P\Utils::queue()->run(); - $this->assertSame('e', $result); - } - - public function testCanYieldErrorsAndSuccessesWithoutRecursion() - { - if (defined('HHVM_VERSION')) { - $this->markTestIncomplete('Broken on HHVM.'); - } - - $promises = []; - for ($i = 0; $i < 20; $i++) { - $promises[] = new Promise(); - } - - $co = P\Coroutine::of(function () use ($promises) { - for ($i = 0; $i < 20; $i += 4) { - try { - yield $promises[$i]; - yield $promises[$i + 1]; - } catch (\Exception $e) { - yield $promises[$i + 2]; - yield $promises[$i + 3]; - } - } - }); - - for ($i = 0; $i < 20; $i += 4) { - $promises[$i]->resolve($i); - $promises[$i + 1]->reject($i + 1); - $promises[$i + 2]->resolve($i + 2); - $promises[$i + 3]->resolve($i + 3); - } - - $co->then(function ($value) use (&$result) { $result = $value; }); - P\Utils::queue()->run(); - $this->assertSame(19, $result); - } - - public function testCanWaitOnPromiseAfterFulfilled() - { - if (defined('HHVM_VERSION')) { - $this->markTestIncomplete('Broken on HHVM.'); - } - - $f = function () { - static $i = 0; - $i++; - return $p = new Promise(function () use (&$p, $i) { - $p->resolve($i . '-bar'); - }); - }; - - $promises = []; - for ($i = 0; $i < 20; $i++) { - $promises[] = $f(); - } - - $p = P\Coroutine::of(function () use ($promises) { - yield new FulfilledPromise('foo!'); - foreach ($promises as $promise) { - yield $promise; - } - }); - - $this->assertSame('20-bar', $p->wait()); - } - - public function testCanWaitOnErroredPromises() - { - if (defined('HHVM_VERSION')) { - $this->markTestIncomplete('Broken on HHVM.'); - } - - $p1 = new Promise(function () use (&$p1) { $p1->reject('a'); }); - $p2 = new Promise(function () use (&$p2) { $p2->resolve('b'); }); - $p3 = new Promise(function () use (&$p3) { $p3->resolve('c'); }); - $p4 = new Promise(function () use (&$p4) { $p4->reject('d'); }); - $p5 = new Promise(function () use (&$p5) { $p5->resolve('e'); }); - $p6 = new Promise(function () use (&$p6) { $p6->reject('f'); }); - - $co = P\Coroutine::of(function () use ($p1, $p2, $p3, $p4, $p5, $p6) { - try { - yield $p1; - } catch (\Exception $e) { - yield $p2; - try { - yield $p3; - yield $p4; - } catch (\Exception $e) { - yield $p5; - yield $p6; - } - } - }); - - $res = P\Utils::inspect($co); - $this->assertSame('f', $res['reason']); - } - - public function testCoroutineOtherwiseIntegrationTest() - { - if (defined('HHVM_VERSION')) { - $this->markTestIncomplete('Broken on HHVM.'); - } - - $a = new Promise(); - $b = new Promise(); - $promise = P\Coroutine::of(function () use ($a, $b) { - // Execute the pool of commands concurrently, and process errors. - yield $a; - yield $b; - })->otherwise(function (\Exception $e) { - // Throw errors from the operations as a specific Multipart error. - throw new \OutOfBoundsException('a', 0, $e); - }); - $a->resolve('a'); - $b->reject('b'); - $reason = P\Utils::inspect($promise)['reason']; - $this->assertInstanceOf(\OutOfBoundsException::class, $reason); - $this->assertInstanceOf(RejectionException::class, $reason->getPrevious()); - } - - public function testCanManuallySettleTaskQueueGeneratedPromises() - { - $p1 = P\Utils::task(function () { return 'a'; }); - $p2 = P\Utils::task(function () { return 'b'; }); - $p3 = P\Utils::task(function () { return 'c'; }); - - $p1->cancel(); - $p2->resolve('b2'); - - $results = P\Utils::inspectAll([$p1, $p2, $p3]); - - $this->assertSame([ - ['state' => 'rejected', 'reason' => 'Promise has been cancelled'], - ['state' => 'fulfilled', 'value' => 'b2'], - ['state' => 'fulfilled', 'value' => 'c'] - ], $results); - } -} diff --git a/lib/Google/vendor/guzzlehttp/psr7/CHANGELOG.md b/lib/Google/vendor/guzzlehttp/psr7/CHANGELOG.md index fa716c094..fe3eda70a 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/CHANGELOG.md +++ b/lib/Google/vendor/guzzlehttp/psr7/CHANGELOG.md @@ -5,7 +5,39 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.6.2 - 2023-12-03 + +### Fixed + +- Fixed another issue with the fact that PHP transforms numeric strings in array keys to ints + +### Changed + +- Updated links in docs to their canonical versions +- Replaced `call_user_func*` with native calls + +## 2.6.1 - 2023-08-27 + +### Fixed + +- Properly handle the fact that PHP transforms numeric strings in array keys to ints + +## 2.6.0 - 2023-08-03 + +### Changed + +- Updated the mime type map to add some new entries, fix a couple of invalid entries, and remove an invalid entry +- Fallback to `application/octet-stream` if we are unable to guess the content type for a multipart file upload + +## 2.5.1 - 2023-08-03 + +### Fixed + +- Corrected mime type for `.acc` files to `audio/aac` + +### Changed + +- PHP 8.3 support ## 2.5.0 - 2023-04-17 diff --git a/lib/Google/vendor/guzzlehttp/psr7/README.md b/lib/Google/vendor/guzzlehttp/psr7/README.md index 9566a7d47..850fa9d70 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/README.md +++ b/lib/Google/vendor/guzzlehttp/psr7/README.md @@ -8,16 +8,24 @@ functionality like query string parsing. ![Static analysis](https://github.com/guzzle/psr7/workflows/Static%20analysis/badge.svg) -# Installation +## Features + +This package comes with a number of stream implementations and stream +decorators. + + +## Installation ```shell composer require guzzlehttp/psr7 ``` -# Stream implementation +## Version Guidance -This package comes with a number of stream implementations and stream -decorators. +| Version | Status | PHP Version | +|---------|---------------------|--------------| +| 1.x | Security fixes only | >=5.4,<8.1 | +| 2.x | Latest | >=7.2.5,<8.4 | ## AppendStream @@ -265,7 +273,7 @@ class EofCallbackStream implements StreamInterface // Invoke the callback when EOF is hit. if ($this->eof()) { - call_user_func($this->callback); + ($this->callback)(); } return $result; @@ -629,7 +637,7 @@ this library also provides additional functionality when working with URIs as st An instance of `Psr\Http\Message\UriInterface` can either be an absolute URI or a relative reference. An absolute URI has a scheme. A relative reference is used to express a URI relative to another URI, the base URI. Relative references can be divided into several forms according to -[RFC 3986 Section 4.2](https://tools.ietf.org/html/rfc3986#section-4.2): +[RFC 3986 Section 4.2](https://datatracker.ietf.org/doc/html/rfc3986#section-4.2): - network-path references, e.g. `//example.com/path` - absolute-path references, e.g. `/path` @@ -688,8 +696,8 @@ or the standard port. This method can be used independently of the implementatio `public static function composeComponents($scheme, $authority, $path, $query, $fragment): string` Composes a URI reference string from its various components according to -[RFC 3986 Section 5.3](https://tools.ietf.org/html/rfc3986#section-5.3). Usually this method does not need to be called -manually but instead is used indirectly via `Psr\Http\Message\UriInterface::__toString`. +[RFC 3986 Section 5.3](https://datatracker.ietf.org/doc/html/rfc3986#section-5.3). Usually this method does not need +to be called manually but instead is used indirectly via `Psr\Http\Message\UriInterface::__toString`. ### `GuzzleHttp\Psr7\Uri::fromParts` @@ -733,8 +741,8 @@ Determines if a modified URL should be considered cross-origin with respect to a ## Reference Resolution `GuzzleHttp\Psr7\UriResolver` provides methods to resolve a URI reference in the context of a base URI according -to [RFC 3986 Section 5](https://tools.ietf.org/html/rfc3986#section-5). This is for example also what web browsers -do when resolving a link in a website based on the current request URI. +to [RFC 3986 Section 5](https://datatracker.ietf.org/doc/html/rfc3986#section-5). This is for example also what web +browsers do when resolving a link in a website based on the current request URI. ### `GuzzleHttp\Psr7\UriResolver::resolve` @@ -747,7 +755,7 @@ Converts the relative URI into a new URI that is resolved against the base URI. `public static function removeDotSegments(string $path): string` Removes dot segments from a path and returns the new path according to -[RFC 3986 Section 5.2.4](https://tools.ietf.org/html/rfc3986#section-5.2.4). +[RFC 3986 Section 5.2.4](https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.4). ### `GuzzleHttp\Psr7\UriResolver::relativize` @@ -773,7 +781,7 @@ echo UriResolver::relativize($base, new Uri('http://example.org/a/b/')); // pr ## Normalization and Comparison `GuzzleHttp\Psr7\UriNormalizer` provides methods to normalize and compare URIs according to -[RFC 3986 Section 6](https://tools.ietf.org/html/rfc3986#section-6). +[RFC 3986 Section 6](https://datatracker.ietf.org/doc/html/rfc3986#section-6). ### `GuzzleHttp\Psr7\UriNormalizer::normalize` @@ -855,14 +863,6 @@ This of course assumes they will be resolved against the same base URI. If this equivalence or difference of relative references does not mean anything. -## Version Guidance - -| Version | Status | PHP Version | -|---------|----------------|------------------| -| 1.x | Security fixes | >=5.4,<8.1 | -| 2.x | Latest | ^7.2.5 \|\| ^8.0 | - - ## Security If you discover a security vulnerability within this package, please send an email to security@tidelift.com. All security vulnerabilities will be promptly addressed. Please do not disclose security-related issues publicly until a fix has been announced. Please see [Security Policy](https://github.com/guzzle/psr7/security/policy) for more information. diff --git a/lib/Google/vendor/guzzlehttp/psr7/composer.json b/lib/Google/vendor/guzzlehttp/psr7/composer.json index d51dd622e..70293fc40 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/composer.json +++ b/lib/Google/vendor/guzzlehttp/psr7/composer.json @@ -60,9 +60,9 @@ "psr/http-message-implementation": "1.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.1", + "bamarni/composer-bin-plugin": "^1.8.2", "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.29 || ^9.5.23" + "phpunit/phpunit": "^8.5.36 || ^9.6.15" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/AppendStream.php b/lib/Google/vendor/guzzlehttp/psr7/src/AppendStream.php index cbcfaee65..ee8f37882 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/AppendStream.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/AppendStream.php @@ -40,12 +40,14 @@ public function __toString(): string { try { $this->rewind(); + return $this->getContents(); } catch (\Throwable $e) { if (\PHP_VERSION_ID >= 70400) { throw $e; } trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR); + return ''; } } @@ -138,9 +140,9 @@ public function getSize(): ?int public function eof(): bool { - return !$this->streams || - ($this->current >= count($this->streams) - 1 && - $this->streams[$this->current]->eof()); + return !$this->streams + || ($this->current >= count($this->streams) - 1 + && $this->streams[$this->current]->eof()); } public function rewind(): void @@ -167,7 +169,7 @@ public function seek($offset, $whence = SEEK_SET): void $stream->rewind(); } catch (\Exception $e) { throw new \RuntimeException('Unable to seek stream ' - . $i . ' of the AppendStream', 0, $e); + .$i.' of the AppendStream', 0, $e); } } @@ -197,7 +199,7 @@ public function read($length): string if ($this->current === $total) { break; } - $this->current++; + ++$this->current; } $result = $this->streams[$this->current]->read($remaining); @@ -237,8 +239,6 @@ public function write($string): int } /** - * {@inheritdoc} - * * @return mixed */ public function getMetadata($key = null) diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/BufferStream.php b/lib/Google/vendor/guzzlehttp/psr7/src/BufferStream.php index 21be8c0a9..2b0eb77be 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/BufferStream.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/BufferStream.php @@ -134,8 +134,6 @@ public function write($string): int } /** - * {@inheritdoc} - * * @return mixed */ public function getMetadata($key = null) diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/FnStream.php b/lib/Google/vendor/guzzlehttp/psr7/src/FnStream.php index 3a1a9512e..9e6a7f31a 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/FnStream.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/FnStream.php @@ -18,7 +18,7 @@ final class FnStream implements StreamInterface private const SLOTS = [ '__toString', 'close', 'detach', 'rewind', 'getSize', 'tell', 'eof', 'isSeekable', 'seek', 'isWritable', 'write', - 'isReadable', 'read', 'getContents', 'getMetadata' + 'isReadable', 'read', 'getContents', 'getMetadata', ]; /** @var array */ @@ -33,7 +33,7 @@ public function __construct(array $methods) // Create the functions on the class foreach ($methods as $name => $fn) { - $this->{'_fn_' . $name} = $fn; + $this->{'_fn_'.$name} = $fn; } } @@ -45,7 +45,7 @@ public function __construct(array $methods) public function __get(string $name): void { throw new \BadMethodCallException(str_replace('_fn_', '', $name) - . '() is not implemented in the FnStream'); + .'() is not implemented in the FnStream'); } /** @@ -54,7 +54,7 @@ public function __get(string $name): void public function __destruct() { if (isset($this->_fn_close)) { - call_user_func($this->_fn_close); + ($this->_fn_close)(); } } @@ -93,88 +93,88 @@ public static function decorate(StreamInterface $stream, array $methods) public function __toString(): string { try { - return call_user_func($this->_fn___toString); + /** @var string */ + return ($this->_fn___toString)(); } catch (\Throwable $e) { if (\PHP_VERSION_ID >= 70400) { throw $e; } trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR); + return ''; } } public function close(): void { - call_user_func($this->_fn_close); + ($this->_fn_close)(); } public function detach() { - return call_user_func($this->_fn_detach); + return ($this->_fn_detach)(); } public function getSize(): ?int { - return call_user_func($this->_fn_getSize); + return ($this->_fn_getSize)(); } public function tell(): int { - return call_user_func($this->_fn_tell); + return ($this->_fn_tell)(); } public function eof(): bool { - return call_user_func($this->_fn_eof); + return ($this->_fn_eof)(); } public function isSeekable(): bool { - return call_user_func($this->_fn_isSeekable); + return ($this->_fn_isSeekable)(); } public function rewind(): void { - call_user_func($this->_fn_rewind); + ($this->_fn_rewind)(); } public function seek($offset, $whence = SEEK_SET): void { - call_user_func($this->_fn_seek, $offset, $whence); + ($this->_fn_seek)($offset, $whence); } public function isWritable(): bool { - return call_user_func($this->_fn_isWritable); + return ($this->_fn_isWritable)(); } public function write($string): int { - return call_user_func($this->_fn_write, $string); + return ($this->_fn_write)($string); } public function isReadable(): bool { - return call_user_func($this->_fn_isReadable); + return ($this->_fn_isReadable)(); } public function read($length): string { - return call_user_func($this->_fn_read, $length); + return ($this->_fn_read)($length); } public function getContents(): string { - return call_user_func($this->_fn_getContents); + return ($this->_fn_getContents)(); } /** - * {@inheritdoc} - * * @return mixed */ public function getMetadata($key = null) { - return call_user_func($this->_fn_getMetadata, $key); + return ($this->_fn_getMetadata)($key); } } diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/Header.php b/lib/Google/vendor/guzzlehttp/psr7/src/Header.php index 4d7005b22..bbce8b03d 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/Header.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/Header.php @@ -22,7 +22,7 @@ public static function parse($header): array foreach ((array) $header as $value) { foreach (self::splitList($value) as $val) { $part = []; - foreach (preg_split('/;(?=([^"]*"[^"]*")*[^"]*$)/', $val) as $kvp) { + foreach (preg_split('/;(?=([^"]*"[^"]*")*[^"]*$)/', $val) ?: [] as $kvp) { if (preg_match_all('/<[^>]+>|[^=]+/', $kvp, $matches)) { $m = $matches[0]; if (isset($m[1])) { @@ -89,7 +89,7 @@ public static function splitList($values): array $v = ''; $isQuoted = false; $isEscaped = false; - for ($i = 0, $max = \strlen($value); $i < $max; $i++) { + for ($i = 0, $max = \strlen($value); $i < $max; ++$i) { if ($isEscaped) { $v .= $value[$i]; $isEscaped = false; diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/HttpFactory.php b/lib/Google/vendor/guzzlehttp/psr7/src/HttpFactory.php index 30be222fc..73d17e337 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/HttpFactory.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/HttpFactory.php @@ -23,13 +23,7 @@ * Note: in consuming code it is recommended to require the implemented interfaces * and inject the instance of this class multiple times. */ -final class HttpFactory implements - RequestFactoryInterface, - ResponseFactoryInterface, - ServerRequestFactoryInterface, - StreamFactoryInterface, - UploadedFileFactoryInterface, - UriFactoryInterface +final class HttpFactory implements RequestFactoryInterface, ResponseFactoryInterface, ServerRequestFactoryInterface, StreamFactoryInterface, UploadedFileFactoryInterface, UriFactoryInterface { public function createUploadedFile( StreamInterface $stream, diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/InflateStream.php b/lib/Google/vendor/guzzlehttp/psr7/src/InflateStream.php index 8e00f1c32..e674c9ab6 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/InflateStream.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/InflateStream.php @@ -13,9 +13,9 @@ * then appends the zlib.inflate filter. The stream is then converted back * to a Guzzle stream resource to be used as a Guzzle stream. * - * @link http://tools.ietf.org/html/rfc1950 - * @link http://tools.ietf.org/html/rfc1952 - * @link http://php.net/manual/en/filters.compression.php + * @see https://datatracker.ietf.org/doc/html/rfc1950 + * @see https://datatracker.ietf.org/doc/html/rfc1952 + * @see https://www.php.net/manual/en/filters.compression.php */ final class InflateStream implements StreamInterface { @@ -28,7 +28,7 @@ public function __construct(StreamInterface $stream) { $resource = StreamWrapper::getResource($stream); // Specify window=15+32, so zlib will use header detection to both gzip (with header) and zlib data - // See http://www.zlib.net/manual.html#Advanced definition of inflateInit2 + // See https://www.zlib.net/manual.html#Advanced definition of inflateInit2 // "Add 32 to windowBits to enable zlib and gzip decoding with automatic header detection" // Default window size is 15. stream_filter_append($resource, 'zlib.inflate', STREAM_FILTER_READ, ['window' => 15 + 32]); diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/Message.php b/lib/Google/vendor/guzzlehttp/psr7/src/Message.php index c1e15f826..5561a5130 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/Message.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/Message.php @@ -18,31 +18,31 @@ final class Message public static function toString(MessageInterface $message): string { if ($message instanceof RequestInterface) { - $msg = trim($message->getMethod() . ' ' - . $message->getRequestTarget()) - . ' HTTP/' . $message->getProtocolVersion(); + $msg = trim($message->getMethod().' ' + .$message->getRequestTarget()) + .' HTTP/'.$message->getProtocolVersion(); if (!$message->hasHeader('host')) { - $msg .= "\r\nHost: " . $message->getUri()->getHost(); + $msg .= "\r\nHost: ".$message->getUri()->getHost(); } } elseif ($message instanceof ResponseInterface) { - $msg = 'HTTP/' . $message->getProtocolVersion() . ' ' - . $message->getStatusCode() . ' ' - . $message->getReasonPhrase(); + $msg = 'HTTP/'.$message->getProtocolVersion().' ' + .$message->getStatusCode().' ' + .$message->getReasonPhrase(); } else { throw new \InvalidArgumentException('Unknown message type'); } foreach ($message->getHeaders() as $name => $values) { - if (strtolower($name) === 'set-cookie') { + if (is_string($name) && strtolower($name) === 'set-cookie') { foreach ($values as $value) { - $msg .= "\r\n{$name}: " . $value; + $msg .= "\r\n{$name}: ".$value; } } else { - $msg .= "\r\n{$name}: " . implode(', ', $values); + $msg .= "\r\n{$name}: ".implode(', ', $values); } } - return "{$msg}\r\n\r\n" . $message->getBody(); + return "{$msg}\r\n\r\n".$message->getBody(); } /** @@ -146,7 +146,7 @@ public static function parseMessage(string $message): array // If these aren't the same, then one line didn't match and there's an invalid header. if ($count !== substr_count($rawHeaders, "\n")) { - // Folding is deprecated, see https://tools.ietf.org/html/rfc7230#section-3.2.4 + // Folding is deprecated, see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.4 if (preg_match(Rfc7230::HEADER_FOLD_REGEX, $rawHeaders)) { throw new \InvalidArgumentException('Invalid header syntax: Obsolete line folding'); } @@ -190,7 +190,7 @@ public static function parseRequestUri(string $path, array $headers): string $host = $headers[reset($hostKey)][0]; $scheme = substr($host, -4) === ':443' ? 'https' : 'http'; - return $scheme . '://' . $host . '/' . ltrim($path, '/'); + return $scheme.'://'.$host.'/'.ltrim($path, '/'); } /** @@ -227,11 +227,11 @@ public static function parseRequest(string $message): RequestInterface public static function parseResponse(string $message): ResponseInterface { $data = self::parseMessage($message); - // According to https://tools.ietf.org/html/rfc7230#section-3.1.2 the space - // between status-code and reason-phrase is required. But browsers accept - // responses without space and reason as well. + // According to https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2 + // the space between status-code and reason-phrase is required. But + // browsers accept responses without space and reason as well. if (!preg_match('/^HTTP\/.* [0-9]{3}( .*|$)/', $data['start-line'])) { - throw new \InvalidArgumentException('Invalid response string: ' . $data['start-line']); + throw new \InvalidArgumentException('Invalid response string: '.$data['start-line']); } $parts = explode(' ', $data['start-line'], 3); diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/MessageTrait.php b/lib/Google/vendor/guzzlehttp/psr7/src/MessageTrait.php index 464bdfaa4..65dbc4ba0 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/MessageTrait.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/MessageTrait.php @@ -12,11 +12,11 @@ */ trait MessageTrait { - /** @var array Map of all registered headers, as original name => array of values */ + /** @var string[][] Map of all registered headers, as original name => array of values */ private $headers = []; - /** @var array Map of lowercase header name => original name at registration */ - private $headerNames = []; + /** @var string[] Map of lowercase header name => original name at registration */ + private $headerNames = []; /** @var string */ private $protocol = '1.1'; @@ -37,6 +37,7 @@ public function withProtocolVersion($version): MessageInterface $new = clone $this; $new->protocol = $version; + return $new; } @@ -135,11 +136,12 @@ public function withBody(StreamInterface $body): MessageInterface $new = clone $this; $new->stream = $body; + return $new; } /** - * @param array $headers + * @param (string|string[])[] $headers */ private function setHeaders(array $headers): void { @@ -191,7 +193,7 @@ private function normalizeHeaderValue($value): array * * @return string[] Trimmed header values * - * @see https://tools.ietf.org/html/rfc7230#section-3.2.4 + * @see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.4 */ private function trimAndValidateHeaderValues(array $values): array { @@ -211,7 +213,7 @@ private function trimAndValidateHeaderValues(array $values): array } /** - * @see https://tools.ietf.org/html/rfc7230#section-3.2 + * @see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2 * * @param mixed $header */ @@ -224,7 +226,7 @@ private function assertHeader($header): void )); } - if (! preg_match('/^[a-zA-Z0-9\'`#$%&*+.^_|~!-]+$/D', $header)) { + if (!preg_match('/^[a-zA-Z0-9\'`#$%&*+.^_|~!-]+$/D', $header)) { throw new \InvalidArgumentException( sprintf('"%s" is not valid header name.', $header) ); @@ -232,7 +234,7 @@ private function assertHeader($header): void } /** - * @see https://tools.ietf.org/html/rfc7230#section-3.2 + * @see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2 * * field-value = *( field-content / obs-fold ) * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] @@ -254,7 +256,7 @@ private function assertValue(string $value): void // Clients must not send a request with line folding and a server sending folded headers is // likely very rare. Line folding is a fairly obscure feature of HTTP/1.1 and thus not accepting // folding is not likely to break any legitimate use case. - if (! preg_match('/^[\x20\x09\x21-\x7E\x80-\xFF]*$/D', $value)) { + if (!preg_match('/^[\x20\x09\x21-\x7E\x80-\xFF]*$/D', $value)) { throw new \InvalidArgumentException( sprintf('"%s" is not valid header value.', $value) ); diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/MimeType.php b/lib/Google/vendor/guzzlehttp/psr7/src/MimeType.php index 0debbd18c..b131bdbe7 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/MimeType.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/MimeType.php @@ -18,7 +18,7 @@ final class MimeType '7zip' => 'application/x-7z-compressed', '123' => 'application/vnd.lotus-1-2-3', 'aab' => 'application/x-authorware-bin', - 'aac' => 'audio/x-acc', + 'aac' => 'audio/aac', 'aam' => 'application/x-authorware-map', 'aas' => 'application/x-authorware-seg', 'abw' => 'application/x-abiword', @@ -29,6 +29,7 @@ final class MimeType 'acu' => 'application/vnd.acucobol', 'acutc' => 'application/vnd.acucorp', 'adp' => 'audio/adpcm', + 'adts' => 'audio/aac', 'aep' => 'application/vnd.audiograph', 'afm' => 'application/x-font-type1', 'afp' => 'application/vnd.ibm.modcap', @@ -41,11 +42,16 @@ final class MimeType 'air' => 'application/vnd.adobe.air-application-installer-package+zip', 'ait' => 'application/vnd.dvb.ait', 'ami' => 'application/vnd.amiga.ami', + 'aml' => 'application/automationml-aml+xml', + 'amlx' => 'application/automationml-amlx+zip', 'amr' => 'audio/amr', 'apk' => 'application/vnd.android.package-archive', 'apng' => 'image/apng', 'appcache' => 'text/cache-manifest', + 'appinstaller' => 'application/appinstaller', 'application' => 'application/x-ms-application', + 'appx' => 'application/appx', + 'appxbundle' => 'application/appxbundle', 'apr' => 'application/vnd.lotus-approach', 'arc' => 'application/x-freearc', 'arj' => 'application/x-arj', @@ -90,6 +96,7 @@ final class MimeType 'bpk' => 'application/octet-stream', 'bpmn' => 'application/octet-stream', 'bsp' => 'model/vnd.valve.source.compiled-map', + 'btf' => 'image/prs.btif', 'btif' => 'image/prs.btif', 'buffer' => 'application/octet-stream', 'bz' => 'application/x-bzip', @@ -141,6 +148,7 @@ final class MimeType 'cjs' => 'application/node', 'cla' => 'application/vnd.claymore', 'class' => 'application/octet-stream', + 'cld' => 'model/vnd.cld', 'clkk' => 'application/vnd.crick.clicker.keyboard', 'clkp' => 'application/vnd.crick.clicker.palette', 'clkt' => 'application/vnd.crick.clicker.template', @@ -175,6 +183,7 @@ final class MimeType 'csv' => 'text/csv', 'cu' => 'application/cu-seeme', 'curl' => 'text/vnd.curl', + 'cwl' => 'application/cwl', 'cww' => 'application/prs.cww', 'cxt' => 'application/x-director', 'cxx' => 'text/x-c', @@ -197,6 +206,7 @@ final class MimeType 'der' => 'application/x-x509-ca-cert', 'dfac' => 'application/vnd.dreamfactory', 'dgc' => 'application/x-dgc-compressed', + 'dib' => 'image/bmp', 'dic' => 'text/x-c', 'dir' => 'application/x-director', 'dis' => 'application/vnd.mobius.dis', @@ -219,6 +229,7 @@ final class MimeType 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', 'dp' => 'application/vnd.osgi.dp', 'dpg' => 'application/vnd.dpgraph', + 'dpx' => 'image/dpx', 'dra' => 'audio/vnd.dra', 'drle' => 'image/dicom-rle', 'dsc' => 'text/prs.lines.tag', @@ -255,7 +266,6 @@ final class MimeType 'eot' => 'application/vnd.ms-fontobject', 'eps' => 'application/postscript', 'epub' => 'application/epub+zip', - 'es' => 'application/ecmascript', 'es3' => 'application/vnd.eszigno3+xml', 'esa' => 'application/vnd.osgi.subsystem', 'esf' => 'application/vnd.epson.esf', @@ -448,6 +458,7 @@ final class MimeType 'jsonld' => 'application/ld+json', 'jsonml' => 'application/jsonml+json', 'jsx' => 'text/jsx', + 'jt' => 'model/jt', 'jxr' => 'image/jxr', 'jxra' => 'image/jxra', 'jxrs' => 'image/jxrs', @@ -552,7 +563,7 @@ final class MimeType 'mime' => 'message/rfc822', 'mj2' => 'video/mj2', 'mjp2' => 'video/mj2', - 'mjs' => 'application/javascript', + 'mjs' => 'text/javascript', 'mk3d' => 'video/x-matroska', 'mka' => 'audio/x-matroska', 'mkd' => 'text/x-markdown', @@ -602,6 +613,8 @@ final class MimeType 'msg' => 'application/vnd.ms-outlook', 'msh' => 'model/mesh', 'msi' => 'application/x-msdownload', + 'msix' => 'application/msix', + 'msixbundle' => 'application/msixbundle', 'msl' => 'application/vnd.mobius.msl', 'msm' => 'application/octet-stream', 'msp' => 'application/octet-stream', @@ -775,6 +788,8 @@ final class MimeType 'pvb' => 'application/vnd.3gpp.pic-bw-var', 'pwn' => 'application/vnd.3m.post-it-notes', 'pya' => 'audio/vnd.ms-playready.media.pya', + 'pyo' => 'model/vnd.pytha.pyox', + 'pyox' => 'model/vnd.pytha.pyox', 'pyv' => 'video/vnd.ms-playready.media.pyv', 'qam' => 'application/vnd.epson.quickanime', 'qbo' => 'application/vnd.intu.qbo', @@ -923,10 +938,12 @@ final class MimeType 'st' => 'application/vnd.sailingtracker.track', 'stc' => 'application/vnd.sun.xml.calc.template', 'std' => 'application/vnd.sun.xml.draw.template', + 'step' => 'application/STEP', 'stf' => 'application/vnd.wt.stf', 'sti' => 'application/vnd.sun.xml.impress.template', 'stk' => 'application/hyperstudio', 'stl' => 'model/stl', + 'stp' => 'application/STEP', 'stpx' => 'model/step+xml', 'stpxz' => 'model/step-xml+zip', 'stpz' => 'model/step+zip', @@ -1013,10 +1030,12 @@ final class MimeType 'ulx' => 'application/x-glulx', 'umj' => 'application/vnd.umajin', 'unityweb' => 'application/vnd.unity', + 'uo' => 'application/vnd.uoml+xml', 'uoml' => 'application/vnd.uoml+xml', 'uri' => 'text/uri-list', 'uris' => 'text/uri-list', 'urls' => 'text/uri-list', + 'usda' => 'model/vnd.usda', 'usdz' => 'model/vnd.usdz+zip', 'ustar' => 'application/x-ustar', 'utz' => 'application/vnd.uiq.theme', @@ -1096,6 +1115,7 @@ final class MimeType 'webmanifest' => 'application/manifest+json', 'webp' => 'image/webp', 'wg' => 'application/vnd.pmi.widget', + 'wgsl' => 'text/wgsl', 'wgt' => 'application/widget', 'wif' => 'application/watcherinfo+xml', 'wks' => 'application/vnd.ms-works', @@ -1150,9 +1170,10 @@ final class MimeType 'xel' => 'application/xcap-el+xml', 'xenc' => 'application/xenc+xml', 'xer' => 'application/patch-ops-error+xml', - 'xfdf' => 'application/vnd.adobe.xfdf', + 'xfdf' => 'application/xfdf', 'xfdl' => 'application/vnd.xfdl', 'xht' => 'application/xhtml+xml', + 'xhtm' => 'application/vnd.pwg-xhtml-print+xml', 'xhtml' => 'application/xhtml+xml', 'xhvml' => 'application/xv+xml', 'xif' => 'image/vnd.xiff', @@ -1183,6 +1204,7 @@ final class MimeType 'xpw' => 'application/vnd.intercon.formnet', 'xpx' => 'application/vnd.intercon.formnet', 'xsd' => 'application/xml', + 'xsf' => 'application/prs.xsf+xml', 'xsl' => 'application/xml', 'xslt' => 'application/xslt+xml', 'xsm' => 'application/vnd.syncml+xml', @@ -1218,7 +1240,7 @@ final class MimeType /** * Determines the mimetype of a file by looking at its extension. * - * @link https://raw.githubusercontent.com/jshttp/mime-db/master/db.json + * @see https://raw.githubusercontent.com/jshttp/mime-db/master/db.json */ public static function fromFilename(string $filename): ?string { @@ -1228,7 +1250,7 @@ public static function fromFilename(string $filename): ?string /** * Maps a file extensions to a mimetype. * - * @link https://raw.githubusercontent.com/jshttp/mime-db/master/db.json + * @see https://raw.githubusercontent.com/jshttp/mime-db/master/db.json */ public static function fromExtension(string $extension): ?string { diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/MultipartStream.php b/lib/Google/vendor/guzzlehttp/psr7/src/MultipartStream.php index 3e12b74d1..d23fba8a3 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/MultipartStream.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/MultipartStream.php @@ -51,7 +51,7 @@ public function isWritable(): bool /** * Get the headers needed before transferring the content of a POST file * - * @param array $headers + * @param string[] $headers */ private function getHeaders(array $headers): string { @@ -60,7 +60,7 @@ private function getHeaders(array $headers): string $str .= "{$key}: {$value}\r\n"; } - return "--{$this->boundary}\r\n" . trim($str) . "\r\n\r\n"; + return "--{$this->boundary}\r\n".trim($str)."\r\n\r\n"; } /** @@ -72,7 +72,7 @@ protected function createStream(array $elements = []): StreamInterface foreach ($elements as $element) { if (!is_array($element)) { - throw new \UnexpectedValueException("An array is expected"); + throw new \UnexpectedValueException('An array is expected'); } $this->addElement($stream, $element); } @@ -112,10 +112,15 @@ private function addElement(AppendStream $stream, array $element): void $stream->addStream(Utils::streamFor("\r\n")); } + /** + * @param string[] $headers + * + * @return array{0: StreamInterface, 1: string[]} + */ private function createElement(string $name, StreamInterface $stream, ?string $filename, array $headers): array { // Set a default content-disposition header if one was no provided - $disposition = $this->getHeader($headers, 'content-disposition'); + $disposition = self::getHeader($headers, 'content-disposition'); if (!$disposition) { $headers['Content-Disposition'] = ($filename === '0' || $filename) ? sprintf( @@ -127,7 +132,7 @@ private function createElement(string $name, StreamInterface $stream, ?string $f } // Set a default content-length header if one was no provided - $length = $this->getHeader($headers, 'content-length'); + $length = self::getHeader($headers, 'content-length'); if (!$length) { if ($length = $stream->getSize()) { $headers['Content-Length'] = (string) $length; @@ -135,21 +140,22 @@ private function createElement(string $name, StreamInterface $stream, ?string $f } // Set a default Content-Type if one was not supplied - $type = $this->getHeader($headers, 'content-type'); + $type = self::getHeader($headers, 'content-type'); if (!$type && ($filename === '0' || $filename)) { - if ($type = MimeType::fromFilename($filename)) { - $headers['Content-Type'] = $type; - } + $headers['Content-Type'] = MimeType::fromFilename($filename) ?? 'application/octet-stream'; } return [$stream, $headers]; } - private function getHeader(array $headers, string $key) + /** + * @param string[] $headers + */ + private static function getHeader(array $headers, string $key): ?string { $lowercaseHeader = strtolower($key); foreach ($headers as $k => $v) { - if (strtolower($k) === $lowercaseHeader) { + if (strtolower((string) $k) === $lowercaseHeader) { return $v; } } diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/PumpStream.php b/lib/Google/vendor/guzzlehttp/psr7/src/PumpStream.php index e90389c3b..e2040709f 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/PumpStream.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/PumpStream.php @@ -18,7 +18,7 @@ */ final class PumpStream implements StreamInterface { - /** @var callable|null */ + /** @var callable(int): (string|false|null)|null */ private $source; /** @var int|null */ @@ -34,7 +34,7 @@ final class PumpStream implements StreamInterface private $buffer; /** - * @param callable(int): (string|null|false) $source Source of the stream data. The callable MAY + * @param callable(int): (string|false|null) $source Source of the stream data. The callable MAY * accept an integer argument used to control the * amount of data to return. The callable MUST * return a string when called, or false|null on error @@ -60,6 +60,7 @@ public function __toString(): string throw $e; } trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR); + return ''; } } @@ -149,8 +150,6 @@ public function getContents(): string } /** - * {@inheritdoc} - * * @return mixed */ public function getMetadata($key = null) @@ -164,11 +163,12 @@ public function getMetadata($key = null) private function pump(int $length): void { - if ($this->source) { + if ($this->source !== null) { do { - $data = call_user_func($this->source, $length); + $data = ($this->source)($length); if ($data === false || $data === null) { $this->source = null; + return; } $this->buffer->write($data); diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/Query.php b/lib/Google/vendor/guzzlehttp/psr7/src/Query.php index 2faab3a88..8b9492797 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/Query.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/Query.php @@ -93,7 +93,7 @@ public static function build(array $params, $encoding = PHP_QUERY_RFC3986): stri $qs .= $k; $v = is_bool($v) ? (int) $v : $v; if ($v !== null) { - $qs .= '=' . $encoder((string) $v); + $qs .= '='.$encoder((string) $v); } $qs .= '&'; } else { @@ -101,7 +101,7 @@ public static function build(array $params, $encoding = PHP_QUERY_RFC3986): stri $qs .= $k; $vv = is_bool($vv) ? (int) $vv : $vv; if ($vv !== null) { - $qs .= '=' . $encoder((string) $vv); + $qs .= '='.$encoder((string) $vv); } $qs .= '&'; } diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/Request.php b/lib/Google/vendor/guzzlehttp/psr7/src/Request.php index b17af66a2..faafe1ad8 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/Request.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/Request.php @@ -28,7 +28,7 @@ class Request implements RequestInterface /** * @param string $method HTTP method * @param string|UriInterface $uri URI - * @param array $headers Request headers + * @param (string|string[])[] $headers Request headers * @param string|resource|StreamInterface|null $body Request body * @param string $version Protocol version */ @@ -69,7 +69,7 @@ public function getRequestTarget(): string $target = '/'; } if ($this->uri->getQuery() != '') { - $target .= '?' . $this->uri->getQuery(); + $target .= '?'.$this->uri->getQuery(); } return $target; @@ -85,6 +85,7 @@ public function withRequestTarget($requestTarget): RequestInterface $new = clone $this; $new->requestTarget = $requestTarget; + return $new; } @@ -98,6 +99,7 @@ public function withMethod($method): RequestInterface $this->assertMethod($method); $new = clone $this; $new->method = strtoupper($method); + return $new; } @@ -131,7 +133,7 @@ private function updateHostFromUri(): void } if (($port = $this->uri->getPort()) !== null) { - $host .= ':' . $port; + $host .= ':'.$port; } if (isset($this->headerNames['host'])) { @@ -141,7 +143,7 @@ private function updateHostFromUri(): void $this->headerNames['host'] = 'Host'; } // Ensure Host is the first header. - // See: http://tools.ietf.org/html/rfc7230#section-5.4 + // See: https://datatracker.ietf.org/doc/html/rfc7230#section-5.4 $this->headers = [$header => [$host]] + $this->headers; } diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/Response.php b/lib/Google/vendor/guzzlehttp/psr7/src/Response.php index 4c6ee6f03..00f16e2d9 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/Response.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/Response.php @@ -86,7 +86,7 @@ class Response implements ResponseInterface /** * @param int $status Status code - * @param array $headers Response headers + * @param (string|string[])[] $headers Response headers * @param string|resource|StreamInterface|null $body Response body * @param string $version Protocol version * @param string|null $reason Reason phrase (when empty a default will be used based on the status code) @@ -138,6 +138,7 @@ public function withStatus($code, $reasonPhrase = ''): ResponseInterface $reasonPhrase = self::PHRASES[$new->statusCode]; } $new->reasonPhrase = (string) $reasonPhrase; + return $new; } diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/Rfc7230.php b/lib/Google/vendor/guzzlehttp/psr7/src/Rfc7230.php index 30224018d..8219dba4d 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/Rfc7230.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/Rfc7230.php @@ -14,7 +14,7 @@ final class Rfc7230 * * Note: header delimiter (\r\n) is modified to \r?\n to accept line feed only delimiters for BC reasons. * - * @link https://github.com/amphp/http/blob/v1.0.1/src/Rfc7230.php#L12-L15 + * @see https://github.com/amphp/http/blob/v1.0.1/src/Rfc7230.php#L12-L15 * * @license https://github.com/amphp/http/blob/v1.0.1/LICENSE */ diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/ServerRequest.php b/lib/Google/vendor/guzzlehttp/psr7/src/ServerRequest.php index b2aa382da..3cc953453 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/ServerRequest.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/ServerRequest.php @@ -59,7 +59,7 @@ class ServerRequest extends Request implements ServerRequestInterface /** * @param string $method HTTP method * @param string|UriInterface $uri URI - * @param array $headers Request headers + * @param (string|string[])[] $headers Request headers * @param string|resource|StreamInterface|null $body Request body * @param string $version Protocol version * @param array $serverParams Typically the $_SERVER superglobal @@ -144,10 +144,10 @@ private static function normalizeNestedFileSpec(array $files = []): array foreach (array_keys($files['tmp_name']) as $key) { $spec = [ 'tmp_name' => $files['tmp_name'][$key], - 'size' => $files['size'][$key] ?? null, - 'error' => $files['error'][$key] ?? null, - 'name' => $files['name'][$key] ?? null, - 'type' => $files['type'][$key] ?? null, + 'size' => $files['size'][$key] ?? null, + 'error' => $files['error'][$key] ?? null, + 'name' => $files['name'][$key] ?? null, + 'type' => $files['type'][$key] ?? null, ]; $normalizedFiles[$key] = self::createUploadedFileFromSpec($spec); } @@ -182,7 +182,7 @@ public static function fromGlobals(): ServerRequestInterface private static function extractHostAndPortFromAuthority(string $authority): array { - $uri = 'http://' . $authority; + $uri = 'http://'.$authority; $parts = parse_url($uri); if (false === $parts) { return [null, null]; @@ -286,8 +286,6 @@ public function withQueryParams(array $query): ServerRequestInterface } /** - * {@inheritdoc} - * * @return array|object|null */ public function getParsedBody() @@ -309,8 +307,6 @@ public function getAttributes(): array } /** - * {@inheritdoc} - * * @return mixed */ public function getAttribute($attribute, $default = null) diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/Stream.php b/lib/Google/vendor/guzzlehttp/psr7/src/Stream.php index ecd31861e..0aff9b2b7 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/Stream.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/Stream.php @@ -12,8 +12,8 @@ class Stream implements StreamInterface { /** - * @see http://php.net/manual/function.fopen.php - * @see http://php.net/manual/en/function.gzopen.php + * @see https://www.php.net/manual/en/function.fopen.php + * @see https://www.php.net/manual/en/function.gzopen.php */ private const READABLE_MODES = '/r|a\+|ab\+|w\+|wb\+|x\+|xb\+|c\+|cb\+/'; private const WRITABLE_MODES = '/a|w|r\+|rb\+|rw|x|c/'; @@ -61,8 +61,8 @@ public function __construct($stream, array $options = []) $this->stream = $stream; $meta = stream_get_meta_data($this->stream); $this->seekable = $meta['seekable']; - $this->readable = (bool)preg_match(self::READABLE_MODES, $meta['mode']); - $this->writable = (bool)preg_match(self::WRITABLE_MODES, $meta['mode']); + $this->readable = (bool) preg_match(self::READABLE_MODES, $meta['mode']); + $this->writable = (bool) preg_match(self::WRITABLE_MODES, $meta['mode']); $this->uri = $this->getMetadata('uri'); } @@ -80,12 +80,14 @@ public function __toString(): string if ($this->isSeekable()) { $this->seek(0); } + return $this->getContents(); } catch (\Throwable $e) { if (\PHP_VERSION_ID >= 70400) { throw $e; } trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR); + return ''; } } @@ -145,6 +147,7 @@ public function getSize(): ?int $stats = fstat($this->stream); if (is_array($stats) && isset($stats['size'])) { $this->size = $stats['size']; + return $this->size; } @@ -207,7 +210,7 @@ public function seek($offset, $whence = SEEK_SET): void } if (fseek($this->stream, $offset, $whence) === -1) { throw new \RuntimeException('Unable to seek to stream position ' - . $offset . ' with whence ' . var_export($whence, true)); + .$offset.' with whence '.var_export($whence, true)); } } @@ -261,8 +264,6 @@ public function write($string): int } /** - * {@inheritdoc} - * * @return mixed */ public function getMetadata($key = null) diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/StreamDecoratorTrait.php b/lib/Google/vendor/guzzlehttp/psr7/src/StreamDecoratorTrait.php index 56d4104d4..601c13afb 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/StreamDecoratorTrait.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/StreamDecoratorTrait.php @@ -31,6 +31,7 @@ public function __get(string $name) { if ($name === 'stream') { $this->stream = $this->createStream(); + return $this->stream; } @@ -43,12 +44,14 @@ public function __toString(): string if ($this->isSeekable()) { $this->seek(0); } + return $this->getContents(); } catch (\Throwable $e) { if (\PHP_VERSION_ID >= 70400) { throw $e; } trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR); + return ''; } } @@ -67,7 +70,7 @@ public function __call(string $method, array $args) { /** @var callable $callable */ $callable = [$this->stream, $method]; - $result = call_user_func_array($callable, $args); + $result = ($callable)(...$args); // Always return the wrapped object if the result is a return $this return $result === $this->stream ? $this : $result; @@ -79,8 +82,6 @@ public function close(): void } /** - * {@inheritdoc} - * * @return mixed */ public function getMetadata($key = null) diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/StreamWrapper.php b/lib/Google/vendor/guzzlehttp/psr7/src/StreamWrapper.php index 2a9346403..ae8538814 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/StreamWrapper.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/StreamWrapper.php @@ -41,7 +41,7 @@ public static function getResource(StreamInterface $stream) $mode = 'w'; } else { throw new \InvalidArgumentException('The stream must be readable, ' - . 'writable, or both.'); + .'writable, or both.'); } return fopen('guzzle://stream', $mode, false, self::createStreamContext($stream)); @@ -55,7 +55,7 @@ public static function getResource(StreamInterface $stream) public static function createStreamContext(StreamInterface $stream) { return stream_context_create([ - 'guzzle' => ['stream' => $stream] + 'guzzle' => ['stream' => $stream], ]); } @@ -115,61 +115,89 @@ public function stream_seek(int $offset, int $whence): bool */ public function stream_cast(int $cast_as) { - $stream = clone($this->stream); + $stream = clone $this->stream; $resource = $stream->detach(); return $resource ?? false; } /** - * @return array + * @return array{ + * dev: int, + * ino: int, + * mode: int, + * nlink: int, + * uid: int, + * gid: int, + * rdev: int, + * size: int, + * atime: int, + * mtime: int, + * ctime: int, + * blksize: int, + * blocks: int + * } */ public function stream_stat(): array { static $modeMap = [ - 'r' => 33060, + 'r' => 33060, 'rb' => 33060, 'r+' => 33206, - 'w' => 33188, - 'wb' => 33188 + 'w' => 33188, + 'wb' => 33188, ]; return [ - 'dev' => 0, - 'ino' => 0, - 'mode' => $modeMap[$this->mode], - 'nlink' => 0, - 'uid' => 0, - 'gid' => 0, - 'rdev' => 0, - 'size' => $this->stream->getSize() ?: 0, - 'atime' => 0, - 'mtime' => 0, - 'ctime' => 0, + 'dev' => 0, + 'ino' => 0, + 'mode' => $modeMap[$this->mode], + 'nlink' => 0, + 'uid' => 0, + 'gid' => 0, + 'rdev' => 0, + 'size' => $this->stream->getSize() ?: 0, + 'atime' => 0, + 'mtime' => 0, + 'ctime' => 0, 'blksize' => 0, - 'blocks' => 0 + 'blocks' => 0, ]; } /** - * @return array + * @return array{ + * dev: int, + * ino: int, + * mode: int, + * nlink: int, + * uid: int, + * gid: int, + * rdev: int, + * size: int, + * atime: int, + * mtime: int, + * ctime: int, + * blksize: int, + * blocks: int + * } */ public function url_stat(string $path, int $flags): array { return [ - 'dev' => 0, - 'ino' => 0, - 'mode' => 0, - 'nlink' => 0, - 'uid' => 0, - 'gid' => 0, - 'rdev' => 0, - 'size' => 0, - 'atime' => 0, - 'mtime' => 0, - 'ctime' => 0, + 'dev' => 0, + 'ino' => 0, + 'mode' => 0, + 'nlink' => 0, + 'uid' => 0, + 'gid' => 0, + 'rdev' => 0, + 'size' => 0, + 'atime' => 0, + 'mtime' => 0, + 'ctime' => 0, 'blksize' => 0, - 'blocks' => 0 + 'blocks' => 0, ]; } } diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/UploadedFile.php b/lib/Google/vendor/guzzlehttp/psr7/src/UploadedFile.php index b1521bcf8..b26719937 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/UploadedFile.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/UploadedFile.php @@ -113,7 +113,7 @@ private function setError(int $error): void $this->error = $error; } - private function isStringNotEmpty($param): bool + private static function isStringNotEmpty($param): bool { return is_string($param) && false === empty($param); } @@ -163,7 +163,7 @@ public function moveTo($targetPath): void { $this->validateActive(); - if (false === $this->isStringNotEmpty($targetPath)) { + if (false === self::isStringNotEmpty($targetPath)) { throw new InvalidArgumentException( 'Invalid path provided for move operation; must be a non-empty string' ); diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/Uri.php b/lib/Google/vendor/guzzlehttp/psr7/src/Uri.php index 09e878d3d..f1feee871 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/Uri.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/Uri.php @@ -25,7 +25,7 @@ class Uri implements UriInterface, \JsonSerializable private const HTTP_DEFAULT_HOST = 'localhost'; private const DEFAULT_PORTS = [ - 'http' => 80, + 'http' => 80, 'https' => 443, 'ftp' => 21, 'gopher' => 70, @@ -41,14 +41,14 @@ class Uri implements UriInterface, \JsonSerializable /** * Unreserved characters for use in a regex. * - * @link https://tools.ietf.org/html/rfc3986#section-2.3 + * @see https://datatracker.ietf.org/doc/html/rfc3986#section-2.3 */ private const CHAR_UNRESERVED = 'a-zA-Z0-9_\-\.~'; /** * Sub-delims for use in a regex. * - * @link https://tools.ietf.org/html/rfc3986#section-2.2 + * @see https://datatracker.ietf.org/doc/html/rfc3986#section-2.2 */ private const CHAR_SUB_DELIMS = '!\$&\'\(\)\*\+,;='; private const QUERY_SEPARATORS_REPLACEMENT = ['=' => '%3D', '&' => '%26']; @@ -87,6 +87,7 @@ public function __construct(string $uri = '') $this->applyParts($parts); } } + /** * UTF-8 aware \parse_url() replacement. * @@ -121,7 +122,7 @@ static function ($matches) { $url ); - $result = parse_url($prefix . $encodedUrl); + $result = parse_url($prefix.$encodedUrl); if ($result === false) { return false; @@ -161,7 +162,7 @@ public function __toString(): string * `file:///` is the more common syntax for the file scheme anyway (Chrome for example redirects to * that format). * - * @link https://tools.ietf.org/html/rfc3986#section-5.3 + * @see https://datatracker.ietf.org/doc/html/rfc3986#section-5.3 */ public static function composeComponents(?string $scheme, ?string $authority, string $path, ?string $query, ?string $fragment): string { @@ -169,25 +170,25 @@ public static function composeComponents(?string $scheme, ?string $authority, st // weak type checks to also accept null until we can add scalar type hints if ($scheme != '') { - $uri .= $scheme . ':'; + $uri .= $scheme.':'; } if ($authority != '' || $scheme === 'file') { - $uri .= '//' . $authority; + $uri .= '//'.$authority; } if ($authority != '' && $path != '' && $path[0] != '/') { - $path = '/' . $path; + $path = '/'.$path; } $uri .= $path; if ($query != '') { - $uri .= '?' . $query; + $uri .= '?'.$query; } if ($fragment != '') { - $uri .= '#' . $fragment; + $uri .= '#'.$fragment; } return $uri; @@ -218,7 +219,7 @@ public static function isDefaultPort(UriInterface $uri): bool * @see Uri::isNetworkPathReference * @see Uri::isAbsolutePathReference * @see Uri::isRelativePathReference - * @link https://tools.ietf.org/html/rfc3986#section-4 + * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4 */ public static function isAbsolute(UriInterface $uri): bool { @@ -230,7 +231,7 @@ public static function isAbsolute(UriInterface $uri): bool * * A relative reference that begins with two slash characters is termed an network-path reference. * - * @link https://tools.ietf.org/html/rfc3986#section-4.2 + * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.2 */ public static function isNetworkPathReference(UriInterface $uri): bool { @@ -242,7 +243,7 @@ public static function isNetworkPathReference(UriInterface $uri): bool * * A relative reference that begins with a single slash character is termed an absolute-path reference. * - * @link https://tools.ietf.org/html/rfc3986#section-4.2 + * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.2 */ public static function isAbsolutePathReference(UriInterface $uri): bool { @@ -257,7 +258,7 @@ public static function isAbsolutePathReference(UriInterface $uri): bool * * A relative reference that does not begin with a slash character is termed a relative-path reference. * - * @link https://tools.ietf.org/html/rfc3986#section-4.2 + * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.2 */ public static function isRelativePathReference(UriInterface $uri): bool { @@ -276,7 +277,7 @@ public static function isRelativePathReference(UriInterface $uri): bool * @param UriInterface $uri The URI to check * @param UriInterface|null $base An optional base URI to compare against * - * @link https://tools.ietf.org/html/rfc3986#section-4.4 + * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.4 */ public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null): bool { @@ -335,8 +336,8 @@ public static function withQueryValue(UriInterface $uri, string $key, ?string $v * * It has the same behavior as withQueryValue() but for an associative array of key => value. * - * @param UriInterface $uri URI to use as a base. - * @param array $keyValueArray Associative array of key and values + * @param UriInterface $uri URI to use as a base. + * @param (string|null)[] $keyValueArray Associative array of key and values */ public static function withQueryValues(UriInterface $uri, array $keyValueArray): UriInterface { @@ -352,7 +353,7 @@ public static function withQueryValues(UriInterface $uri, array $keyValueArray): /** * Creates a URI from a hash of `parse_url` components. * - * @link http://php.net/manual/en/function.parse-url.php + * @see https://www.php.net/manual/en/function.parse-url.php * * @throws MalformedUriException If the components do not form a valid URI. */ @@ -374,11 +375,11 @@ public function getAuthority(): string { $authority = $this->host; if ($this->userInfo !== '') { - $authority = $this->userInfo . '@' . $authority; + $authority = $this->userInfo.'@'.$authority; } if ($this->port !== null) { - $authority .= ':' . $this->port; + $authority .= ':'.$this->port; } return $authority; @@ -435,7 +436,7 @@ public function withUserInfo($user, $password = null): UriInterface { $info = $this->filterUserInfoComponent($user); if ($password !== null) { - $info .= ':' . $this->filterUserInfoComponent($password); + $info .= ':'.$this->filterUserInfoComponent($password); } if ($this->userInfo === $info) { @@ -563,7 +564,7 @@ private function applyParts(array $parts): void ? $this->filterQueryAndFragment($parts['fragment']) : ''; if (isset($parts['pass'])) { - $this->userInfo .= ':' . $this->filterUserInfoComponent($parts['pass']); + $this->userInfo .= ':'.$this->filterUserInfoComponent($parts['pass']); } $this->removeDefaultPort(); @@ -595,7 +596,7 @@ private function filterUserInfoComponent($component): string } return preg_replace_callback( - '/(?:[^%' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . ']+|%(?![A-Fa-f0-9]{2}))/', + '/(?:[^%'.self::CHAR_UNRESERVED.self::CHAR_SUB_DELIMS.']+|%(?![A-Fa-f0-9]{2}))/', [$this, 'rawurlencodeMatchZero'], $component ); @@ -627,7 +628,7 @@ private function filterPort($port): ?int } $port = (int) $port; - if (0 > $port || 0xffff < $port) { + if (0 > $port || 0xFFFF < $port) { throw new \InvalidArgumentException( sprintf('Invalid port: %d. Must be between 0 and 65535', $port) ); @@ -637,7 +638,7 @@ private function filterPort($port): ?int } /** - * @param string[] $keys + * @param (string|int)[] $keys * * @return string[] */ @@ -649,7 +650,9 @@ private static function getFilteredQueryString(UriInterface $uri, array $keys): return []; } - $decodedKeys = array_map('rawurldecode', $keys); + $decodedKeys = array_map(function ($k): string { + return rawurldecode((string) $k); + }, $keys); return array_filter(explode('&', $current), function ($part) use ($decodedKeys) { return !in_array(rawurldecode(explode('=', $part)[0]), $decodedKeys, true); @@ -664,7 +667,7 @@ private static function generateQueryString(string $key, ?string $value): string $queryString = strtr($key, self::QUERY_SEPARATORS_REPLACEMENT); if ($value !== null) { - $queryString .= '=' . strtr($value, self::QUERY_SEPARATORS_REPLACEMENT); + $queryString .= '='.strtr($value, self::QUERY_SEPARATORS_REPLACEMENT); } return $queryString; @@ -691,7 +694,7 @@ private function filterPath($path): string } return preg_replace_callback( - '/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:@\/]++|%(?![A-Fa-f0-9]{2}))/', + '/(?:[^'.self::CHAR_UNRESERVED.self::CHAR_SUB_DELIMS.'%:@\/]++|%(?![A-Fa-f0-9]{2}))/', [$this, 'rawurlencodeMatchZero'], $path ); @@ -711,7 +714,7 @@ private function filterQueryAndFragment($str): string } return preg_replace_callback( - '/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/', + '/(?:[^'.self::CHAR_UNRESERVED.self::CHAR_SUB_DELIMS.'%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/', [$this, 'rawurlencodeMatchZero'], $str ); diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/UriNormalizer.php b/lib/Google/vendor/guzzlehttp/psr7/src/UriNormalizer.php index e12971edd..e17455737 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/UriNormalizer.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/UriNormalizer.php @@ -11,7 +11,7 @@ * * @author Tobias Schultze * - * @link https://tools.ietf.org/html/rfc3986#section-6 + * @see https://datatracker.ietf.org/doc/html/rfc3986#section-6 */ final class UriNormalizer { @@ -119,7 +119,7 @@ final class UriNormalizer * @param UriInterface $uri The URI to normalize * @param int $flags A bitmask of normalizations to apply, see constants * - * @link https://tools.ietf.org/html/rfc3986#section-6.2 + * @see https://datatracker.ietf.org/doc/html/rfc3986#section-6.2 */ public static function normalize(UriInterface $uri, int $flags = self::PRESERVING_NORMALIZATIONS): UriInterface { @@ -131,8 +131,8 @@ public static function normalize(UriInterface $uri, int $flags = self::PRESERVIN $uri = self::decodeUnreservedCharacters($uri); } - if ($flags & self::CONVERT_EMPTY_PATH && $uri->getPath() === '' && - ($uri->getScheme() === 'http' || $uri->getScheme() === 'https') + if ($flags & self::CONVERT_EMPTY_PATH && $uri->getPath() === '' + && ($uri->getScheme() === 'http' || $uri->getScheme() === 'https') ) { $uri = $uri->withPath('/'); } @@ -174,7 +174,7 @@ public static function normalize(UriInterface $uri, int $flags = self::PRESERVIN * @param UriInterface $uri2 An URI to compare * @param int $normalizations A bitmask of normalizations to apply, see constants * - * @link https://tools.ietf.org/html/rfc3986#section-6.1 + * @see https://datatracker.ietf.org/doc/html/rfc3986#section-6.1 */ public static function isEquivalent(UriInterface $uri1, UriInterface $uri2, int $normalizations = self::PRESERVING_NORMALIZATIONS): bool { @@ -185,7 +185,7 @@ private static function capitalizePercentEncoding(UriInterface $uri): UriInterfa { $regex = '/(?:%[A-Fa-f0-9]{2})++/'; - $callback = function (array $match) { + $callback = function (array $match): string { return strtoupper($match[0]); }; @@ -201,7 +201,7 @@ private static function decodeUnreservedCharacters(UriInterface $uri): UriInterf { $regex = '/%(?:2D|2E|5F|7E|3[0-9]|[46][1-9A-F]|[57][0-9A])/i'; - $callback = function (array $match) { + $callback = function (array $match): string { return rawurldecode($match[0]); }; diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/UriResolver.php b/lib/Google/vendor/guzzlehttp/psr7/src/UriResolver.php index 426e5c9ad..3737be1e5 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/UriResolver.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/UriResolver.php @@ -11,14 +11,14 @@ * * @author Tobias Schultze * - * @link https://tools.ietf.org/html/rfc3986#section-5 + * @see https://datatracker.ietf.org/doc/html/rfc3986#section-5 */ final class UriResolver { /** * Removes dot segments from a path and returns the new path. * - * @link http://tools.ietf.org/html/rfc3986#section-5.2.4 + * @see https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.4 */ public static function removeDotSegments(string $path): string { @@ -40,7 +40,7 @@ public static function removeDotSegments(string $path): string if ($path[0] === '/' && (!isset($newPath[0]) || $newPath[0] !== '/')) { // Re-add the leading slash if necessary for cases like "/.." - $newPath = '/' . $newPath; + $newPath = '/'.$newPath; } elseif ($newPath !== '' && ($segment === '.' || $segment === '..')) { // Add the trailing slash if necessary // If newPath is not empty, then $segment must be set and is the last segment from the foreach @@ -53,7 +53,7 @@ public static function removeDotSegments(string $path): string /** * Converts the relative URI into a new URI that is resolved against the base URI. * - * @link http://tools.ietf.org/html/rfc3986#section-5.2 + * @see https://datatracker.ietf.org/doc/html/rfc3986#section-5.2 */ public static function resolve(UriInterface $base, UriInterface $rel): UriInterface { @@ -80,13 +80,13 @@ public static function resolve(UriInterface $base, UriInterface $rel): UriInterf $targetPath = $rel->getPath(); } else { if ($targetAuthority != '' && $base->getPath() === '') { - $targetPath = '/' . $rel->getPath(); + $targetPath = '/'.$rel->getPath(); } else { $lastSlashPos = strrpos($base->getPath(), '/'); if ($lastSlashPos === false) { $targetPath = $rel->getPath(); } else { - $targetPath = substr($base->getPath(), 0, $lastSlashPos + 1) . $rel->getPath(); + $targetPath = substr($base->getPath(), 0, $lastSlashPos + 1).$rel->getPath(); } } } @@ -127,8 +127,8 @@ public static function resolve(UriInterface $base, UriInterface $rel): UriInterf */ public static function relativize(UriInterface $base, UriInterface $target): UriInterface { - if ($target->getScheme() !== '' && - ($base->getScheme() !== $target->getScheme() || $target->getAuthority() === '' && $base->getAuthority() !== '') + if ($target->getScheme() !== '' + && ($base->getScheme() !== $target->getScheme() || $target->getAuthority() === '' && $base->getAuthority() !== '') ) { return $target; } @@ -185,7 +185,7 @@ private static function getRelativePath(UriInterface $base, UriInterface $target } } $targetSegments[] = $targetLastSegment; - $relativePath = str_repeat('../', count($sourceSegments)) . implode('/', $targetSegments); + $relativePath = str_repeat('../', count($sourceSegments)).implode('/', $targetSegments); // A reference to am empty last segment or an empty first sub-segment must be prefixed with "./". // This also applies to a segment with a colon character (e.g., "file:colon") that cannot be used diff --git a/lib/Google/vendor/guzzlehttp/psr7/src/Utils.php b/lib/Google/vendor/guzzlehttp/psr7/src/Utils.php index 3a4cf3946..bf5ea9dba 100644 --- a/lib/Google/vendor/guzzlehttp/psr7/src/Utils.php +++ b/lib/Google/vendor/guzzlehttp/psr7/src/Utils.php @@ -14,18 +14,18 @@ final class Utils /** * Remove the items given by the keys, case insensitively from the data. * - * @param string[] $keys + * @param (string|int)[] $keys */ public static function caselessRemove(array $keys, array $data): array { $result = []; foreach ($keys as &$key) { - $key = strtolower($key); + $key = strtolower((string) $key); } foreach ($data as $k => $v) { - if (!is_string($k) || !in_array(strtolower($k), $keys)) { + if (!in_array(strtolower((string) $k), $keys)) { $result[$k] = $v; } } @@ -90,6 +90,7 @@ public static function copyToString(StreamInterface $stream, int $maxLen = -1): } $buffer .= $buf; } + return $buffer; } @@ -174,7 +175,7 @@ public static function modifyRequest(RequestInterface $request, array $changes): $standardPorts = ['http' => 80, 'https' => 443]; $scheme = $changes['uri']->getScheme(); if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) { - $changes['set_headers']['Host'] .= ':' . $port; + $changes['set_headers']['Host'] .= ':'.$port; } } } @@ -230,7 +231,7 @@ public static function modifyRequest(RequestInterface $request, array $changes): * @param StreamInterface $stream Stream to read from * @param int|null $maxLength Maximum buffer length */ - public static function readLine(StreamInterface $stream, ?int $maxLength = null): string + public static function readLine(StreamInterface $stream, int $maxLength = null): string { $buffer = ''; $size = 0; @@ -291,6 +292,7 @@ public static function streamFor($resource = '', array $options = []): StreamInt fwrite($stream, (string) $resource); fseek($stream, 0); } + return new Stream($stream, $options); } @@ -308,6 +310,7 @@ public static function streamFor($resource = '', array $options = []): StreamInt fseek($stream, 0); $resource = $stream; } + return new Stream($resource, $options); case 'object': /** @var object $resource */ @@ -320,6 +323,7 @@ public static function streamFor($resource = '', array $options = []): StreamInt } $result = $resource->current(); $resource->next(); + return $result; }, $options); } elseif (method_exists($resource, '__toString')) { @@ -334,7 +338,7 @@ public static function streamFor($resource = '', array $options = []): StreamInt return new PumpStream($resource, $options); } - throw new \InvalidArgumentException('Invalid resource type: ' . gettype($resource)); + throw new \InvalidArgumentException('Invalid resource type: '.gettype($resource)); } /** diff --git a/lib/Google/vendor/monolog/monolog/CHANGELOG.md b/lib/Google/vendor/monolog/monolog/CHANGELOG.md index 8a8c65124..aca1bdd0d 100644 --- a/lib/Google/vendor/monolog/monolog/CHANGELOG.md +++ b/lib/Google/vendor/monolog/monolog/CHANGELOG.md @@ -1,3 +1,9 @@ +### 2.9.2 (2023-10-27) + + * Fixed display_errors parsing in ErrorHandler which did not support string values (#1804) + * Fixed bug where the previous error handler would not be restored in some cases where StreamHandler fails (#1815) + * Fixed normalization error when normalizing incomplete classes (#1833) + ### 2.9.1 (2023-02-06) * Fixed Logger not being serializable anymore (#1792) diff --git a/lib/Google/vendor/monolog/monolog/src/Monolog/ErrorHandler.php b/lib/Google/vendor/monolog/monolog/src/Monolog/ErrorHandler.php index 576f1713f..1406d34e8 100644 --- a/lib/Google/vendor/monolog/monolog/src/Monolog/ErrorHandler.php +++ b/lib/Google/vendor/monolog/monolog/src/Monolog/ErrorHandler.php @@ -198,7 +198,7 @@ private function handleException(\Throwable $e): void ($this->previousExceptionHandler)($e); } - if (!headers_sent() && !ini_get('display_errors')) { + if (!headers_sent() && in_array(strtolower((string) ini_get('display_errors')), ['0', '', 'false', 'off', 'none', 'no'], true)) { http_response_code(500); } diff --git a/lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php b/lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php index b31b2971a..e6e789833 100644 --- a/lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php +++ b/lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php @@ -155,7 +155,7 @@ protected function normalizeException(\Throwable $e, int $depth = 0): string do { $depth++; if ($depth > $this->maxNormalizeDepth) { - $str .= '\n[previous exception] Over ' . $this->maxNormalizeDepth . ' levels deep, aborting normalization'; + $str .= "\n[previous exception] Over " . $this->maxNormalizeDepth . ' levels deep, aborting normalization'; break; } diff --git a/lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php b/lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php index 5441bc0aa..f926a842f 100644 --- a/lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php +++ b/lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php @@ -174,6 +174,9 @@ protected function normalize($data, int $depth = 0) if ($data instanceof \JsonSerializable) { /** @var null|scalar|array $value */ $value = $data->jsonSerialize(); + } elseif (\get_class($data) === '__PHP_Incomplete_Class') { + $accessor = new \ArrayObject($data); + $value = (string) $accessor['__PHP_Incomplete_Class_Name']; } elseif (method_exists($data, '__toString')) { /** @var string $value */ $value = $data->__toString(); diff --git a/lib/Google/vendor/monolog/monolog/src/Monolog/Handler/ElasticSearchHandler.php b/lib/Google/vendor/monolog/monolog/src/Monolog/Handler/ElasticsearchHandler.php similarity index 100% rename from lib/Google/vendor/monolog/monolog/src/Monolog/Handler/ElasticSearchHandler.php rename to lib/Google/vendor/monolog/monolog/src/Monolog/Handler/ElasticsearchHandler.php diff --git a/lib/Google/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php b/lib/Google/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php index 651835122..82c048e1c 100644 --- a/lib/Google/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php +++ b/lib/Google/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php @@ -135,11 +135,14 @@ protected function write(array $record): void $this->createDir($url); $this->errorMessage = null; set_error_handler([$this, 'customErrorHandler']); - $stream = fopen($url, 'a'); - if ($this->filePermission !== null) { - @chmod($url, $this->filePermission); + try { + $stream = fopen($url, 'a'); + if ($this->filePermission !== null) { + @chmod($url, $this->filePermission); + } + } finally { + restore_error_handler(); } - restore_error_handler(); if (!is_resource($stream)) { $this->stream = null; diff --git a/lib/Google/vendor/phpseclib/phpseclib/BACKERS.md b/lib/Google/vendor/phpseclib/phpseclib/BACKERS.md index 5e5c6d99b..efca482ad 100644 --- a/lib/Google/vendor/phpseclib/phpseclib/BACKERS.md +++ b/lib/Google/vendor/phpseclib/phpseclib/BACKERS.md @@ -12,4 +12,6 @@ phpseclib ongoing development is made possible by [Tidelift](https://tidelift.co - [Charles Severance](https://github.com/csev) - [Rachel Fish](https://github.com/itsrachelfish) - Tharyrok -- [cjhaas](https://github.com/cjhaas) \ No newline at end of file +- [cjhaas](https://github.com/cjhaas) +- [istiak-tridip](https://github.com/istiak-tridip) +- [Anna Filina](https://github.com/afilina) \ No newline at end of file diff --git a/lib/Google/vendor/phpseclib/phpseclib/README.md b/lib/Google/vendor/phpseclib/phpseclib/README.md index 64c06ba28..37cbcb9d5 100644 --- a/lib/Google/vendor/phpseclib/phpseclib/README.md +++ b/lib/Google/vendor/phpseclib/phpseclib/README.md @@ -51,8 +51,7 @@ SSH-2, SFTP, X.509, an arbitrary-precision integer arithmetic library, Ed25519 / * PHP4 compatible * Composer compatible (PSR-0 autoloading) * Install using Composer: `composer require phpseclib/phpseclib:~1.0` -* Install using PEAR: See [phpseclib PEAR Channel Documentation](http://phpseclib.sourceforge.net/pear.htm) -* [Download 1.0.20 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.20.zip/download) +* [Download 1.0.23 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.23.zip/download) ## Security contact information diff --git a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php index 407f03699..09eb5b1b3 100644 --- a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php +++ b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php @@ -94,7 +94,7 @@ abstract class AsymmetricKey /** * @param string $type - * @return string + * @return array|string */ abstract public function toString($type, array $options = []); @@ -130,7 +130,7 @@ protected static function initialize_static_variables() * * @param string $key * @param string $password optional - * @return AsymmetricKey + * @return \phpseclib3\Crypt\Common\PublicKey|\phpseclib3\Crypt\Common\PrivateKey */ public static function load($key, $password = false) { @@ -382,7 +382,7 @@ public static function addFileFormat($fullname) $shortname = $meta->getShortName(); self::$plugins[static::ALGORITHM]['Keys'][strtolower($shortname)] = $fullname; if ($meta->hasConstant('IS_INVISIBLE')) { - self::$invisiblePlugins[static::ALGORITHM] = strtolower($name); + self::$invisiblePlugins[static::ALGORITHM][] = strtolower($shortname); } } } diff --git a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php index 4638a5393..7aa554808 100644 --- a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php +++ b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php @@ -141,6 +141,7 @@ private static function getPBES1EncryptionObject($algo) break; case 'RC2': $cipher = new RC2('cbc'); + $cipher->setKeyLength(64); break; case '3-KeyTripleDES': $cipher = new TripleDES('cbc'); @@ -218,7 +219,7 @@ private static function getPBES2EncryptionObject($algo) { switch ($algo) { case 'desCBC': - $cipher = new TripleDES('cbc'); + $cipher = new DES('cbc'); break; case 'des-EDE3-CBC': $cipher = new TripleDES('cbc'); diff --git a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php index 2a376f113..175508d41 100644 --- a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php +++ b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php @@ -668,6 +668,8 @@ protected static function initialize_static_variables() switch (true) { // PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster case (PHP_OS & "\xDF\xDF\xDF") === 'WIN': + case !function_exists('php_uname'): + case !is_string(php_uname('m')): case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM': case defined('PHP_INT_SIZE') && PHP_INT_SIZE == 8: self::$use_reg_intval = true; @@ -917,7 +919,7 @@ public function setKey($key) * @see Crypt/Hash.php * @param string $password * @param string $method - * @param string[] ...$func_args + * @param int|string ...$func_args * @throws \LengthException if pbkdf1 is being used and the derived key length exceeds the hash length * @throws \RuntimeException if bcrypt is being used and a salt isn't provided * @return bool diff --git a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/IEEE.php b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/IEEE.php new file mode 100644 index 000000000..69139da45 --- /dev/null +++ b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/IEEE.php @@ -0,0 +1,66 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Signature; + +use phpseclib3\Math\BigInteger; + +/** + * ASN1 Signature Handler + * + * @author Jim Wigginton + */ +abstract class IEEE +{ + /** + * Loads a signature + * + * @param string $sig + * @return array + */ + public static function load($sig) + { + if (!is_string($sig)) { + return false; + } + + $len = strlen($sig); + if ($len & 1) { + return false; + } + + $r = new BigInteger(substr($sig, 0, $len >> 1), 256); + $s = new BigInteger(substr($sig, $len >> 1), 256); + + return compact('r', 's'); + } + + /** + * Returns a signature in the appropriate format + * + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @return string + */ + public static function save(BigInteger $r, BigInteger $s) + { + $r = $r->toBytes(); + $s = $s->toBytes(); + $len = max(strlen($r), strlen($s)); + return str_pad($r, $len, "\0", STR_PAD_LEFT) . str_pad($s, $len, "\0", STR_PAD_LEFT); + } +} diff --git a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php index 462ea1a33..598869614 100644 --- a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php +++ b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php @@ -150,7 +150,7 @@ public function sign($message) // we use specified curves to avoid issues with OpenSSL possibly not supporting a given named curve; // doing this may mean some curve-specific optimizations can't be used but idk if OpenSSL even // has curve-specific optimizations - $result = openssl_sign($message, $signature, $this->toString('PKCS8', ['namedCurve' => false]), $this->hash->getHash()); + $result = openssl_sign($message, $signature, $this->withPassword()->toString('PKCS8', ['namedCurve' => false]), $this->hash->getHash()); if ($result) { if ($shortFormat == 'ASN1') { diff --git a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php index 7b935cc2d..19dcfea3f 100644 --- a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php +++ b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php @@ -332,6 +332,7 @@ public static function createKey($bits = 2048) openssl_pkey_export($rsa, $privatekeystr, null, $config); // clear the buffer of error strings stemming from a minimalistic openssl.cnf + // https://github.com/php/php-src/issues/11054 talks about other errors this'll pick up while (openssl_error_string() !== false) { } @@ -841,15 +842,15 @@ public function withPadding($padding) self::ENCRYPTION_PKCS1, self::ENCRYPTION_NONE ]; - $numSelected = 0; + $encryptedCount = 0; $selected = 0; foreach ($masks as $mask) { if ($padding & $mask) { $selected = $mask; - $numSelected++; + $encryptedCount++; } } - if ($numSelected > 1) { + if ($encryptedCount > 1) { throw new InconsistentSetupException('Multiple encryption padding modes have been selected; at most only one should be selected'); } $encryptionPadding = $selected; @@ -859,22 +860,26 @@ public function withPadding($padding) self::SIGNATURE_RELAXED_PKCS1, self::SIGNATURE_PKCS1 ]; - $numSelected = 0; + $signatureCount = 0; $selected = 0; foreach ($masks as $mask) { if ($padding & $mask) { $selected = $mask; - $numSelected++; + $signatureCount++; } } - if ($numSelected > 1) { + if ($signatureCount > 1) { throw new InconsistentSetupException('Multiple signature padding modes have been selected; at most only one should be selected'); } $signaturePadding = $selected; $new = clone $this; - $new->encryptionPadding = $encryptionPadding; - $new->signaturePadding = $signaturePadding; + if ($encryptedCount) { + $new->encryptionPadding = $encryptionPadding; + } + if ($signatureCount) { + $new->signaturePadding = $signaturePadding; + } return $new; } diff --git a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php index cd8b76272..ff31f9c88 100644 --- a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php +++ b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php @@ -833,7 +833,6 @@ protected function setupInlineCrypt() // Generating encrypt code: $init_encrypt .= ' - static $tables; if (empty($tables)) { $tables = &$this->getTables(); } @@ -890,7 +889,6 @@ protected function setupInlineCrypt() // Generating decrypt code: $init_decrypt .= ' - static $invtables; if (empty($invtables)) { $invtables = &$this->getInvTables(); } @@ -947,7 +945,7 @@ protected function setupInlineCrypt() $this->inline_crypt = $this->createInlineCryptFunction( [ - 'init_crypt' => '', + 'init_crypt' => 'static $tables; static $invtables;', 'init_encrypt' => $init_encrypt, 'init_decrypt' => $init_decrypt, 'encrypt_block' => $encrypt_block, diff --git a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php index e21589c51..c4b06a560 100644 --- a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php +++ b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php @@ -21,7 +21,6 @@ namespace phpseclib3\File; -use DateTime; use phpseclib3\Common\Functions\Strings; use phpseclib3\File\ASN1\Element; use phpseclib3\Math\BigInteger; @@ -205,7 +204,7 @@ public static function decodeBER($encoded) return null; } - return [self::decode_ber($encoded)]; + return [$decoded]; } /** @@ -1149,6 +1148,11 @@ public static function decodeOID($content) $oid = []; $pos = 0; $len = strlen($content); + // see https://github.com/openjdk/jdk/blob/2deb318c9f047ec5a4b160d66a4b52f93688ec42/src/java.base/share/classes/sun/security/util/ObjectIdentifier.java#L55 + if ($len > 4096) { + //throw new \RuntimeException("Object identifier size is limited to 4096 bytes ($len bytes present)"); + return false; + } if (ord($content[$len - 1]) & 0x80) { return false; @@ -1403,7 +1407,7 @@ public static function convert($in, $from = self::TYPE_UTF8_STRING, $to = self:: return false; } break; - case ($c & 0x80000000) != 0: + case ($c & (PHP_INT_SIZE == 8 ? 0x80000000 : (1 << 31))) != 0: return false; case $c >= 0x04000000: $v .= chr(0x80 | ($c & 0x3F)); diff --git a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/X509.php b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/X509.php index 7aa278f2a..5e2f073f4 100644 --- a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/X509.php +++ b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/X509.php @@ -164,7 +164,7 @@ class X509 * * @var array */ - private $CAs; + private $CAs = []; /** * The currently loaded certificate @@ -315,6 +315,10 @@ public function __construct() 'id-at-uniqueIdentifier' => '2.5.4.45', 'id-at-role' => '2.5.4.72', 'id-at-postalAddress' => '2.5.4.16', + 'jurisdictionOfIncorporationCountryName' => '1.3.6.1.4.1.311.60.2.1.3', + 'jurisdictionOfIncorporationStateOrProvinceName' => '1.3.6.1.4.1.311.60.2.1.2', + 'jurisdictionLocalityName' => '1.3.6.1.4.1.311.60.2.1.1', + 'id-at-businessCategory' => '2.5.4.15', //'id-domainComponent' => '0.9.2342.19200300.100.1.25', //'pkcs-9' => '1.2.840.113549.1.9', @@ -1038,7 +1042,8 @@ public function validateURL($url) if ($names = $this->getExtension('id-ce-subjectAltName')) { foreach ($names as $name) { foreach ($name as $key => $value) { - $value = str_replace(['.', '*'], ['\.', '[^.]*'], $value); + $value = preg_quote($value); + $value = str_replace('\*', '[^.]*', $value); switch ($key) { case 'dNSName': /* From RFC2818 "HTTP over TLS": @@ -1538,6 +1543,20 @@ public static function encodeIP($ip) private function translateDNProp($propName) { switch (strtolower($propName)) { + case 'jurisdictionofincorporationcountryname': + case 'jurisdictioncountryname': + case 'jurisdictionc': + return 'jurisdictionOfIncorporationCountryName'; + case 'jurisdictionofincorporationstateorprovincename': + case 'jurisdictionstateorprovincename': + case 'jurisdictionst': + return 'jurisdictionOfIncorporationStateOrProvinceName'; + case 'jurisdictionlocalityname': + case 'jurisdictionl': + return 'jurisdictionLocalityName'; + case 'id-at-businesscategory': + case 'businesscategory': + return 'id-at-businessCategory'; case 'id-at-countryname': case 'countryname': case 'c': @@ -2030,9 +2049,6 @@ public function getChain() if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { return false; } - if (empty($this->CAs)) { - return $chain; - } while (true) { $currentCert = $chain[count($chain) - 1]; for ($i = 0; $i < count($this->CAs); $i++) { diff --git a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php index 70491abd6..67d4788f9 100644 --- a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php +++ b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php @@ -100,10 +100,6 @@ public static function setEngine($main, array $modexps = ['DefaultEngine']) /** @var class-string $fqmain */ self::$mainEngine = $fqmain; - if (!in_array('Default', $modexps)) { - $modexps[] = 'DefaultEngine'; - } - $found = false; foreach ($modexps as $modexp) { try { @@ -140,18 +136,23 @@ private static function initialize_static_variables() { if (!isset(self::$mainEngine)) { $engines = [ - ['GMP'], + ['GMP', ['DefaultEngine']], ['PHP64', ['OpenSSL']], ['BCMath', ['OpenSSL']], - ['PHP32', ['OpenSSL']] + ['PHP32', ['OpenSSL']], + ['PHP64', ['DefaultEngine']], + ['PHP32', ['DefaultEngine']] ]; + foreach ($engines as $engine) { try { - self::setEngine($engine[0], isset($engine[1]) ? $engine[1] : []); - break; + self::setEngine($engine[0], $engine[1]); + return; } catch (\Exception $e) { } } + + throw new \UnexpectedValueException('No valid BigInteger found. This is only possible when JIT is enabled on Windows and neither the GMP or BCMath extensions are available so either disable JIT or install GMP / BCMath'); } } diff --git a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php index 2b00bc37c..474abe105 100644 --- a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php +++ b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php @@ -619,7 +619,7 @@ public function getLength() */ public function getLengthInBytes() { - return strlen($this->toBytes()); + return (int) ceil($this->getLength() / 8); } /** @@ -644,6 +644,11 @@ protected function powModOuter(Engine $e, Engine $n) return $this->normalize($temp->powModInner($e, $n)); } + if ($this->compare($n) > 0) { + list(, $temp) = $this->divide($n); + return $temp->powModInner($e, $n); + } + return $this->powModInner($e, $n); } @@ -781,6 +786,11 @@ protected static function randomRangePrimeOuter(Engine $min, Engine $max) $min = $temp; } + $length = $max->getLength(); + if ($length > 8196) { + throw new \RuntimeException("Generation of random prime numbers larger than 8196 has been disabled ($length)"); + } + $x = static::randomRange($min, $max); return static::randomRangePrimeInner($x, $min, $max); @@ -985,6 +995,15 @@ protected function testPrimality($t) */ public function isPrime($t = false) { + // OpenSSL limits RSA keys to 16384 bits. The length of an RSA key is equal to the length of the modulo, which is + // produced by multiplying the primes p and q by one another. The largest number two 8196 bit primes can produce is + // a 16384 bit number so, basically, 8196 bit primes are the largest OpenSSL will generate and if that's the largest + // that it'll generate it also stands to reason that that's the largest you'll be able to test primality on + $length = $this->getLength(); + if ($length > 8196) { + throw new \RuntimeException("Primality testing is not supported for numbers larger than 8196 bits ($length)"); + } + if (!$t) { $t = $this->setupIsPrime(); } diff --git a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php index ab9bdc99b..2d8959522 100644 --- a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php +++ b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php @@ -1326,4 +1326,32 @@ private function bitwise_small_split($split) return array_reverse($vals); } + + /** + * @return bool + */ + protected static function testJITOnWindows() + { + // see https://github.com/php/php-src/issues/11917 + if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' && function_exists('opcache_get_status') && PHP_VERSION_ID < 80213 && !defined('PHPSECLIB_ALLOW_JIT')) { + $status = opcache_get_status(); + if ($status && isset($status['jit']) && $status['jit']['enabled'] && $status['jit']['on']) { + return true; + } + } + return false; + } + + /** + * Return the size of a BigInteger in bits + * + * @return int + */ + public function getLength() + { + $max = count($this->value) - 1; + return $max != -1 ? + $max * static::BASE + intval(ceil(log($this->value[$max] + 1, 2))) : + 0; + } } diff --git a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php index 964cd170d..3a775e7db 100644 --- a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php +++ b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php @@ -80,10 +80,10 @@ protected function initialize($base) } $step = count($vals) & 3; if ($step) { - $digit = floor($digit / pow(2, 2 * $step)); + $digit = (int) floor($digit / pow(2, 2 * $step)); } if ($step != 3) { - $digit &= static::MAX_DIGIT; + $digit = (int) fmod($digit, static::BASE_FULL); $i++; } $vals[] = $digit; @@ -102,7 +102,7 @@ protected function initialize($base) */ public static function isValidEngine() { - return PHP_INT_SIZE >= 4; + return PHP_INT_SIZE >= 4 && !self::testJITOnWindows(); } /** diff --git a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php index ca11c08d4..70a2e173b 100644 --- a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php +++ b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php @@ -103,7 +103,7 @@ protected function initialize($base) */ public static function isValidEngine() { - return PHP_INT_SIZE >= 8; + return PHP_INT_SIZE >= 8 && !self::testJITOnWindows(); } /** diff --git a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php index 3e21a67ad..5da8c937e 100644 --- a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php +++ b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php @@ -48,6 +48,15 @@ class BinaryField extends FiniteField public function __construct(...$indices) { $m = array_shift($indices); + if ($m > 571) { + /* sect571r1 and sect571k1 are the largest binary curves that https://www.secg.org/sec2-v2.pdf defines + altho theoretically there may be legit reasons to use binary finite fields with larger degrees + imposing a limit on the maximum size is both reasonable and precedented. in particular, + http://tools.ietf.org/html/rfc4253#section-6.1 (The Secure Shell (SSH) Transport Layer Protocol) says + "implementations SHOULD check that the packet length is reasonable in order for the implementation to + avoid denial of service and/or buffer overflow attacks" */ + throw new \OutOfBoundsException('Degrees larger than 571 are not supported'); + } $val = str_repeat('0', $m) . '1'; foreach ($indices as $index) { $val[$index] = '1'; diff --git a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php index 748f9a49f..1bd7aaf0f 100644 --- a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php +++ b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php @@ -263,7 +263,7 @@ public function squareRoot() $r = $this->value->powMod($temp, static::$modulo[$this->instanceID]); while (!$t->equals($one)) { - for ($i == clone $one; $i->compare($m) < 0; $i = $i->add($one)) { + for ($i = clone $one; $i->compare($m) < 0; $i = $i->add($one)) { if ($t->powMod($two->pow($i), static::$modulo[$this->instanceID])->equals($one)) { break; } @@ -312,8 +312,11 @@ public function negate() */ public function toBytes() { - $length = static::$modulo[$this->instanceID]->getLengthInBytes(); - return str_pad($this->value->toBytes(), $length, "\0", STR_PAD_LEFT); + if (isset(static::$modulo[$this->instanceID])) { + $length = static::$modulo[$this->instanceID]->getLengthInBytes(); + return str_pad($this->value->toBytes(), $length, "\0", STR_PAD_LEFT); + } + return $this->value->toBytes(); } /** diff --git a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php index 1c675a6e0..144ef7950 100644 --- a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php +++ b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php @@ -93,7 +93,7 @@ class SFTP extends SSH2 * @var array * @access private */ - private $packet_types = []; + private static $packet_types = []; /** * Status Codes @@ -102,19 +102,19 @@ class SFTP extends SSH2 * @var array * @access private */ - private $status_codes = []; + private static $status_codes = []; /** @var array */ - private $attributes; + private static $attributes; /** @var array */ - private $open_flags; + private static $open_flags; /** @var array */ - private $open_flags5; + private static $open_flags5; /** @var array */ - private $file_types; + private static $file_types; /** * The Request ID @@ -350,7 +350,9 @@ class SFTP extends SSH2 * * Connects to an SFTP server * - * @param string $host + * $host can either be a string, representing the host, or a stream resource. + * + * @param mixed $host * @param int $port * @param int $timeout */ @@ -360,154 +362,156 @@ public function __construct($host, $port = 22, $timeout = 10) $this->max_sftp_packet = 1 << 15; - $this->packet_types = [ - 1 => 'NET_SFTP_INIT', - 2 => 'NET_SFTP_VERSION', - 3 => 'NET_SFTP_OPEN', - 4 => 'NET_SFTP_CLOSE', - 5 => 'NET_SFTP_READ', - 6 => 'NET_SFTP_WRITE', - 7 => 'NET_SFTP_LSTAT', - 9 => 'NET_SFTP_SETSTAT', - 10 => 'NET_SFTP_FSETSTAT', - 11 => 'NET_SFTP_OPENDIR', - 12 => 'NET_SFTP_READDIR', - 13 => 'NET_SFTP_REMOVE', - 14 => 'NET_SFTP_MKDIR', - 15 => 'NET_SFTP_RMDIR', - 16 => 'NET_SFTP_REALPATH', - 17 => 'NET_SFTP_STAT', - 18 => 'NET_SFTP_RENAME', - 19 => 'NET_SFTP_READLINK', - 20 => 'NET_SFTP_SYMLINK', - 21 => 'NET_SFTP_LINK', - - 101 => 'NET_SFTP_STATUS', - 102 => 'NET_SFTP_HANDLE', - 103 => 'NET_SFTP_DATA', - 104 => 'NET_SFTP_NAME', - 105 => 'NET_SFTP_ATTRS', - - 200 => 'NET_SFTP_EXTENDED' - ]; - $this->status_codes = [ - 0 => 'NET_SFTP_STATUS_OK', - 1 => 'NET_SFTP_STATUS_EOF', - 2 => 'NET_SFTP_STATUS_NO_SUCH_FILE', - 3 => 'NET_SFTP_STATUS_PERMISSION_DENIED', - 4 => 'NET_SFTP_STATUS_FAILURE', - 5 => 'NET_SFTP_STATUS_BAD_MESSAGE', - 6 => 'NET_SFTP_STATUS_NO_CONNECTION', - 7 => 'NET_SFTP_STATUS_CONNECTION_LOST', - 8 => 'NET_SFTP_STATUS_OP_UNSUPPORTED', - 9 => 'NET_SFTP_STATUS_INVALID_HANDLE', - 10 => 'NET_SFTP_STATUS_NO_SUCH_PATH', - 11 => 'NET_SFTP_STATUS_FILE_ALREADY_EXISTS', - 12 => 'NET_SFTP_STATUS_WRITE_PROTECT', - 13 => 'NET_SFTP_STATUS_NO_MEDIA', - 14 => 'NET_SFTP_STATUS_NO_SPACE_ON_FILESYSTEM', - 15 => 'NET_SFTP_STATUS_QUOTA_EXCEEDED', - 16 => 'NET_SFTP_STATUS_UNKNOWN_PRINCIPAL', - 17 => 'NET_SFTP_STATUS_LOCK_CONFLICT', - 18 => 'NET_SFTP_STATUS_DIR_NOT_EMPTY', - 19 => 'NET_SFTP_STATUS_NOT_A_DIRECTORY', - 20 => 'NET_SFTP_STATUS_INVALID_FILENAME', - 21 => 'NET_SFTP_STATUS_LINK_LOOP', - 22 => 'NET_SFTP_STATUS_CANNOT_DELETE', - 23 => 'NET_SFTP_STATUS_INVALID_PARAMETER', - 24 => 'NET_SFTP_STATUS_FILE_IS_A_DIRECTORY', - 25 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_CONFLICT', - 26 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_REFUSED', - 27 => 'NET_SFTP_STATUS_DELETE_PENDING', - 28 => 'NET_SFTP_STATUS_FILE_CORRUPT', - 29 => 'NET_SFTP_STATUS_OWNER_INVALID', - 30 => 'NET_SFTP_STATUS_GROUP_INVALID', - 31 => 'NET_SFTP_STATUS_NO_MATCHING_BYTE_RANGE_LOCK' - ]; - // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1 - // the order, in this case, matters quite a lot - see \phpseclib3\Net\SFTP::_parseAttributes() to understand why - $this->attributes = [ - 0x00000001 => 'NET_SFTP_ATTR_SIZE', - 0x00000002 => 'NET_SFTP_ATTR_UIDGID', // defined in SFTPv3, removed in SFTPv4+ - 0x00000080 => 'NET_SFTP_ATTR_OWNERGROUP', // defined in SFTPv4+ - 0x00000004 => 'NET_SFTP_ATTR_PERMISSIONS', - 0x00000008 => 'NET_SFTP_ATTR_ACCESSTIME', - 0x00000010 => 'NET_SFTP_ATTR_CREATETIME', // SFTPv4+ - 0x00000020 => 'NET_SFTP_ATTR_MODIFYTIME', - 0x00000040 => 'NET_SFTP_ATTR_ACL', - 0x00000100 => 'NET_SFTP_ATTR_SUBSECOND_TIMES', - 0x00000200 => 'NET_SFTP_ATTR_BITS', // SFTPv5+ - 0x00000400 => 'NET_SFTP_ATTR_ALLOCATION_SIZE', // SFTPv6+ - 0x00000800 => 'NET_SFTP_ATTR_TEXT_HINT', - 0x00001000 => 'NET_SFTP_ATTR_MIME_TYPE', - 0x00002000 => 'NET_SFTP_ATTR_LINK_COUNT', - 0x00004000 => 'NET_SFTP_ATTR_UNTRANSLATED_NAME', - 0x00008000 => 'NET_SFTP_ATTR_CTIME', - // 0x80000000 will yield a floating point on 32-bit systems and converting floating points to integers - // yields inconsistent behavior depending on how php is compiled. so we left shift -1 (which, in - // two's compliment, consists of all 1 bits) by 31. on 64-bit systems this'll yield 0xFFFFFFFF80000000. - // that's not a problem, however, and 'anded' and a 32-bit number, as all the leading 1 bits are ignored. - (PHP_INT_SIZE == 4 ? -1 : 0xFFFFFFFF) => 'NET_SFTP_ATTR_EXTENDED' - ]; - // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3 - // the flag definitions change somewhat in SFTPv5+. if SFTPv5+ support is added to this library, maybe name - // the array for that $this->open5_flags and similarly alter the constant names. - $this->open_flags = [ - 0x00000001 => 'NET_SFTP_OPEN_READ', - 0x00000002 => 'NET_SFTP_OPEN_WRITE', - 0x00000004 => 'NET_SFTP_OPEN_APPEND', - 0x00000008 => 'NET_SFTP_OPEN_CREATE', - 0x00000010 => 'NET_SFTP_OPEN_TRUNCATE', - 0x00000020 => 'NET_SFTP_OPEN_EXCL', - 0x00000040 => 'NET_SFTP_OPEN_TEXT' // defined in SFTPv4 - ]; - // SFTPv5+ changed the flags up: - // https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-8.1.1.3 - $this->open_flags5 = [ - // when SSH_FXF_ACCESS_DISPOSITION is a 3 bit field that controls how the file is opened - 0x00000000 => 'NET_SFTP_OPEN_CREATE_NEW', - 0x00000001 => 'NET_SFTP_OPEN_CREATE_TRUNCATE', - 0x00000002 => 'NET_SFTP_OPEN_OPEN_EXISTING', - 0x00000003 => 'NET_SFTP_OPEN_OPEN_OR_CREATE', - 0x00000004 => 'NET_SFTP_OPEN_TRUNCATE_EXISTING', - // the rest of the flags are not supported - 0x00000008 => 'NET_SFTP_OPEN_APPEND_DATA', // "the offset field of SS_FXP_WRITE requests is ignored" - 0x00000010 => 'NET_SFTP_OPEN_APPEND_DATA_ATOMIC', - 0x00000020 => 'NET_SFTP_OPEN_TEXT_MODE', - 0x00000040 => 'NET_SFTP_OPEN_BLOCK_READ', - 0x00000080 => 'NET_SFTP_OPEN_BLOCK_WRITE', - 0x00000100 => 'NET_SFTP_OPEN_BLOCK_DELETE', - 0x00000200 => 'NET_SFTP_OPEN_BLOCK_ADVISORY', - 0x00000400 => 'NET_SFTP_OPEN_NOFOLLOW', - 0x00000800 => 'NET_SFTP_OPEN_DELETE_ON_CLOSE', - 0x00001000 => 'NET_SFTP_OPEN_ACCESS_AUDIT_ALARM_INFO', - 0x00002000 => 'NET_SFTP_OPEN_ACCESS_BACKUP', - 0x00004000 => 'NET_SFTP_OPEN_BACKUP_STREAM', - 0x00008000 => 'NET_SFTP_OPEN_OVERRIDE_OWNER', - ]; - // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2 - // see \phpseclib3\Net\SFTP::_parseLongname() for an explanation - $this->file_types = [ - 1 => 'NET_SFTP_TYPE_REGULAR', - 2 => 'NET_SFTP_TYPE_DIRECTORY', - 3 => 'NET_SFTP_TYPE_SYMLINK', - 4 => 'NET_SFTP_TYPE_SPECIAL', - 5 => 'NET_SFTP_TYPE_UNKNOWN', - // the following types were first defined for use in SFTPv5+ - // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2 - 6 => 'NET_SFTP_TYPE_SOCKET', - 7 => 'NET_SFTP_TYPE_CHAR_DEVICE', - 8 => 'NET_SFTP_TYPE_BLOCK_DEVICE', - 9 => 'NET_SFTP_TYPE_FIFO' - ]; - $this->define_array( - $this->packet_types, - $this->status_codes, - $this->attributes, - $this->open_flags, - $this->open_flags5, - $this->file_types - ); + if (empty(self::$packet_types)) { + self::$packet_types = [ + 1 => 'NET_SFTP_INIT', + 2 => 'NET_SFTP_VERSION', + 3 => 'NET_SFTP_OPEN', + 4 => 'NET_SFTP_CLOSE', + 5 => 'NET_SFTP_READ', + 6 => 'NET_SFTP_WRITE', + 7 => 'NET_SFTP_LSTAT', + 9 => 'NET_SFTP_SETSTAT', + 10 => 'NET_SFTP_FSETSTAT', + 11 => 'NET_SFTP_OPENDIR', + 12 => 'NET_SFTP_READDIR', + 13 => 'NET_SFTP_REMOVE', + 14 => 'NET_SFTP_MKDIR', + 15 => 'NET_SFTP_RMDIR', + 16 => 'NET_SFTP_REALPATH', + 17 => 'NET_SFTP_STAT', + 18 => 'NET_SFTP_RENAME', + 19 => 'NET_SFTP_READLINK', + 20 => 'NET_SFTP_SYMLINK', + 21 => 'NET_SFTP_LINK', + + 101 => 'NET_SFTP_STATUS', + 102 => 'NET_SFTP_HANDLE', + 103 => 'NET_SFTP_DATA', + 104 => 'NET_SFTP_NAME', + 105 => 'NET_SFTP_ATTRS', + + 200 => 'NET_SFTP_EXTENDED' + ]; + self::$status_codes = [ + 0 => 'NET_SFTP_STATUS_OK', + 1 => 'NET_SFTP_STATUS_EOF', + 2 => 'NET_SFTP_STATUS_NO_SUCH_FILE', + 3 => 'NET_SFTP_STATUS_PERMISSION_DENIED', + 4 => 'NET_SFTP_STATUS_FAILURE', + 5 => 'NET_SFTP_STATUS_BAD_MESSAGE', + 6 => 'NET_SFTP_STATUS_NO_CONNECTION', + 7 => 'NET_SFTP_STATUS_CONNECTION_LOST', + 8 => 'NET_SFTP_STATUS_OP_UNSUPPORTED', + 9 => 'NET_SFTP_STATUS_INVALID_HANDLE', + 10 => 'NET_SFTP_STATUS_NO_SUCH_PATH', + 11 => 'NET_SFTP_STATUS_FILE_ALREADY_EXISTS', + 12 => 'NET_SFTP_STATUS_WRITE_PROTECT', + 13 => 'NET_SFTP_STATUS_NO_MEDIA', + 14 => 'NET_SFTP_STATUS_NO_SPACE_ON_FILESYSTEM', + 15 => 'NET_SFTP_STATUS_QUOTA_EXCEEDED', + 16 => 'NET_SFTP_STATUS_UNKNOWN_PRINCIPAL', + 17 => 'NET_SFTP_STATUS_LOCK_CONFLICT', + 18 => 'NET_SFTP_STATUS_DIR_NOT_EMPTY', + 19 => 'NET_SFTP_STATUS_NOT_A_DIRECTORY', + 20 => 'NET_SFTP_STATUS_INVALID_FILENAME', + 21 => 'NET_SFTP_STATUS_LINK_LOOP', + 22 => 'NET_SFTP_STATUS_CANNOT_DELETE', + 23 => 'NET_SFTP_STATUS_INVALID_PARAMETER', + 24 => 'NET_SFTP_STATUS_FILE_IS_A_DIRECTORY', + 25 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_CONFLICT', + 26 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_REFUSED', + 27 => 'NET_SFTP_STATUS_DELETE_PENDING', + 28 => 'NET_SFTP_STATUS_FILE_CORRUPT', + 29 => 'NET_SFTP_STATUS_OWNER_INVALID', + 30 => 'NET_SFTP_STATUS_GROUP_INVALID', + 31 => 'NET_SFTP_STATUS_NO_MATCHING_BYTE_RANGE_LOCK' + ]; + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1 + // the order, in this case, matters quite a lot - see \phpseclib3\Net\SFTP::_parseAttributes() to understand why + self::$attributes = [ + 0x00000001 => 'NET_SFTP_ATTR_SIZE', + 0x00000002 => 'NET_SFTP_ATTR_UIDGID', // defined in SFTPv3, removed in SFTPv4+ + 0x00000080 => 'NET_SFTP_ATTR_OWNERGROUP', // defined in SFTPv4+ + 0x00000004 => 'NET_SFTP_ATTR_PERMISSIONS', + 0x00000008 => 'NET_SFTP_ATTR_ACCESSTIME', + 0x00000010 => 'NET_SFTP_ATTR_CREATETIME', // SFTPv4+ + 0x00000020 => 'NET_SFTP_ATTR_MODIFYTIME', + 0x00000040 => 'NET_SFTP_ATTR_ACL', + 0x00000100 => 'NET_SFTP_ATTR_SUBSECOND_TIMES', + 0x00000200 => 'NET_SFTP_ATTR_BITS', // SFTPv5+ + 0x00000400 => 'NET_SFTP_ATTR_ALLOCATION_SIZE', // SFTPv6+ + 0x00000800 => 'NET_SFTP_ATTR_TEXT_HINT', + 0x00001000 => 'NET_SFTP_ATTR_MIME_TYPE', + 0x00002000 => 'NET_SFTP_ATTR_LINK_COUNT', + 0x00004000 => 'NET_SFTP_ATTR_UNTRANSLATED_NAME', + 0x00008000 => 'NET_SFTP_ATTR_CTIME', + // 0x80000000 will yield a floating point on 32-bit systems and converting floating points to integers + // yields inconsistent behavior depending on how php is compiled. so we left shift -1 (which, in + // two's compliment, consists of all 1 bits) by 31. on 64-bit systems this'll yield 0xFFFFFFFF80000000. + // that's not a problem, however, and 'anded' and a 32-bit number, as all the leading 1 bits are ignored. + (PHP_INT_SIZE == 4 ? (-1 << 31) : 0x80000000) => 'NET_SFTP_ATTR_EXTENDED' + ]; + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3 + // the flag definitions change somewhat in SFTPv5+. if SFTPv5+ support is added to this library, maybe name + // the array for that $this->open5_flags and similarly alter the constant names. + self::$open_flags = [ + 0x00000001 => 'NET_SFTP_OPEN_READ', + 0x00000002 => 'NET_SFTP_OPEN_WRITE', + 0x00000004 => 'NET_SFTP_OPEN_APPEND', + 0x00000008 => 'NET_SFTP_OPEN_CREATE', + 0x00000010 => 'NET_SFTP_OPEN_TRUNCATE', + 0x00000020 => 'NET_SFTP_OPEN_EXCL', + 0x00000040 => 'NET_SFTP_OPEN_TEXT' // defined in SFTPv4 + ]; + // SFTPv5+ changed the flags up: + // https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-8.1.1.3 + self::$open_flags5 = [ + // when SSH_FXF_ACCESS_DISPOSITION is a 3 bit field that controls how the file is opened + 0x00000000 => 'NET_SFTP_OPEN_CREATE_NEW', + 0x00000001 => 'NET_SFTP_OPEN_CREATE_TRUNCATE', + 0x00000002 => 'NET_SFTP_OPEN_OPEN_EXISTING', + 0x00000003 => 'NET_SFTP_OPEN_OPEN_OR_CREATE', + 0x00000004 => 'NET_SFTP_OPEN_TRUNCATE_EXISTING', + // the rest of the flags are not supported + 0x00000008 => 'NET_SFTP_OPEN_APPEND_DATA', // "the offset field of SS_FXP_WRITE requests is ignored" + 0x00000010 => 'NET_SFTP_OPEN_APPEND_DATA_ATOMIC', + 0x00000020 => 'NET_SFTP_OPEN_TEXT_MODE', + 0x00000040 => 'NET_SFTP_OPEN_BLOCK_READ', + 0x00000080 => 'NET_SFTP_OPEN_BLOCK_WRITE', + 0x00000100 => 'NET_SFTP_OPEN_BLOCK_DELETE', + 0x00000200 => 'NET_SFTP_OPEN_BLOCK_ADVISORY', + 0x00000400 => 'NET_SFTP_OPEN_NOFOLLOW', + 0x00000800 => 'NET_SFTP_OPEN_DELETE_ON_CLOSE', + 0x00001000 => 'NET_SFTP_OPEN_ACCESS_AUDIT_ALARM_INFO', + 0x00002000 => 'NET_SFTP_OPEN_ACCESS_BACKUP', + 0x00004000 => 'NET_SFTP_OPEN_BACKUP_STREAM', + 0x00008000 => 'NET_SFTP_OPEN_OVERRIDE_OWNER', + ]; + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2 + // see \phpseclib3\Net\SFTP::_parseLongname() for an explanation + self::$file_types = [ + 1 => 'NET_SFTP_TYPE_REGULAR', + 2 => 'NET_SFTP_TYPE_DIRECTORY', + 3 => 'NET_SFTP_TYPE_SYMLINK', + 4 => 'NET_SFTP_TYPE_SPECIAL', + 5 => 'NET_SFTP_TYPE_UNKNOWN', + // the following types were first defined for use in SFTPv5+ + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2 + 6 => 'NET_SFTP_TYPE_SOCKET', + 7 => 'NET_SFTP_TYPE_CHAR_DEVICE', + 8 => 'NET_SFTP_TYPE_BLOCK_DEVICE', + 9 => 'NET_SFTP_TYPE_FIFO' + ]; + self::define_array( + self::$packet_types, + self::$status_codes, + self::$attributes, + self::$open_flags, + self::$open_flags5, + self::$file_types + ); + } if (!defined('NET_SFTP_QUEUE_SIZE')) { define('NET_SFTP_QUEUE_SIZE', 32); @@ -543,22 +547,7 @@ private function precheck() */ private function partial_init_sftp_connection() { - $this->window_size_server_to_client[self::CHANNEL] = $this->window_size; - - $packet = Strings::packSSH2( - 'CsN3', - NET_SSH2_MSG_CHANNEL_OPEN, - 'session', - self::CHANNEL, - $this->window_size, - 0x4000 - ); - - $this->send_binary_packet($packet); - - $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_OPEN; - - $response = $this->get_channel_packet(self::CHANNEL, true); + $response = $this->open_channel(self::CHANNEL, true); if ($response === true && $this->isTimeout()) { return false; } @@ -815,7 +804,7 @@ private function logError($response, $status = -1) list($status) = Strings::unpackSSH2('N', $response); } - $error = $this->status_codes[$status]; + $error = self::$status_codes[$status]; if ($this->version > 2) { list($message) = Strings::unpackSSH2('s', $response); @@ -2138,10 +2127,10 @@ public function put($remote_file, $data, $mode = self::SOURCE_STRING, $start = - if ($start >= 0) { $offset = $start; - } elseif ($mode & self::RESUME) { + } elseif ($mode & (self::RESUME | self::RESUME_START)) { // if NET_SFTP_OPEN_APPEND worked as it should _size() wouldn't need to be called - $size = $this->stat($remote_file)['size']; - $offset = $size !== false ? $size : 0; + $stat = $this->stat($remote_file); + $offset = $stat !== false && $stat['size'] ? $stat['size'] : 0; } else { $offset = 0; if ($this->version >= 5) { @@ -2210,6 +2199,9 @@ public function put($remote_file, $data, $mode = self::SOURCE_STRING, $start = - if ($local_start >= 0) { fseek($fp, $local_start); $size -= $local_start; + } elseif ($mode & self::RESUME) { + fseek($fp, $offset); + $size -= $offset; } } elseif ($dataCallback) { $size = 0; @@ -2497,14 +2489,6 @@ public function get($remote_file, $local_file = false, $offset = 0, $length = -1 } } - if ($length > 0 && $length <= $offset - $start) { - if ($local_file === false) { - $content = substr($content, 0, $length); - } else { - ftruncate($fp, $length + $res_offset); - } - } - if ($fclose_check) { fclose($fp); @@ -2840,15 +2824,37 @@ public function filegroup($path) return $this->get_stat_cache_prop($path, 'gid'); } + /** + * Recursively go through rawlist() output to get the total filesize + * + * @return int + */ + private static function recursiveFilesize(array $files) + { + $size = 0; + foreach ($files as $name => $file) { + if ($name == '.' || $name == '..') { + continue; + } + $size += is_array($file) ? + self::recursiveFilesize($file) : + $file->size; + } + return $size; + } + /** * Gets file size * * @param string $path + * @param bool $recursive * @return mixed */ - public function filesize($path) + public function filesize($path, $recursive = false) { - return $this->get_stat_cache_prop($path, 'size'); + return !$recursive || $this->filetype($path) != 'dir' ? + $this->get_stat_cache_prop($path, 'size') : + self::recursiveFilesize($this->rawlist($path, true)); } /** @@ -3041,7 +3047,7 @@ protected function parseAttributes(&$response) list($flags) = Strings::unpackSSH2('N', $response); } - foreach ($this->attributes as $key => $value) { + foreach (self::$attributes as $key => $value) { switch ($flags & $key) { case NET_SFTP_ATTR_UIDGID: if ($this->version > 3) { @@ -3272,7 +3278,7 @@ private function send_sftp_packet($type, $data, $request_id = 1) $stop = microtime(true); if (defined('NET_SFTP_LOGGING')) { - $packet_type = '-> ' . $this->packet_types[$type] . + $packet_type = '-> ' . self::$packet_types[$type] . ' (' . round($stop - $start, 4) . 's)'; $this->append_log($packet_type, $data); } @@ -3289,6 +3295,7 @@ protected function reset_connection($reason) $this->use_request_id = false; $this->pwd = false; $this->requestBuffer = []; + $this->partial_init = false; } /** @@ -3376,7 +3383,7 @@ private function get_sftp_packet($request_id = null) $packet = Strings::shift($this->packet_buffer, $length); if (defined('NET_SFTP_LOGGING')) { - $packet_type = '<- ' . $this->packet_types[$this->packet_type] . + $packet_type = '<- ' . self::$packet_types[$this->packet_type] . ' (' . round($stop - $start, 4) . 's)'; $this->append_log($packet_type, $packet); } @@ -3420,7 +3427,7 @@ private function append_log($message_number, $message) * * Returns a string if NET_SFTP_LOGGING == self::LOG_COMPLEX, an array if NET_SFTP_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SFTP_LOGGING') * - * @return array|string + * @return array|string|false */ public function getSFTPLog() { @@ -3439,7 +3446,7 @@ public function getSFTPLog() } /** - * Returns all errors + * Returns all errors on the SFTP layer * * @return array */ @@ -3449,7 +3456,7 @@ public function getSFTPErrors() } /** - * Returns the last error + * Returns the last error on the SFTP layer * * @return string */ diff --git a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php index 9a0133fdc..eee2e108d 100644 --- a/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php +++ b/lib/Google/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php @@ -553,7 +553,7 @@ class SSH2 * @var array * @access private */ - private $message_numbers = []; + private static $message_numbers = []; /** * Disconnection Message 'reason codes' defined in RFC4253 @@ -562,7 +562,7 @@ class SSH2 * @var array * @access private */ - private $disconnect_reasons = []; + private static $disconnect_reasons = []; /** * SSH_MSG_CHANNEL_OPEN_FAILURE 'reason codes', defined in RFC4254 @@ -571,7 +571,7 @@ class SSH2 * @var array * @access private */ - private $channel_open_failure_reasons = []; + private static $channel_open_failure_reasons = []; /** * Terminal Modes @@ -581,7 +581,7 @@ class SSH2 * @var array * @access private */ - private $terminal_modes = []; + private static $terminal_modes = []; /** * SSH_MSG_CHANNEL_EXTENDED_DATA's data_type_codes @@ -591,7 +591,7 @@ class SSH2 * @var array * @access private */ - private $channel_extended_data_type_codes = []; + private static $channel_extended_data_type_codes = []; /** * Send Sequence Number @@ -646,6 +646,14 @@ class SSH2 */ protected $channel_status = []; + /** + * The identifier of the interactive channel which was opened most recently + * + * @see self::getInteractiveChannelId() + * @var int + */ + private $channel_id_last_interactive = 0; + /** * Packet Size * @@ -837,20 +845,6 @@ class SSH2 */ private $request_pty = false; - /** - * Flag set while exec() is running when using enablePTY() - * - * @var bool - */ - private $in_request_pty_exec = false; - - /** - * Flag set after startSubsystem() is called - * - * @var bool - */ - private $in_subsystem; - /** * Contents of stdError * @@ -1093,10 +1087,37 @@ class SSH2 */ private $smartMFA = true; + /** + * How many channels are currently opened + * + * @var int + */ + private $channelCount = 0; + + /** + * Does the server support multiple channels? If not then error out + * when multiple channels are attempted to be opened + * + * @var bool + */ + private $errorOnMultipleChannels; + + /** + * Terrapin Countermeasure + * + * "During initial KEX, terminate the connection if any unexpected or out-of-sequence packet is received" + * -- https://github.com/openssh/openssh-portable/commit/1edb00c58f8a6875fad6a497aa2bacf37f9e6cd5 + * + * @var int + */ + private $extra_packets; + /** * Default Constructor. * * $host can either be a string, representing the host, or a stream resource. + * If $host is a stream resource then $port doesn't do anything, altho $timeout + * still will be used * * @param mixed $host * @param int $port @@ -1105,84 +1126,87 @@ class SSH2 */ public function __construct($host, $port = 22, $timeout = 10) { - $this->message_numbers = [ - 1 => 'NET_SSH2_MSG_DISCONNECT', - 2 => 'NET_SSH2_MSG_IGNORE', - 3 => 'NET_SSH2_MSG_UNIMPLEMENTED', - 4 => 'NET_SSH2_MSG_DEBUG', - 5 => 'NET_SSH2_MSG_SERVICE_REQUEST', - 6 => 'NET_SSH2_MSG_SERVICE_ACCEPT', - 20 => 'NET_SSH2_MSG_KEXINIT', - 21 => 'NET_SSH2_MSG_NEWKEYS', - 30 => 'NET_SSH2_MSG_KEXDH_INIT', - 31 => 'NET_SSH2_MSG_KEXDH_REPLY', - 50 => 'NET_SSH2_MSG_USERAUTH_REQUEST', - 51 => 'NET_SSH2_MSG_USERAUTH_FAILURE', - 52 => 'NET_SSH2_MSG_USERAUTH_SUCCESS', - 53 => 'NET_SSH2_MSG_USERAUTH_BANNER', - - 80 => 'NET_SSH2_MSG_GLOBAL_REQUEST', - 81 => 'NET_SSH2_MSG_REQUEST_SUCCESS', - 82 => 'NET_SSH2_MSG_REQUEST_FAILURE', - 90 => 'NET_SSH2_MSG_CHANNEL_OPEN', - 91 => 'NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION', - 92 => 'NET_SSH2_MSG_CHANNEL_OPEN_FAILURE', - 93 => 'NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST', - 94 => 'NET_SSH2_MSG_CHANNEL_DATA', - 95 => 'NET_SSH2_MSG_CHANNEL_EXTENDED_DATA', - 96 => 'NET_SSH2_MSG_CHANNEL_EOF', - 97 => 'NET_SSH2_MSG_CHANNEL_CLOSE', - 98 => 'NET_SSH2_MSG_CHANNEL_REQUEST', - 99 => 'NET_SSH2_MSG_CHANNEL_SUCCESS', - 100 => 'NET_SSH2_MSG_CHANNEL_FAILURE' - ]; - $this->disconnect_reasons = [ - 1 => 'NET_SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT', - 2 => 'NET_SSH2_DISCONNECT_PROTOCOL_ERROR', - 3 => 'NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED', - 4 => 'NET_SSH2_DISCONNECT_RESERVED', - 5 => 'NET_SSH2_DISCONNECT_MAC_ERROR', - 6 => 'NET_SSH2_DISCONNECT_COMPRESSION_ERROR', - 7 => 'NET_SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE', - 8 => 'NET_SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED', - 9 => 'NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE', - 10 => 'NET_SSH2_DISCONNECT_CONNECTION_LOST', - 11 => 'NET_SSH2_DISCONNECT_BY_APPLICATION', - 12 => 'NET_SSH2_DISCONNECT_TOO_MANY_CONNECTIONS', - 13 => 'NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER', - 14 => 'NET_SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE', - 15 => 'NET_SSH2_DISCONNECT_ILLEGAL_USER_NAME' - ]; - $this->channel_open_failure_reasons = [ - 1 => 'NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED' - ]; - $this->terminal_modes = [ - 0 => 'NET_SSH2_TTY_OP_END' - ]; - $this->channel_extended_data_type_codes = [ - 1 => 'NET_SSH2_EXTENDED_DATA_STDERR' - ]; + if (empty(self::$message_numbers)) { + self::$message_numbers = [ + 1 => 'NET_SSH2_MSG_DISCONNECT', + 2 => 'NET_SSH2_MSG_IGNORE', + 3 => 'NET_SSH2_MSG_UNIMPLEMENTED', + 4 => 'NET_SSH2_MSG_DEBUG', + 5 => 'NET_SSH2_MSG_SERVICE_REQUEST', + 6 => 'NET_SSH2_MSG_SERVICE_ACCEPT', + 7 => 'NET_SSH2_MSG_EXT_INFO', // RFC 8308 + 20 => 'NET_SSH2_MSG_KEXINIT', + 21 => 'NET_SSH2_MSG_NEWKEYS', + 30 => 'NET_SSH2_MSG_KEXDH_INIT', + 31 => 'NET_SSH2_MSG_KEXDH_REPLY', + 50 => 'NET_SSH2_MSG_USERAUTH_REQUEST', + 51 => 'NET_SSH2_MSG_USERAUTH_FAILURE', + 52 => 'NET_SSH2_MSG_USERAUTH_SUCCESS', + 53 => 'NET_SSH2_MSG_USERAUTH_BANNER', + + 80 => 'NET_SSH2_MSG_GLOBAL_REQUEST', + 81 => 'NET_SSH2_MSG_REQUEST_SUCCESS', + 82 => 'NET_SSH2_MSG_REQUEST_FAILURE', + 90 => 'NET_SSH2_MSG_CHANNEL_OPEN', + 91 => 'NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION', + 92 => 'NET_SSH2_MSG_CHANNEL_OPEN_FAILURE', + 93 => 'NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST', + 94 => 'NET_SSH2_MSG_CHANNEL_DATA', + 95 => 'NET_SSH2_MSG_CHANNEL_EXTENDED_DATA', + 96 => 'NET_SSH2_MSG_CHANNEL_EOF', + 97 => 'NET_SSH2_MSG_CHANNEL_CLOSE', + 98 => 'NET_SSH2_MSG_CHANNEL_REQUEST', + 99 => 'NET_SSH2_MSG_CHANNEL_SUCCESS', + 100 => 'NET_SSH2_MSG_CHANNEL_FAILURE' + ]; + self::$disconnect_reasons = [ + 1 => 'NET_SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT', + 2 => 'NET_SSH2_DISCONNECT_PROTOCOL_ERROR', + 3 => 'NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED', + 4 => 'NET_SSH2_DISCONNECT_RESERVED', + 5 => 'NET_SSH2_DISCONNECT_MAC_ERROR', + 6 => 'NET_SSH2_DISCONNECT_COMPRESSION_ERROR', + 7 => 'NET_SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE', + 8 => 'NET_SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED', + 9 => 'NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE', + 10 => 'NET_SSH2_DISCONNECT_CONNECTION_LOST', + 11 => 'NET_SSH2_DISCONNECT_BY_APPLICATION', + 12 => 'NET_SSH2_DISCONNECT_TOO_MANY_CONNECTIONS', + 13 => 'NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER', + 14 => 'NET_SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE', + 15 => 'NET_SSH2_DISCONNECT_ILLEGAL_USER_NAME' + ]; + self::$channel_open_failure_reasons = [ + 1 => 'NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED' + ]; + self::$terminal_modes = [ + 0 => 'NET_SSH2_TTY_OP_END' + ]; + self::$channel_extended_data_type_codes = [ + 1 => 'NET_SSH2_EXTENDED_DATA_STDERR' + ]; - $this->define_array( - $this->message_numbers, - $this->disconnect_reasons, - $this->channel_open_failure_reasons, - $this->terminal_modes, - $this->channel_extended_data_type_codes, - [60 => 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'], - [60 => 'NET_SSH2_MSG_USERAUTH_PK_OK'], - [60 => 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST', - 61 => 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'], - // RFC 4419 - diffie-hellman-group-exchange-sha{1,256} - [30 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST_OLD', - 31 => 'NET_SSH2_MSG_KEXDH_GEX_GROUP', - 32 => 'NET_SSH2_MSG_KEXDH_GEX_INIT', - 33 => 'NET_SSH2_MSG_KEXDH_GEX_REPLY', - 34 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'], - // RFC 5656 - Elliptic Curves (for curve25519-sha256@libssh.org) - [30 => 'NET_SSH2_MSG_KEX_ECDH_INIT', - 31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY'] - ); + self::define_array( + self::$message_numbers, + self::$disconnect_reasons, + self::$channel_open_failure_reasons, + self::$terminal_modes, + self::$channel_extended_data_type_codes, + [60 => 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'], + [60 => 'NET_SSH2_MSG_USERAUTH_PK_OK'], + [60 => 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST', + 61 => 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'], + // RFC 4419 - diffie-hellman-group-exchange-sha{1,256} + [30 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST_OLD', + 31 => 'NET_SSH2_MSG_KEXDH_GEX_GROUP', + 32 => 'NET_SSH2_MSG_KEXDH_GEX_INIT', + 33 => 'NET_SSH2_MSG_KEXDH_GEX_REPLY', + 34 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'], + // RFC 5656 - Elliptic Curves (for curve25519-sha256@libssh.org) + [30 => 'NET_SSH2_MSG_KEX_ECDH_INIT', + 31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY'] + ); + } /** * Typehint is required due to a bug in Psalm: https://github.com/vimeo/psalm/issues/7508 @@ -1192,6 +1216,8 @@ public function __construct($host, $port = 22, $timeout = 10) ? \WeakReference::create($this) : $this; + $this->timeout = $timeout; + if (is_resource($host)) { $this->fsock = $host; return; @@ -1200,7 +1226,6 @@ public function __construct($host, $port = 22, $timeout = 10) if (Strings::is_stringable($host)) { $this->host = $host; $this->port = $port; - $this->timeout = $timeout; } } @@ -1269,6 +1294,32 @@ public function sendKEXINITLast() $this->send_kex_first = false; } + /** + * stream_select wrapper + * + * Quoting https://stackoverflow.com/a/14262151/569976, + * "The general approach to `EINTR` is to simply handle the error and retry the operation again" + * + * This wrapper does that loop + */ + private static function stream_select(&$read, &$write, &$except, $seconds, $microseconds = null) + { + $remaining = $seconds + $microseconds / 1000000; + $start = microtime(true); + while (true) { + $result = @stream_select($read, $write, $except, $seconds, $microseconds); + if ($result !== false) { + return $result; + } + $elapsed = microtime(true) - $start; + $seconds = (int) ($remaining - floor($elapsed)); + $microseconds = (int) (1000000 * ($remaining - $seconds)); + if ($elapsed >= $remaining) { + return false; + } + } + } + /** * Connect to an SSHv2 server * @@ -1333,7 +1384,7 @@ private function connect() $start = microtime(true); $sec = (int) floor($this->curTimeout); $usec = (int) (1000000 * ($this->curTimeout - $sec)); - if (@stream_select($read, $write, $except, $sec, $usec) === false) { + if (static::stream_select($read, $write, $except, $sec, $usec) === false) { throw new \RuntimeException('Connection timed out whilst receiving server identification string'); } $elapsed = microtime(true) - $start; @@ -1388,6 +1439,18 @@ private function connect() throw new UnableToConnectException("Cannot connect to SSH $matches[3] servers"); } + // Ubuntu's OpenSSH from 5.8 to 6.9 didn't work with multiple channels. see + // https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/1334916 for more info. + // https://lists.ubuntu.com/archives/oneiric-changes/2011-July/005772.html discusses + // when consolekit was incorporated. + // https://marc.info/?l=openssh-unix-dev&m=163409903417589&w=2 discusses some of the + // issues with how Ubuntu incorporated consolekit + $pattern = '#^SSH-2\.0-OpenSSH_([\d.]+)[^ ]* Ubuntu-.*$#'; + $match = preg_match($pattern, $this->server_identifier, $matches); + $match = $match && version_compare('5.8', $matches[1], '<='); + $match = $match && version_compare('6.9', $matches[1], '>='); + $this->errorOnMultipleChannels = $match; + if (!$this->send_id_string_first) { fputs($this->fsock, $this->identifier . "\r\n"); } @@ -1486,6 +1549,8 @@ private function key_exchange($kexinit_payload_server = false) $preferred['client_to_server']['comp'] : SSH2::getSupportedCompressionAlgorithms(); + $kex_algorithms = array_merge($kex_algorithms, ['ext-info-c', 'kex-strict-c-v00@openssh.com']); + // some SSH servers have buggy implementations of some of the above algorithms switch (true) { case $this->server_identifier == 'SSH-2.0-SSHD': @@ -1502,6 +1567,20 @@ private function key_exchange($kexinit_payload_server = false) ['hmac-sha1-96', 'hmac-md5-96'] )); } + break; + case substr($this->server_identifier, 0, 24) == 'SSH-2.0-TurboFTP_SERVER_': + if (!isset($preferred['server_to_client']['crypt'])) { + $s2c_encryption_algorithms = array_values(array_diff( + $s2c_encryption_algorithms, + ['aes128-gcm@openssh.com', 'aes256-gcm@openssh.com'] + )); + } + if (!isset($preferred['client_to_server']['crypt'])) { + $c2s_encryption_algorithms = array_values(array_diff( + $c2s_encryption_algorithms, + ['aes128-gcm@openssh.com', 'aes256-gcm@openssh.com'] + )); + } } $client_cookie = Random::string(16); @@ -1526,6 +1605,7 @@ private function key_exchange($kexinit_payload_server = false) if ($kexinit_payload_server === false) { $this->send_binary_packet($kexinit_payload_client); + $this->extra_packets = 0; $kexinit_payload_server = $this->get_binary_packet(); if ( @@ -1557,6 +1637,11 @@ private function key_exchange($kexinit_payload_server = false) $this->languages_server_to_client, $first_kex_packet_follows ) = Strings::unpackSSH2('L10C', $response); + if (in_array('kex-strict-s-v00@openssh.com', $this->kex_algorithms)) { + if ($this->session_id === false && $this->extra_packets) { + throw new \UnexpectedValueException('Possible Terrapin Attack detected'); + } + } $this->supported_private_key_algorithms = $this->server_host_key_algorithms; @@ -1815,6 +1900,10 @@ private function key_exchange($kexinit_payload_server = false) throw new \UnexpectedValueException('Expected SSH_MSG_NEWKEYS'); } + if (in_array('kex-strict-s-v00@openssh.com', $this->kex_algorithms)) { + $this->get_seq_no = $this->send_seq_no = 0; + } + $keyBytes = pack('Na*', strlen($keyBytes), $keyBytes); $this->encrypt = self::encryption_algorithm_to_crypt_instance($encrypt); @@ -2121,13 +2210,15 @@ private static function bad_algorithm_candidate($algorithm) * The $password parameter can be a plaintext password, a \phpseclib3\Crypt\RSA|EC|DSA object, a \phpseclib3\System\SSH\Agent object or an array * * @param string $username - * @param string|AsymmetricKey|array[]|Agent|null ...$args + * @param string|PrivateKey|array[]|Agent|null ...$args * @return bool * @see self::_login() */ public function login($username, ...$args) { - $this->auth[] = func_get_args(); + if (!$this->retry_connect) { + $this->auth[] = func_get_args(); + } // try logging with 'none' as an authentication method first since that's what // PuTTY does @@ -2146,7 +2237,7 @@ public function login($username, ...$args) * Login Helper * * @param string $username - * @param string ...$args + * @param string|PrivateKey|array[]|Agent|null ...$args * @return bool * @see self::_login_helper() */ @@ -2266,10 +2357,26 @@ private function login_helper($username, $password = null) return $this->login_helper($username, $password); } $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); - throw new ConnectionClosedException('Connection closed by server'); + throw $e; + } + + list($type) = Strings::unpackSSH2('C', $response); + + if ($type == NET_SSH2_MSG_EXT_INFO) { + list($nr_extensions) = Strings::unpackSSH2('N', $response); + for ($i = 0; $i < $nr_extensions; $i++) { + list($extension_name, $extension_value) = Strings::unpackSSH2('ss', $response); + if ($extension_name == 'server-sig-algs') { + $this->supported_private_key_algorithms = explode(',', $extension_value); + } + } + + $response = $this->get_binary_packet(); + list($type) = Strings::unpackSSH2('C', $response); } - list($type, $service) = Strings::unpackSSH2('Cs', $response); + list($service) = Strings::unpackSSH2('s', $response); + if ($type != NET_SSH2_MSG_SERVICE_ACCEPT || $service != 'ssh-userauth') { $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); throw new \UnexpectedValueException('Expected SSH_MSG_SERVICE_ACCEPT'); @@ -2545,7 +2652,7 @@ private function privatekey_login($username, PrivateKey $privatekey) $privatekey = $privatekey->withPadding(RSA::SIGNATURE_PKCS1); $algos = ['rsa-sha2-256', 'rsa-sha2-512', 'ssh-rsa']; if (isset($this->preferred['hostkey'])) { - $algos = array_intersect($this->preferred['hostkey'], $algos); + $algos = array_intersect($algos, $this->preferred['hostkey']); } $algo = self::array_intersect_first($algos, $this->supported_private_key_algorithms); switch ($algo) { @@ -2729,32 +2836,11 @@ public function exec($command, callable $callback = null) return false; } - if ($this->in_request_pty_exec) { - throw new \RuntimeException('If you want to run multiple exec()\'s you will need to disable (and re-enable if appropriate) a PTY for each one.'); - } + //if ($this->isPTYOpen()) { + // throw new \RuntimeException('If you want to run multiple exec()\'s you will need to disable (and re-enable if appropriate) a PTY for each one.'); + //} - // RFC4254 defines the (client) window size as "bytes the other party can send before it must wait for the window to - // be adjusted". 0x7FFFFFFF is, at 2GB, the max size. technically, it should probably be decremented, but, - // honestly, if you're transferring more than 2GB, you probably shouldn't be using phpseclib, anyway. - // see http://tools.ietf.org/html/rfc4254#section-5.2 for more info - $this->window_size_server_to_client[self::CHANNEL_EXEC] = $this->window_size; - // 0x8000 is the maximum max packet size, per http://tools.ietf.org/html/rfc4253#section-6.1, although since PuTTy - // uses 0x4000, that's what will be used here, as well. - $packet_size = 0x4000; - - $packet = Strings::packSSH2( - 'CsN3', - NET_SSH2_MSG_CHANNEL_OPEN, - 'session', - self::CHANNEL_EXEC, - $this->window_size_server_to_client[self::CHANNEL_EXEC], - $packet_size - ); - $this->send_binary_packet($packet); - - $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_OPEN; - - $this->get_channel_packet(self::CHANNEL_EXEC); + $this->open_channel(self::CHANNEL_EXEC); if ($this->request_pty === true) { $terminal_modes = pack('C', NET_SSH2_TTY_OP_END); @@ -2779,8 +2865,6 @@ public function exec($command, callable $callback = null) $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); throw new \RuntimeException('Unable to request pseudo-terminal'); } - - $this->in_request_pty_exec = true; } // sending a pty-req SSH_MSG_CHANNEL_REQUEST message is unnecessary and, in fact, in most cases, slows things @@ -2810,7 +2894,8 @@ public function exec($command, callable $callback = null) $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_DATA; - if ($this->in_request_pty_exec) { + if ($this->request_pty === true) { + $this->channel_id_last_interactive = self::CHANNEL_EXEC; return true; } @@ -2836,37 +2921,80 @@ public function exec($command, callable $callback = null) } /** - * Creates an interactive shell + * How many channels are currently open? * - * @see self::read() - * @see self::write() + * @return int + */ + public function getOpenChannelCount() + { + return $this->channelCount; + } + + /** + * Opens a channel + * + * @param string $channel + * @param bool $skip_extended * @return bool - * @throws \UnexpectedValueException on receipt of unexpected packets - * @throws \RuntimeException on other errors */ - private function initShell() + protected function open_channel($channel, $skip_extended = false) { - if ($this->in_request_pty_exec === true) { - return true; + if (isset($this->channel_status[$channel]) && $this->channel_status[$channel] != NET_SSH2_MSG_CHANNEL_CLOSE) { + throw new \RuntimeException('Please close the channel (' . $channel . ') before trying to open it again'); } - $this->window_size_server_to_client[self::CHANNEL_SHELL] = $this->window_size; + $this->channelCount++; + + if ($this->channelCount > 1 && $this->errorOnMultipleChannels) { + throw new \RuntimeException("Ubuntu's OpenSSH from 5.8 to 6.9 doesn't work with multiple channels"); + } + + // RFC4254 defines the (client) window size as "bytes the other party can send before it must wait for the window to + // be adjusted". 0x7FFFFFFF is, at 2GB, the max size. technically, it should probably be decremented, but, + // honestly, if you're transferring more than 2GB, you probably shouldn't be using phpseclib, anyway. + // see http://tools.ietf.org/html/rfc4254#section-5.2 for more info + $this->window_size_server_to_client[$channel] = $this->window_size; + // 0x8000 is the maximum max packet size, per http://tools.ietf.org/html/rfc4253#section-6.1, although since PuTTy + // uses 0x4000, that's what will be used here, as well. $packet_size = 0x4000; $packet = Strings::packSSH2( 'CsN3', NET_SSH2_MSG_CHANNEL_OPEN, 'session', - self::CHANNEL_SHELL, - $this->window_size_server_to_client[self::CHANNEL_SHELL], + $channel, + $this->window_size_server_to_client[$channel], $packet_size ); $this->send_binary_packet($packet); - $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_OPEN; + $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_OPEN; + + return $this->get_channel_packet($channel, $skip_extended); + } + + /** + * Creates an interactive shell + * + * Returns bool(true) if the shell was opened. + * Returns bool(false) if the shell was already open. + * + * @see self::isShellOpen() + * @see self::read() + * @see self::write() + * @return bool + * @throws InsufficientSetupException if not authenticated + * @throws \UnexpectedValueException on receipt of unexpected packets + * @throws \RuntimeException on other errors + */ + public function openShell() + { + if (!$this->isAuthenticated()) { + throw new InsufficientSetupException('Operation disallowed prior to login()'); + } - $this->get_channel_packet(self::CHANNEL_SHELL); + $this->open_channel(self::CHANNEL_SHELL); $terminal_modes = pack('C', NET_SSH2_TTY_OP_END); $packet = Strings::packSSH2( @@ -2907,14 +3035,18 @@ private function initShell() $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_DATA; + $this->channel_id_last_interactive = self::CHANNEL_SHELL; + $this->bitmap |= self::MASK_SHELL; return true; } /** - * Return the channel to be used with read() / write() - * + * Return the channel to be used with read(), write(), and reset(), if none were specified + * @deprecated for lack of transparency in intended channel target, to be potentially replaced + * with method which guarantees open-ness of all yielded channels and throws + * error for multiple open channels * @see self::read() * @see self::write() * @return int @@ -2922,15 +3054,26 @@ private function initShell() private function get_interactive_channel() { switch (true) { - case $this->in_subsystem: + case $this->is_channel_status_data(self::CHANNEL_SUBSYSTEM): return self::CHANNEL_SUBSYSTEM; - case $this->in_request_pty_exec: + case $this->is_channel_status_data(self::CHANNEL_EXEC): return self::CHANNEL_EXEC; default: return self::CHANNEL_SHELL; } } + /** + * Indicates the DATA status on the given channel + * + * @param int $channel The channel number to evaluate + * @return bool + */ + private function is_channel_status_data($channel) + { + return isset($this->channel_status[$channel]) && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA; + } + /** * Return an available open channel * @@ -2987,26 +3130,41 @@ public function requestAgentForwarding() * Returns when there's a match for $expect, which can take the form of a string literal or, * if $mode == self::READ_REGEX, a regular expression. * + * If not specifying a channel, an open interactive channel will be selected, or, if there are + * no open channels, an interactive shell will be created. If there are multiple open + * interactive channels, a legacy behavior will apply in which channel selection prioritizes + * an active subsystem, the exec pty, and, lastly, the shell. If using multiple interactive + * channels, callers are discouraged from relying on this legacy behavior and should specify + * the intended channel. + * * @see self::write() * @param string $expect - * @param int $mode + * @param int $mode One of the self::READ_* constants + * @param int|null $channel Channel id returned by self::getInteractiveChannelId() * @return string|bool|null * @throws \RuntimeException on connection error + * @throws InsufficientSetupException on unexpected channel status, possibly due to closure */ - public function read($expect = '', $mode = self::READ_SIMPLE) + public function read($expect = '', $mode = self::READ_SIMPLE, $channel = null) { - $this->curTimeout = $this->timeout; - $this->is_timeout = false; - if (!$this->isAuthenticated()) { throw new InsufficientSetupException('Operation disallowed prior to login()'); } - if (!($this->bitmap & self::MASK_SHELL) && !$this->initShell()) { - throw new \RuntimeException('Unable to initiate an interactive shell session'); + $this->curTimeout = $this->timeout; + $this->is_timeout = false; + + if ($channel === null) { + $channel = $this->get_interactive_channel(); } - $channel = $this->get_interactive_channel(); + if (!$this->is_channel_status_data($channel) && empty($this->channel_buffers[$channel])) { + if ($channel != self::CHANNEL_SHELL) { + throw new InsufficientSetupException('Data is not available on channel'); + } elseif (!$this->openShell()) { + throw new \RuntimeException('Unable to initiate an interactive shell session'); + } + } if ($mode == self::READ_NEXT) { return $this->get_channel_packet($channel); @@ -3024,7 +3182,6 @@ public function read($expect = '', $mode = self::READ_SIMPLE) } $response = $this->get_channel_packet($channel); if ($response === true) { - $this->in_request_pty_exec = false; return Strings::shift($this->interactiveBuffer, strlen($this->interactiveBuffer)); } @@ -3035,22 +3192,39 @@ public function read($expect = '', $mode = self::READ_SIMPLE) /** * Inputs a command into an interactive shell. * + * If not specifying a channel, an open interactive channel will be selected, or, if there are + * no open channels, an interactive shell will be created. If there are multiple open + * interactive channels, a legacy behavior will apply in which channel selection prioritizes + * an active subsystem, the exec pty, and, lastly, the shell. If using multiple interactive + * channels, callers are discouraged from relying on this legacy behavior and should specify + * the intended channel. + * * @see SSH2::read() * @param string $cmd + * @param int|null $channel Channel id returned by self::getInteractiveChannelId() * @return void * @throws \RuntimeException on connection error + * @throws InsufficientSetupException on unexpected channel status, possibly due to closure */ - public function write($cmd) + public function write($cmd, $channel = null) { if (!$this->isAuthenticated()) { throw new InsufficientSetupException('Operation disallowed prior to login()'); } - if (!($this->bitmap & self::MASK_SHELL) && !$this->initShell()) { - throw new \RuntimeException('Unable to initiate an interactive shell session'); + if ($channel === null) { + $channel = $this->get_interactive_channel(); + } + + if (!$this->is_channel_status_data($channel)) { + if ($channel != self::CHANNEL_SHELL) { + throw new InsufficientSetupException('Data is not available on channel'); + } elseif (!$this->openShell()) { + throw new \RuntimeException('Unable to initiate an interactive shell session'); + } } - $this->send_channel_packet($this->get_interactive_channel(), $cmd); + $this->send_channel_packet($channel, $cmd); } /** @@ -3068,22 +3242,7 @@ public function write($cmd) */ public function startSubsystem($subsystem) { - $this->window_size_server_to_client[self::CHANNEL_SUBSYSTEM] = $this->window_size; - - $packet = Strings::packSSH2( - 'CsN3', - NET_SSH2_MSG_CHANNEL_OPEN, - 'session', - self::CHANNEL_SUBSYSTEM, - $this->window_size, - 0x4000 - ); - - $this->send_binary_packet($packet); - - $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_OPEN; - - $this->get_channel_packet(self::CHANNEL_SUBSYSTEM); + $this->open_channel(self::CHANNEL_SUBSYSTEM); $packet = Strings::packSSH2( 'CNsCs', @@ -3103,8 +3262,7 @@ public function startSubsystem($subsystem) $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_DATA; - $this->bitmap |= self::MASK_SHELL; - $this->in_subsystem = true; + $this->channel_id_last_interactive = self::CHANNEL_SUBSYSTEM; return true; } @@ -3117,8 +3275,9 @@ public function startSubsystem($subsystem) */ public function stopSubsystem() { - $this->in_subsystem = false; - $this->close_channel(self::CHANNEL_SUBSYSTEM); + if ($this->isInteractiveChannelOpen(self::CHANNEL_SUBSYSTEM)) { + $this->close_channel(self::CHANNEL_SUBSYSTEM); + } return true; } @@ -3127,10 +3286,23 @@ public function stopSubsystem() * * If read() timed out you might want to just close the channel and have it auto-restart on the next read() call * + * If not specifying a channel, an open interactive channel will be selected. If there are + * multiple open interactive channels, a legacy behavior will apply in which channel selection + * prioritizes an active subsystem, the exec pty, and, lastly, the shell. If using multiple + * interactive channels, callers are discouraged from relying on this legacy behavior and + * should specify the intended channel. + * + * @param int|null $channel Channel id returned by self::getInteractiveChannelId() + * @return void */ - public function reset() + public function reset($channel = null) { - $this->close_channel($this->get_interactive_channel()); + if ($channel === null) { + $channel = $this->get_interactive_channel(); + } + if ($this->isInteractiveChannelOpen($channel)) { + $this->close_channel($channel); + } } /** @@ -3172,11 +3344,38 @@ public function __destruct() /** * Is the connection still active? * + * $level has 3x possible values: + * 0 (default): phpseclib takes a passive approach to see if the connection is still active by calling feof() + * on the socket + * 1: phpseclib takes an active approach to see if the connection is still active by sending an SSH_MSG_IGNORE + * packet that doesn't require a response + * 2: phpseclib takes an active approach to see if the connection is still active by sending an SSH_MSG_CHANNEL_OPEN + * packet and imediately trying to close that channel. some routers, in particular, however, will only let you + * open one channel, so this approach could yield false positives + * + * @param int $level * @return bool */ - public function isConnected() + public function isConnected($level = 0) { - return (bool) ($this->bitmap & self::MASK_CONNECTED); + if (!is_int($level) || $level < 0 || $level > 2) { + throw new \InvalidArgumentException('$level must be 0, 1 or 2'); + } + + if ($level == 0) { + return ($this->bitmap & self::MASK_CONNECTED) && is_resource($this->fsock) && !feof($this->fsock); + } + try { + if ($level == 1) { + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); + } else { + $this->open_channel(self::CHANNEL_KEEP_ALIVE); + $this->close_channel(self::CHANNEL_KEEP_ALIVE); + } + return true; + } catch (\Exception $e) { + return false; + } } /** @@ -3189,6 +3388,49 @@ public function isAuthenticated() return (bool) ($this->bitmap & self::MASK_LOGIN); } + /** + * Is the interactive shell active? + * + * @return bool + */ + public function isShellOpen() + { + return $this->isInteractiveChannelOpen(self::CHANNEL_SHELL); + } + + /** + * Is the exec pty active? + * + * @return bool + */ + public function isPTYOpen() + { + return $this->isInteractiveChannelOpen(self::CHANNEL_EXEC); + } + + /** + * Is the given interactive channel active? + * + * @param int $channel Channel id returned by self::getInteractiveChannelId() + * @return bool + */ + public function isInteractiveChannelOpen($channel) + { + return $this->isAuthenticated() && $this->is_channel_status_data($channel); + } + + /** + * Returns a channel identifier, presently of the last interactive channel opened, regardless of current status. + * Returns 0 if no interactive channel has been opened. + * + * @see self::isInteractiveChannelOpen() + * @return int + */ + public function getInteractiveChannelId() + { + return $this->channel_id_last_interactive; + } + /** * Pings a server connection, or tries to reconnect if the connection has gone down * @@ -3205,23 +3447,8 @@ public function ping() return false; } - $this->window_size_server_to_client[self::CHANNEL_KEEP_ALIVE] = $this->window_size; - $packet_size = 0x4000; - $packet = Strings::packSSH2( - 'CsN3', - NET_SSH2_MSG_CHANNEL_OPEN, - 'session', - self::CHANNEL_KEEP_ALIVE, - $this->window_size_server_to_client[self::CHANNEL_KEEP_ALIVE], - $packet_size - ); - try { - $this->send_binary_packet($packet); - - $this->channel_status[self::CHANNEL_KEEP_ALIVE] = NET_SSH2_MSG_CHANNEL_OPEN; - - $response = $this->get_channel_packet(self::CHANNEL_KEEP_ALIVE); + $this->open_channel(self::CHANNEL_KEEP_ALIVE); } catch (\RuntimeException $e) { return $this->reconnect(); } @@ -3261,6 +3488,8 @@ protected function reset_connection($reason) $this->session_id = false; $this->retry_connect = true; $this->get_seq_no = $this->send_seq_no = 0; + $this->channel_status = []; + $this->channel_id_last_interactive = 0; } /** @@ -3283,9 +3512,9 @@ private function get_binary_packet($skip_channel_filter = false) if (!$this->curTimeout) { if ($this->keepAlive <= 0) { - @stream_select($read, $write, $except, null); + static::stream_select($read, $write, $except, null); } else { - if (!@stream_select($read, $write, $except, $this->keepAlive)) { + if (!static::stream_select($read, $write, $except, $this->keepAlive)) { $this->send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); return $this->get_binary_packet(true); } @@ -3299,7 +3528,7 @@ private function get_binary_packet($skip_channel_filter = false) $start = microtime(true); if ($this->keepAlive > 0 && $this->keepAlive < $this->curTimeout) { - if (!@stream_select($read, $write, $except, $this->keepAlive)) { + if (!static::stream_select($read, $write, $except, $this->keepAlive)) { $this->send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); $elapsed = microtime(true) - $start; $this->curTimeout -= $elapsed; @@ -3313,7 +3542,7 @@ private function get_binary_packet($skip_channel_filter = false) $usec = (int) (1000000 * ($this->curTimeout - $sec)); // this can return a "stream_select(): unable to select [4]: Interrupted system call" error - if (!@stream_select($read, $write, $except, $sec, $usec)) { + if (!static::stream_select($read, $write, $except, $sec, $usec)) { $this->is_timeout = true; return true; } @@ -3332,6 +3561,11 @@ private function get_binary_packet($skip_channel_filter = false) } $start = microtime(true); + if ($this->curTimeout) { + $sec = (int) floor($this->curTimeout); + $usec = (int) (1000000 * ($this->curTimeout - $sec)); + stream_set_timeout($this->fsock, $sec, $usec); + } $raw = stream_get_contents($this->fsock, $this->decrypt_block_size); if (!strlen($raw)) { @@ -3504,7 +3738,7 @@ private function get_binary_packet($skip_channel_filter = false) if (defined('NET_SSH2_LOGGING')) { $current = microtime(true); - $message_number = isset($this->message_numbers[ord($payload[0])]) ? $this->message_numbers[ord($payload[0])] : 'UNKNOWN (' . ord($payload[0]) . ')'; + $message_number = isset(self::$message_numbers[ord($payload[0])]) ? self::$message_numbers[ord($payload[0])] : 'UNKNOWN (' . ord($payload[0]) . ')'; $message_number = '<- ' . $message_number . ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)'; $this->append_log($message_number, $payload); @@ -3586,13 +3820,15 @@ private function filter($payload, $skip_channel_filter) case NET_SSH2_MSG_DISCONNECT: Strings::shift($payload, 1); list($reason_code, $message) = Strings::unpackSSH2('Ns', $payload); - $this->errors[] = 'SSH_MSG_DISCONNECT: ' . $this->disconnect_reasons[$reason_code] . "\r\n$message"; + $this->errors[] = 'SSH_MSG_DISCONNECT: ' . self::$disconnect_reasons[$reason_code] . "\r\n$message"; $this->bitmap = 0; return false; case NET_SSH2_MSG_IGNORE: + $this->extra_packets++; $payload = $this->get_binary_packet($skip_channel_filter); break; case NET_SSH2_MSG_DEBUG: + $this->extra_packets++; Strings::shift($payload, 2); // second byte is "always_display" list($message) = Strings::unpackSSH2('s', $payload); $this->errors[] = "SSH_MSG_DEBUG: $message"; @@ -3601,6 +3837,7 @@ private function filter($payload, $skip_channel_filter) case NET_SSH2_MSG_UNIMPLEMENTED: return false; case NET_SSH2_MSG_KEXINIT: + // this is here for key re-exchanges after the initial key exchange if ($this->session_id !== false) { if (!$this->key_exchange($payload)) { $this->bitmap = 0; @@ -3773,9 +4010,8 @@ public function enablePTY() */ public function disablePTY() { - if ($this->in_request_pty_exec) { + if ($this->isPTYOpen()) { $this->close_channel(self::CHANNEL_EXEC); - $this->in_request_pty_exec = false; } $this->request_pty = false; } @@ -3801,6 +4037,7 @@ public function isPTYEnabled() * - if the connection times out * - if the channel status is CHANNEL_OPEN and the response was CHANNEL_OPEN_CONFIRMATION * - if the channel status is CHANNEL_REQUEST and the response was CHANNEL_SUCCESS + * - if the channel status is CHANNEL_CLOSE and the response was CHANNEL_CLOSE * * bool(false) is returned if: * @@ -3968,7 +4205,10 @@ protected function get_channel_packet($client_channel, $skip_extended = false) throw new \RuntimeException('Unable to fulfill channel request'); } case NET_SSH2_MSG_CHANNEL_CLOSE: - return $type == NET_SSH2_MSG_CHANNEL_CLOSE ? true : $this->get_channel_packet($client_channel, $skip_extended); + if ($client_channel == $channel && $type == NET_SSH2_MSG_CHANNEL_CLOSE) { + return true; + } + return $this->get_channel_packet($client_channel, $skip_extended); } } @@ -4003,14 +4243,15 @@ protected function get_channel_packet($client_channel, $skip_extended = false) case NET_SSH2_MSG_CHANNEL_CLOSE: $this->curTimeout = 5; - if ($this->bitmap & self::MASK_SHELL) { - $this->bitmap &= ~self::MASK_SHELL; - } + $this->close_channel_bitmap($channel); + if ($this->channel_status[$channel] != NET_SSH2_MSG_CHANNEL_EOF) { $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel])); } $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_CLOSE; + $this->channelCount--; + if ($client_channel == $channel) { return true; } @@ -4157,7 +4398,7 @@ protected function send_binary_packet($data, $logged = null) if (defined('NET_SSH2_LOGGING')) { $current = microtime(true); - $message_number = isset($this->message_numbers[ord($logged[0])]) ? $this->message_numbers[ord($logged[0])] : 'UNKNOWN (' . ord($logged[0]) . ')'; + $message_number = isset(self::$message_numbers[ord($logged[0])]) ? self::$message_numbers[ord($logged[0])] : 'UNKNOWN (' . ord($logged[0]) . ')'; $message_number = '-> ' . $message_number . ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)'; $this->append_log($message_number, $logged); @@ -4166,7 +4407,10 @@ protected function send_binary_packet($data, $logged = null) if (strlen($packet) != $sent) { $this->bitmap = 0; - throw new \RuntimeException("Only $sent of " . strlen($packet) . " bytes were sent"); + $message = $sent === false ? + 'Unable to write ' . strlen($packet) . ' bytes' : + "Only $sent of " . strlen($packet) . " bytes were sent"; + throw new \RuntimeException($message); } } @@ -4342,22 +4586,36 @@ private function close_channel($client_channel, $want_reply = false) } $this->channel_status[$client_channel] = NET_SSH2_MSG_CHANNEL_CLOSE; + $this->channelCount--; $this->curTimeout = 5; while (!is_bool($this->get_channel_packet($client_channel))) { } - if ($this->is_timeout) { - $this->disconnect(); - } - if ($want_reply) { $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel])); } - if ($this->bitmap & self::MASK_SHELL) { - $this->bitmap &= ~self::MASK_SHELL; + $this->close_channel_bitmap($client_channel); + } + + /** + * Maintains execution state bitmap in response to channel closure + * + * @param int $client_channel The channel number to maintain closure status of + * @return void + */ + private function close_channel_bitmap($client_channel) + { + switch ($client_channel) { + case self::CHANNEL_SHELL: + // Shell status has been maintained in the bitmap for backwards + // compatibility sake, but can be removed going forward + if ($this->bitmap & self::MASK_SHELL) { + $this->bitmap &= ~self::MASK_SHELL; + } + break; } } @@ -4395,7 +4653,7 @@ protected function disconnect_helper($reason) * @param mixed[] ...$args * @access protected */ - protected function define_array(...$args) + protected static function define_array(...$args) { foreach ($args as $arg) { foreach ($arg as $key => $value) { @@ -4501,7 +4759,9 @@ private static function array_intersect_first(array $array1, array $array2) } /** - * Returns all errors + * Returns all errors / debug messages on the SSH layer + * + * If you are looking for messages from the SFTP layer, please see SFTP::getSFTPErrors() * * @return string[] */ @@ -4511,7 +4771,9 @@ public function getErrors() } /** - * Returns the last error + * Returns the last error received on the SSH layer + * + * If you are looking for messages from the SFTP layer, please see SFTP::getLastSFTPError() * * @return string */ @@ -4800,6 +5062,14 @@ public function getAlgorithmsNegotiated() ]; } + /** + * Force multiple channels (even if phpseclib has decided to disable them) + */ + public function forceMultipleChannels() + { + $this->errorOnMultipleChannels = false; + } + /** * Allows you to set the terminal * diff --git a/lib/Google/vendor/psr/cache/src/CacheItemInterface.php b/lib/Google/vendor/psr/cache/src/CacheItemInterface.php index 5e736e382..893315e6e 100644 --- a/lib/Google/vendor/psr/cache/src/CacheItemInterface.php +++ b/lib/Google/vendor/psr/cache/src/CacheItemInterface.php @@ -86,7 +86,7 @@ public function set(mixed $value); * @return static * The called object. */ - public function expiresAt($expiration); + public function expiresAt(?\DateTimeInterface $expiration); /** * Sets the expiration time for this cache item. @@ -101,5 +101,5 @@ public function expiresAt($expiration); * @return static * The called object. */ - public function expiresAfter($time); + public function expiresAfter(int|\DateInterval|null $time); } diff --git a/lib/Google/vendor/psr/http-client/CHANGELOG.md b/lib/Google/vendor/psr/http-client/CHANGELOG.md index e2dc25f51..babba7c7b 100644 --- a/lib/Google/vendor/psr/http-client/CHANGELOG.md +++ b/lib/Google/vendor/psr/http-client/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file, in reverse chronological order by release. +## 1.0.3 + +Add `source` link in composer.json. No code changes. + +## 1.0.2 + +Allow PSR-7 (psr/http-message) 2.0. No code changes. + ## 1.0.1 Allow installation with PHP 8. No code changes. diff --git a/lib/Google/vendor/psr/http-client/composer.json b/lib/Google/vendor/psr/http-client/composer.json index e4cab2f3e..6fed350be 100644 --- a/lib/Google/vendor/psr/http-client/composer.json +++ b/lib/Google/vendor/psr/http-client/composer.json @@ -10,6 +10,9 @@ "homepage": "https://www.php-fig.org/" } ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, "require": { "php": "^7.0 || ^8.0", "psr/http-message": "^1.0 || ^2.0" diff --git a/lib/Google/vendor/psr/http-message/composer.json b/lib/Google/vendor/psr/http-message/composer.json index 56e8c0a6d..c66e5aba4 100644 --- a/lib/Google/vendor/psr/http-message/composer.json +++ b/lib/Google/vendor/psr/http-message/composer.json @@ -7,7 +7,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "require": { @@ -20,7 +20,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "2.0.x-dev" } } } diff --git a/lib/Google/vendor/psr/http-message/src/MessageInterface.php b/lib/Google/vendor/psr/http-message/src/MessageInterface.php index 8cdb4ed63..a83c98518 100644 --- a/lib/Google/vendor/psr/http-message/src/MessageInterface.php +++ b/lib/Google/vendor/psr/http-message/src/MessageInterface.php @@ -1,7 +1,5 @@ data[$offset]); } @@ -80,12 +82,13 @@ public function offsetExists(mixed $offset): bool * * @param array-key $offset The offset for which a value should be returned. * - * @return T the value stored at the offset, or null if the offset + * @return T|null the value stored at the offset, or null if the offset * does not exist. */ - public function offsetGet(mixed $offset): mixed + #[\ReturnTypeWillChange] // phpcs:ignore + public function offsetGet($offset) { - return $this->data[$offset]; + return $this->data[$offset] ?? null; } /** @@ -93,11 +96,12 @@ public function offsetGet(mixed $offset): mixed * * @link http://php.net/manual/en/arrayaccess.offsetset.php ArrayAccess::offsetSet() * - * @param array-key | null $offset The offset to set. If `null`, the value - * may be set at a numerically-indexed offset. + * @param array-key|null $offset The offset to set. If `null`, the value may be + * set at a numerically-indexed offset. * @param T $value The value to set at the given offset. */ - public function offsetSet(mixed $offset, mixed $value): void + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + public function offsetSet($offset, $value): void { if ($offset === null) { $this->data[] = $value; @@ -113,11 +117,25 @@ public function offsetSet(mixed $offset, mixed $value): void * * @param array-key $offset The offset to remove from the array. */ - public function offsetUnset(mixed $offset): void + public function offsetUnset($offset): void { unset($this->data[$offset]); } + /** + * Returns a serialized string representation of this array object. + * + * @deprecated The Serializable interface will go away in PHP 9. + * + * @link http://php.net/manual/en/serializable.serialize.php Serializable::serialize() + * + * @return string a PHP serialized string. + */ + public function serialize(): string + { + return serialize($this->data); + } + /** * Returns data suitable for PHP serialization. * @@ -131,6 +149,25 @@ public function __serialize(): array return $this->data; } + /** + * Converts a serialized string representation into an instance object. + * + * @deprecated The Serializable interface will go away in PHP 9. + * + * @link http://php.net/manual/en/serializable.unserialize.php Serializable::unserialize() + * + * @param string $serialized A PHP serialized string to unserialize. + * + * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + */ + public function unserialize($serialized): void + { + /** @var array $data */ + $data = unserialize($serialized, ['allowed_classes' => false]); + + $this->data = $data; + } + /** * Adds unserialized data to the object. * @@ -166,6 +203,6 @@ public function toArray(): array public function isEmpty(): bool { - return $this->data === []; + return count($this->data) === 0; } } diff --git a/lib/Google/vendor/ramsey/collection/src/AbstractCollection.php b/lib/Google/vendor/ramsey/collection/src/AbstractCollection.php index 8cb21ec02..38ef7144c 100644 --- a/lib/Google/vendor/ramsey/collection/src/AbstractCollection.php +++ b/lib/Google/vendor/ramsey/collection/src/AbstractCollection.php @@ -17,27 +17,27 @@ use Closure; use Ramsey\Collection\Exception\CollectionMismatchException; use Ramsey\Collection\Exception\InvalidArgumentException; -use Ramsey\Collection\Exception\InvalidPropertyOrMethod; -use Ramsey\Collection\Exception\NoSuchElementException; -use Ramsey\Collection\Exception\UnsupportedOperationException; +use Ramsey\Collection\Exception\InvalidSortOrderException; +use Ramsey\Collection\Exception\OutOfBoundsException; use Ramsey\Collection\Tool\TypeTrait; use Ramsey\Collection\Tool\ValueExtractorTrait; use Ramsey\Collection\Tool\ValueToStringTrait; use function array_filter; -use function array_key_first; -use function array_key_last; use function array_map; use function array_merge; -use function array_reduce; use function array_search; use function array_udiff; use function array_uintersect; +use function current; +use function end; use function in_array; use function is_int; use function is_object; +use function reset; use function spl_object_id; use function sprintf; +use function unserialize; use function usort; /** @@ -55,24 +55,27 @@ abstract class AbstractCollection extends AbstractArray implements CollectionInt use ValueExtractorTrait; /** - * @throws InvalidArgumentException if $element is of the wrong type. + * @inheritDoc */ - public function add(mixed $element): bool + public function add($element): bool { $this[] = $element; return true; } - public function contains(mixed $element, bool $strict = true): bool + /** + * @inheritDoc + */ + public function contains($element, bool $strict = true): bool { return in_array($element, $this->data, $strict); } /** - * @throws InvalidArgumentException if $element is of the wrong type. + * @inheritDoc */ - public function offsetSet(mixed $offset, mixed $value): void + public function offsetSet($offset, $value): void { if ($this->checkType($this->getType(), $value) === false) { throw new InvalidArgumentException( @@ -88,7 +91,10 @@ public function offsetSet(mixed $offset, mixed $value): void } } - public function remove(mixed $element): bool + /** + * @inheritDoc + */ + public function remove($element): bool { if (($position = array_search($element, $this->data, true)) !== false) { unset($this[$position]); @@ -100,11 +106,6 @@ public function remove(mixed $element): bool } /** - * @throws InvalidPropertyOrMethod if the $propertyOrMethod does not exist - * on the elements in this collection. - * @throws UnsupportedOperationException if unable to call column() on this - * collection. - * * @inheritDoc */ public function column(string $propertyOrMethod): array @@ -112,55 +113,55 @@ public function column(string $propertyOrMethod): array $temp = []; foreach ($this->data as $item) { + /** @var mixed $value */ + $value = $this->extractValue($item, $propertyOrMethod); + /** @psalm-suppress MixedAssignment */ - $temp[] = $this->extractValue($item, $propertyOrMethod); + $temp[] = $value; } return $temp; } /** - * @return T - * - * @throws NoSuchElementException if this collection is empty. + * @inheritDoc */ - public function first(): mixed + public function first() { - $firstIndex = array_key_first($this->data); - - if ($firstIndex === null) { - throw new NoSuchElementException('Can\'t determine first item. Collection is empty'); + if ($this->isEmpty()) { + throw new OutOfBoundsException('Can\'t determine first item. Collection is empty'); } - return $this->data[$firstIndex]; + reset($this->data); + + /** @var T $first */ + $first = current($this->data); + + return $first; } /** - * @return T - * - * @throws NoSuchElementException if this collection is empty. + * @inheritDoc */ - public function last(): mixed + public function last() { - $lastIndex = array_key_last($this->data); - - if ($lastIndex === null) { - throw new NoSuchElementException('Can\'t determine last item. Collection is empty'); + if ($this->isEmpty()) { + throw new OutOfBoundsException('Can\'t determine last item. Collection is empty'); } - return $this->data[$lastIndex]; + /** @var T $item */ + $item = end($this->data); + reset($this->data); + + return $item; } - /** - * @return CollectionInterface - * - * @throws InvalidPropertyOrMethod if the $propertyOrMethod does not exist - * on the elements in this collection. - * @throws UnsupportedOperationException if unable to call sort() on this - * collection. - */ - public function sort(?string $propertyOrMethod = null, Sort $order = Sort::Ascending): CollectionInterface + public function sort(string $propertyOrMethod, string $order = self::SORT_ASC): CollectionInterface { + if (!in_array($order, [self::SORT_ASC, self::SORT_DESC], true)) { + throw new InvalidSortOrderException('Invalid sort order given: ' . $order); + } + $collection = clone $this; usort( @@ -169,25 +170,20 @@ public function sort(?string $propertyOrMethod = null, Sort $order = Sort::Ascen * @param T $a * @param T $b */ - function (mixed $a, mixed $b) use ($propertyOrMethod, $order): int { + function ($a, $b) use ($propertyOrMethod, $order): int { /** @var mixed $aValue */ $aValue = $this->extractValue($a, $propertyOrMethod); /** @var mixed $bValue */ $bValue = $this->extractValue($b, $propertyOrMethod); - return ($aValue <=> $bValue) * ($order === Sort::Descending ? -1 : 1); + return ($aValue <=> $bValue) * ($order === self::SORT_DESC ? -1 : 1); }, ); return $collection; } - /** - * @param callable(T): bool $callback A callable to use for filtering elements. - * - * @return CollectionInterface - */ public function filter(callable $callback): CollectionInterface { $collection = clone $this; @@ -197,66 +193,23 @@ public function filter(callable $callback): CollectionInterface } /** - * @return CollectionInterface - * - * @throws InvalidPropertyOrMethod if the $propertyOrMethod does not exist - * on the elements in this collection. - * @throws UnsupportedOperationException if unable to call where() on this - * collection. + * {@inheritdoc} */ - public function where(?string $propertyOrMethod, mixed $value): CollectionInterface + public function where(string $propertyOrMethod, $value): CollectionInterface { - return $this->filter( - /** - * @param T $item - */ - function (mixed $item) use ($propertyOrMethod, $value): bool { - /** @var mixed $accessorValue */ - $accessorValue = $this->extractValue($item, $propertyOrMethod); + return $this->filter(function ($item) use ($propertyOrMethod, $value) { + /** @var mixed $accessorValue */ + $accessorValue = $this->extractValue($item, $propertyOrMethod); - return $accessorValue === $value; - }, - ); + return $accessorValue === $value; + }); } - /** - * @param callable(T): TCallbackReturn $callback A callable to apply to each - * item of the collection. - * - * @return CollectionInterface - * - * @template TCallbackReturn - */ public function map(callable $callback): CollectionInterface { - /** @var Collection */ return new Collection('mixed', array_map($callback, $this->data)); } - /** - * @param callable(TCarry, T): TCarry $callback A callable to apply to each - * item of the collection to reduce it to a single value. - * @param TCarry $initial This is the initial value provided to the callback. - * - * @return TCarry - * - * @template TCarry - */ - public function reduce(callable $callback, mixed $initial): mixed - { - /** @var TCarry */ - return array_reduce($this->data, $callback, $initial); - } - - /** - * @param CollectionInterface $other The collection to check for divergent - * items. - * - * @return CollectionInterface - * - * @throws CollectionMismatchException if the compared collections are of - * differing types. - */ public function diff(CollectionInterface $other): CollectionInterface { $this->compareCollectionTypes($other); @@ -273,15 +226,6 @@ public function diff(CollectionInterface $other): CollectionInterface return $collection; } - /** - * @param CollectionInterface $other The collection to check for - * intersecting items. - * - * @return CollectionInterface - * - * @throws CollectionMismatchException if the compared collections are of - * differing types. - */ public function intersect(CollectionInterface $other): CollectionInterface { $this->compareCollectionTypes($other); @@ -295,15 +239,6 @@ public function intersect(CollectionInterface $other): CollectionInterface return $collection; } - /** - * @param CollectionInterface ...$collections The collections to merge. - * - * @return CollectionInterface - * - * @throws CollectionMismatchException if unable to merge any of the given - * collections or items within the given collections due to type - * mismatch errors. - */ public function merge(CollectionInterface ...$collections): CollectionInterface { $mergedCollection = clone $this; @@ -339,10 +274,19 @@ public function merge(CollectionInterface ...$collections): CollectionInterface return $mergedCollection; } + /** + * @inheritDoc + */ + public function unserialize($serialized): void + { + /** @var array $data */ + $data = unserialize($serialized, ['allowed_classes' => [$this->getType()]]); + + $this->data = $data; + } + /** * @param CollectionInterface $other - * - * @throws CollectionMismatchException */ private function compareCollectionTypes(CollectionInterface $other): void { @@ -363,7 +307,7 @@ private function getComparator(): Closure * @param T $a * @param T $b */ - function (mixed $a, mixed $b): int { + function ($a, $b): int { // If the two values are object, we convert them to unique scalars. // If the collection contains mixed values (unlikely) where some are objects // and some are not, we leave them as they are. @@ -383,11 +327,15 @@ function (mixed $a, mixed $b): int { */ private function getUniformType(CollectionInterface $collection): string { - return match ($collection->getType()) { - 'integer' => 'int', - 'boolean' => 'bool', - 'double' => 'float', - default => $collection->getType(), - }; + switch ($collection->getType()) { + case 'integer': + return 'int'; + case 'boolean': + return 'bool'; + case 'double': + return 'float'; + default: + return $collection->getType(); + } } } diff --git a/lib/Google/vendor/ramsey/collection/src/AbstractSet.php b/lib/Google/vendor/ramsey/collection/src/AbstractSet.php index 7186939d7..1126ccb0a 100644 --- a/lib/Google/vendor/ramsey/collection/src/AbstractSet.php +++ b/lib/Google/vendor/ramsey/collection/src/AbstractSet.php @@ -24,7 +24,10 @@ */ abstract class AbstractSet extends AbstractCollection { - public function add(mixed $element): bool + /** + * @inheritDoc + */ + public function add($element): bool { if ($this->contains($element)) { return false; @@ -33,7 +36,10 @@ public function add(mixed $element): bool return parent::add($element); } - public function offsetSet(mixed $offset, mixed $value): void + /** + * @inheritDoc + */ + public function offsetSet($offset, $value): void { if ($this->contains($value)) { return; diff --git a/lib/Google/vendor/ramsey/collection/src/ArrayInterface.php b/lib/Google/vendor/ramsey/collection/src/ArrayInterface.php index bc7f6f424..27af6102b 100644 --- a/lib/Google/vendor/ramsey/collection/src/ArrayInterface.php +++ b/lib/Google/vendor/ramsey/collection/src/ArrayInterface.php @@ -17,6 +17,7 @@ use ArrayAccess; use Countable; use IteratorAggregate; +use Serializable; /** * `ArrayInterface` provides traversable array functionality to data types. @@ -28,7 +29,8 @@ interface ArrayInterface extends ArrayAccess, Countable, - IteratorAggregate + IteratorAggregate, + Serializable { /** * Removes all items from this array. diff --git a/lib/Google/vendor/ramsey/collection/src/Collection.php b/lib/Google/vendor/ramsey/collection/src/Collection.php index 44d26bf2e..532b971b6 100644 --- a/lib/Google/vendor/ramsey/collection/src/Collection.php +++ b/lib/Google/vendor/ramsey/collection/src/Collection.php @@ -75,16 +75,25 @@ */ class Collection extends AbstractCollection { + /** + * The type of elements stored in this collection. + * + * A collection's type is immutable once it is set. For this reason, this + * property is set private. + */ + private string $collectionType; + /** * Constructs a collection object of the specified type, optionally with the * specified data. * - * @param string $collectionType The type or class name associated with this + * @param string $collectionType The type (FQCN) associated with this * collection. * @param array $data The initial items to store in the collection. */ - public function __construct(private readonly string $collectionType, array $data = []) + public function __construct(string $collectionType, array $data = []) { + $this->collectionType = $collectionType; parent::__construct($data); } diff --git a/lib/Google/vendor/ramsey/collection/src/CollectionInterface.php b/lib/Google/vendor/ramsey/collection/src/CollectionInterface.php index e3ad01470..9f86a2837 100644 --- a/lib/Google/vendor/ramsey/collection/src/CollectionInterface.php +++ b/lib/Google/vendor/ramsey/collection/src/CollectionInterface.php @@ -14,14 +14,8 @@ namespace Ramsey\Collection; -use Ramsey\Collection\Exception\CollectionMismatchException; -use Ramsey\Collection\Exception\InvalidArgumentException; -use Ramsey\Collection\Exception\InvalidPropertyOrMethod; -use Ramsey\Collection\Exception\NoSuchElementException; -use Ramsey\Collection\Exception\UnsupportedOperationException; - /** - * A collection represents a group of values, known as its elements. + * A collection represents a group of objects, known as its elements. * * Some collections allow duplicate elements and others do not. Some are ordered * and others unordered. @@ -31,6 +25,16 @@ */ interface CollectionInterface extends ArrayInterface { + /** + * Ascending sort type. + */ + public const SORT_ASC = 'asc'; + + /** + * Descending sort type. + */ + public const SORT_DESC = 'desc'; + /** * Ensures that this collection contains the specified element (optional * operation). @@ -54,11 +58,9 @@ interface CollectionInterface extends ArrayInterface * @param T $element The element to add to the collection. * * @return bool `true` if this collection changed as a result of the call. - * - * @throws InvalidArgumentException if the collection refuses to add the - * $element for any reason other than that it already contains the element. */ - public function add(mixed $element): bool; + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + public function add($element): bool; /** * Returns `true` if this collection contains the specified element. @@ -66,7 +68,8 @@ public function add(mixed $element): bool; * @param T $element The element to check whether the collection contains. * @param bool $strict Whether to perform a strict type check on the value. */ - public function contains(mixed $element, bool $strict = true): bool; + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + public function contains($element, bool $strict = true): bool; /** * Returns the type associated with this collection. @@ -81,20 +84,15 @@ public function getType(): string; * * @return bool `true` if an element was removed as a result of this call. */ - public function remove(mixed $element): bool; + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + public function remove($element): bool; /** - * Returns the values from the given property, method, or array key. - * - * @param string $propertyOrMethod The name of the property, method, or - * array key to evaluate and return. + * Returns the values from the given property or method. * - * @return array + * @param string $propertyOrMethod The property or method name to filter by. * - * @throws InvalidPropertyOrMethod if the $propertyOrMethod does not exist - * on the elements in this collection. - * @throws UnsupportedOperationException if unable to call column() on this - * collection. + * @return list */ public function column(string $propertyOrMethod): array; @@ -102,41 +100,29 @@ public function column(string $propertyOrMethod): array; * Returns the first item of the collection. * * @return T - * - * @throws NoSuchElementException if this collection is empty. */ - public function first(): mixed; + public function first(); /** * Returns the last item of the collection. * * @return T - * - * @throws NoSuchElementException if this collection is empty. */ - public function last(): mixed; + public function last(); /** - * Sort the collection by a property, method, or array key with the given - * sort order. - * - * If $propertyOrMethod is `null`, this will sort by comparing each element. + * Sort the collection by a property or method with the given sort order. * * This will always leave the original collection untouched and will return * a new one. * - * @param string | null $propertyOrMethod The property, method, or array key - * to sort by. - * @param Sort $order The sort order for the resulting collection. + * @param string $propertyOrMethod The property or method to sort by. + * @param string $order The sort order for the resulting collection (one of + * this interface's `SORT_*` constants). * * @return CollectionInterface - * - * @throws InvalidPropertyOrMethod if the $propertyOrMethod does not exist - * on the elements in this collection. - * @throws UnsupportedOperationException if unable to call sort() on this - * collection. */ - public function sort(?string $propertyOrMethod = null, Sort $order = Sort::Ascending): self; + public function sort(string $propertyOrMethod, string $order = self::SORT_ASC): self; /** * Filter out items of the collection which don't match the criteria of @@ -148,31 +134,25 @@ public function sort(?string $propertyOrMethod = null, Sort $order = Sort::Ascen * See the {@link http://php.net/manual/en/function.array-filter.php PHP array_filter() documentation} * for examples of how the `$callback` parameter works. * - * @param callable(T): bool $callback A callable to use for filtering elements. + * @param callable(T):bool $callback A callable to use for filtering elements. * * @return CollectionInterface */ public function filter(callable $callback): self; /** - * Create a new collection where the result of the given property, method, - * or array key of each item in the collection equals the given value. + * Create a new collection where items match the criteria of given callback. * * This will always leave the original collection untouched and will return * a new one. * - * @param string | null $propertyOrMethod The property, method, or array key - * to evaluate. If `null`, the element itself is compared to $value. + * @param string $propertyOrMethod The property or method to evaluate. * @param mixed $value The value to match. * * @return CollectionInterface - * - * @throws InvalidPropertyOrMethod if the $propertyOrMethod does not exist - * on the elements in this collection. - * @throws UnsupportedOperationException if unable to call where() on this - * collection. */ - public function where(?string $propertyOrMethod, mixed $value): self; + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + public function where(string $propertyOrMethod, $value): self; /** * Apply a given callback method on each item of the collection. @@ -184,7 +164,7 @@ public function where(?string $propertyOrMethod, mixed $value): self; * See the {@link http://php.net/manual/en/function.array-map.php PHP array_map() documentation} * for examples of how the `$callback` parameter works. * - * @param callable(T): TCallbackReturn $callback A callable to apply to each + * @param callable(T):TCallbackReturn $callback A callable to apply to each * item of the collection. * * @return CollectionInterface @@ -193,23 +173,6 @@ public function where(?string $propertyOrMethod, mixed $value): self; */ public function map(callable $callback): self; - /** - * Apply a given callback method on each item of the collection - * to reduce it to a single value. - * - * See the {@link http://php.net/manual/en/function.array-reduce.php PHP array_reduce() documentation} - * for examples of how the `$callback` and `$initial` parameters work. - * - * @param callable(TCarry, T): TCarry $callback A callable to apply to each - * item of the collection to reduce it to a single value. - * @param TCarry $initial This is the initial value provided to the callback. - * - * @return TCarry - * - * @template TCarry - */ - public function reduce(callable $callback, mixed $initial): mixed; - /** * Create a new collection with divergent items between current and given * collection. @@ -218,9 +181,6 @@ public function reduce(callable $callback, mixed $initial): mixed; * items. * * @return CollectionInterface - * - * @throws CollectionMismatchException if the compared collections are of - * differing types. */ public function diff(CollectionInterface $other): self; @@ -232,9 +192,6 @@ public function diff(CollectionInterface $other): self; * intersecting items. * * @return CollectionInterface - * - * @throws CollectionMismatchException if the compared collections are of - * differing types. */ public function intersect(CollectionInterface $other): self; @@ -244,10 +201,6 @@ public function intersect(CollectionInterface $other): self; * @param CollectionInterface ...$collections The collections to merge. * * @return CollectionInterface - * - * @throws CollectionMismatchException if unable to merge any of the given - * collections or items within the given collections due to type - * mismatch errors. */ public function merge(CollectionInterface ...$collections): self; } diff --git a/lib/Google/vendor/ramsey/collection/src/DoubleEndedQueue.php b/lib/Google/vendor/ramsey/collection/src/DoubleEndedQueue.php index 62947a24f..4d1f71ea4 100644 --- a/lib/Google/vendor/ramsey/collection/src/DoubleEndedQueue.php +++ b/lib/Google/vendor/ramsey/collection/src/DoubleEndedQueue.php @@ -17,10 +17,6 @@ use Ramsey\Collection\Exception\InvalidArgumentException; use Ramsey\Collection\Exception\NoSuchElementException; -use function array_key_last; -use function array_pop; -use function array_unshift; - /** * This class provides a basic implementation of `DoubleEndedQueueInterface`, to * minimize the effort required to implement this interface. @@ -32,21 +28,33 @@ class DoubleEndedQueue extends Queue implements DoubleEndedQueueInterface { /** - * Constructs a double-ended queue (dequeue) object of the specified type, - * optionally with the specified data. - * - * @param string $queueType The type or class name associated with this dequeue. - * @param array $data The initial items to store in the dequeue. + * Index of the last element in the queue. + */ + private int $tail = -1; + + /** + * @inheritDoc */ - public function __construct(private readonly string $queueType, array $data = []) + public function offsetSet($offset, $value): void { - parent::__construct($this->queueType, $data); + if ($this->checkType($this->getType(), $value) === false) { + throw new InvalidArgumentException( + 'Value must be of type ' . $this->getType() . '; value is ' + . $this->toolValueToString($value), + ); + } + + $this->tail++; + + $this->data[$this->tail] = $value; } /** * @throws InvalidArgumentException if $element is of the wrong type + * + * @inheritDoc */ - public function addFirst(mixed $element): bool + public function addFirst($element): bool { if ($this->checkType($this->getType(), $element) === false) { throw new InvalidArgumentException( @@ -55,112 +63,125 @@ public function addFirst(mixed $element): bool ); } - array_unshift($this->data, $element); + $this->index--; + + $this->data[$this->index] = $element; return true; } /** - * @throws InvalidArgumentException if $element is of the wrong type + * @inheritDoc */ - public function addLast(mixed $element): bool + public function addLast($element): bool { return $this->add($element); } - public function offerFirst(mixed $element): bool + /** + * @inheritDoc + */ + public function offerFirst($element): bool { try { return $this->addFirst($element); - } catch (InvalidArgumentException) { + } catch (InvalidArgumentException $e) { return false; } } - public function offerLast(mixed $element): bool + /** + * @inheritDoc + */ + public function offerLast($element): bool { return $this->offer($element); } /** - * @return T the first element in this queue. - * - * @throws NoSuchElementException if the queue is empty + * @inheritDoc */ - public function removeFirst(): mixed + public function removeFirst() { return $this->remove(); } /** - * @return T the last element in this queue. - * - * @throws NoSuchElementException if this queue is empty. + * @inheritDoc */ - public function removeLast(): mixed + public function removeLast() { - return $this->pollLast() ?? throw new NoSuchElementException( - 'Can\'t return element from Queue. Queue is empty.', - ); + $tail = $this->pollLast(); + + if ($tail === null) { + throw new NoSuchElementException('Can\'t return element from Queue. Queue is empty.'); + } + + return $tail; } /** - * @return T | null the head of this queue, or `null` if this queue is empty. + * @inheritDoc */ - public function pollFirst(): mixed + public function pollFirst() { return $this->poll(); } /** - * @return T | null the tail of this queue, or `null` if this queue is empty. + * @inheritDoc */ - public function pollLast(): mixed + public function pollLast() { - return array_pop($this->data); + if ($this->count() === 0) { + return null; + } + + $tail = $this[$this->tail]; + + unset($this[$this->tail]); + $this->tail--; + + return $tail; } /** - * @return T the head of this queue. - * - * @throws NoSuchElementException if this queue is empty. + * @inheritDoc */ - public function firstElement(): mixed + public function firstElement() { return $this->element(); } /** - * @return T the tail of this queue. - * - * @throws NoSuchElementException if this queue is empty. + * @inheritDoc */ - public function lastElement(): mixed + public function lastElement() { - return $this->peekLast() ?? throw new NoSuchElementException( - 'Can\'t return element from Queue. Queue is empty.', - ); + if ($this->count() === 0) { + throw new NoSuchElementException('Can\'t return element from Queue. Queue is empty.'); + } + + return $this->data[$this->tail]; } /** - * @return T | null the head of this queue, or `null` if this queue is empty. + * @inheritDoc */ - public function peekFirst(): mixed + public function peekFirst() { return $this->peek(); } /** - * @return T | null the tail of this queue, or `null` if this queue is empty. + * @inheritDoc */ - public function peekLast(): mixed + public function peekLast() { - $lastIndex = array_key_last($this->data); - - if ($lastIndex === null) { + if ($this->count() === 0) { return null; } - return $this->data[$lastIndex]; + return $this->data[$this->tail]; } } diff --git a/lib/Google/vendor/ramsey/collection/src/DoubleEndedQueueInterface.php b/lib/Google/vendor/ramsey/collection/src/DoubleEndedQueueInterface.php index 15cc0e97b..3fa4ecab8 100644 --- a/lib/Google/vendor/ramsey/collection/src/DoubleEndedQueueInterface.php +++ b/lib/Google/vendor/ramsey/collection/src/DoubleEndedQueueInterface.php @@ -181,7 +181,8 @@ interface DoubleEndedQueueInterface extends QueueInterface * Implementations should use a more-specific exception that extends * `\RuntimeException`. */ - public function addFirst(mixed $element): bool; + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + public function addFirst($element): bool; /** * Inserts the specified element at the end of this queue if it is possible @@ -201,7 +202,8 @@ public function addFirst(mixed $element): bool; * Implementations should use a more-specific exception that extends * `\RuntimeException`. */ - public function addLast(mixed $element): bool; + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + public function addLast($element): bool; /** * Inserts the specified element at the front of this queue if it is @@ -215,7 +217,8 @@ public function addLast(mixed $element): bool; * * @return bool `true` if the element was added to this queue, else `false`. */ - public function offerFirst(mixed $element): bool; + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + public function offerFirst($element): bool; /** * Inserts the specified element at the end of this queue if it is possible @@ -229,7 +232,8 @@ public function offerFirst(mixed $element): bool; * * @return bool `true` if the element was added to this queue, else `false`. */ - public function offerLast(mixed $element): bool; + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + public function offerLast($element): bool; /** * Retrieves and removes the head of this queue. @@ -241,7 +245,7 @@ public function offerLast(mixed $element): bool; * * @throws NoSuchElementException if this queue is empty. */ - public function removeFirst(): mixed; + public function removeFirst(); /** * Retrieves and removes the tail of this queue. @@ -253,23 +257,23 @@ public function removeFirst(): mixed; * * @throws NoSuchElementException if this queue is empty. */ - public function removeLast(): mixed; + public function removeLast(); /** * Retrieves and removes the head of this queue, or returns `null` if this * queue is empty. * - * @return T | null the head of this queue, or `null` if this queue is empty. + * @return T|null the head of this queue, or `null` if this queue is empty. */ - public function pollFirst(): mixed; + public function pollFirst(); /** * Retrieves and removes the tail of this queue, or returns `null` if this * queue is empty. * - * @return T | null the tail of this queue, or `null` if this queue is empty. + * @return T|null the tail of this queue, or `null` if this queue is empty. */ - public function pollLast(): mixed; + public function pollLast(); /** * Retrieves, but does not remove, the head of this queue. @@ -281,7 +285,7 @@ public function pollLast(): mixed; * * @throws NoSuchElementException if this queue is empty. */ - public function firstElement(): mixed; + public function firstElement(); /** * Retrieves, but does not remove, the tail of this queue. @@ -293,21 +297,21 @@ public function firstElement(): mixed; * * @throws NoSuchElementException if this queue is empty. */ - public function lastElement(): mixed; + public function lastElement(); /** * Retrieves, but does not remove, the head of this queue, or returns `null` * if this queue is empty. * - * @return T | null the head of this queue, or `null` if this queue is empty. + * @return T|null the head of this queue, or `null` if this queue is empty. */ - public function peekFirst(): mixed; + public function peekFirst(); /** * Retrieves, but does not remove, the tail of this queue, or returns `null` * if this queue is empty. * - * @return T | null the tail of this queue, or `null` if this queue is empty. + * @return T|null the tail of this queue, or `null` if this queue is empty. */ - public function peekLast(): mixed; + public function peekLast(); } diff --git a/lib/Google/vendor/ramsey/collection/src/Exception/CollectionMismatchException.php b/lib/Google/vendor/ramsey/collection/src/Exception/CollectionMismatchException.php index 42f5be2df..7058bcf6e 100644 --- a/lib/Google/vendor/ramsey/collection/src/Exception/CollectionMismatchException.php +++ b/lib/Google/vendor/ramsey/collection/src/Exception/CollectionMismatchException.php @@ -19,6 +19,6 @@ /** * Thrown when attempting to operate on collections of differing types. */ -class CollectionMismatchException extends RuntimeException implements CollectionException +class CollectionMismatchException extends RuntimeException { } diff --git a/lib/Google/vendor/ramsey/collection/src/Exception/InvalidArgumentException.php b/lib/Google/vendor/ramsey/collection/src/Exception/InvalidArgumentException.php index 7b41b4a7c..dcc3eac60 100644 --- a/lib/Google/vendor/ramsey/collection/src/Exception/InvalidArgumentException.php +++ b/lib/Google/vendor/ramsey/collection/src/Exception/InvalidArgumentException.php @@ -14,11 +14,9 @@ namespace Ramsey\Collection\Exception; -use InvalidArgumentException as PhpInvalidArgumentException; - /** * Thrown to indicate an argument is not of the expected type. */ -class InvalidArgumentException extends PhpInvalidArgumentException implements CollectionException +class InvalidArgumentException extends \InvalidArgumentException { } diff --git a/lib/Google/vendor/ramsey/collection/src/Exception/CollectionException.php b/lib/Google/vendor/ramsey/collection/src/Exception/InvalidSortOrderException.php similarity index 70% rename from lib/Google/vendor/ramsey/collection/src/Exception/CollectionException.php rename to lib/Google/vendor/ramsey/collection/src/Exception/InvalidSortOrderException.php index 4aa92bed8..4491429c7 100644 --- a/lib/Google/vendor/ramsey/collection/src/Exception/CollectionException.php +++ b/lib/Google/vendor/ramsey/collection/src/Exception/InvalidSortOrderException.php @@ -14,8 +14,11 @@ namespace Ramsey\Collection\Exception; -use Throwable; +use RuntimeException; -interface CollectionException extends Throwable +/** + * Thrown when attempting to use a sort order that is not recognized. + */ +class InvalidSortOrderException extends RuntimeException { } diff --git a/lib/Google/vendor/ramsey/collection/src/Exception/NoSuchElementException.php b/lib/Google/vendor/ramsey/collection/src/Exception/NoSuchElementException.php index cd98f0c0f..cabcb9d88 100644 --- a/lib/Google/vendor/ramsey/collection/src/Exception/NoSuchElementException.php +++ b/lib/Google/vendor/ramsey/collection/src/Exception/NoSuchElementException.php @@ -19,6 +19,6 @@ /** * Thrown when attempting to access an element that does not exist. */ -class NoSuchElementException extends RuntimeException implements CollectionException +class NoSuchElementException extends RuntimeException { } diff --git a/lib/Google/vendor/ramsey/collection/src/Exception/OutOfBoundsException.php b/lib/Google/vendor/ramsey/collection/src/Exception/OutOfBoundsException.php index c75294e53..4e9d16fa3 100644 --- a/lib/Google/vendor/ramsey/collection/src/Exception/OutOfBoundsException.php +++ b/lib/Google/vendor/ramsey/collection/src/Exception/OutOfBoundsException.php @@ -14,11 +14,9 @@ namespace Ramsey\Collection\Exception; -use OutOfBoundsException as PhpOutOfBoundsException; - /** * Thrown when attempting to access an element out of the range of the collection. */ -class OutOfBoundsException extends PhpOutOfBoundsException implements CollectionException +class OutOfBoundsException extends \OutOfBoundsException { } diff --git a/lib/Google/vendor/ramsey/collection/src/Exception/UnsupportedOperationException.php b/lib/Google/vendor/ramsey/collection/src/Exception/UnsupportedOperationException.php index d074f45fd..9b6228971 100644 --- a/lib/Google/vendor/ramsey/collection/src/Exception/UnsupportedOperationException.php +++ b/lib/Google/vendor/ramsey/collection/src/Exception/UnsupportedOperationException.php @@ -19,6 +19,6 @@ /** * Thrown to indicate that the requested operation is not supported. */ -class UnsupportedOperationException extends RuntimeException implements CollectionException +class UnsupportedOperationException extends RuntimeException { } diff --git a/lib/Google/vendor/ramsey/collection/src/Exception/InvalidPropertyOrMethod.php b/lib/Google/vendor/ramsey/collection/src/Exception/ValueExtractionException.php similarity index 62% rename from lib/Google/vendor/ramsey/collection/src/Exception/InvalidPropertyOrMethod.php rename to lib/Google/vendor/ramsey/collection/src/Exception/ValueExtractionException.php index a53be14aa..32f2a175f 100644 --- a/lib/Google/vendor/ramsey/collection/src/Exception/InvalidPropertyOrMethod.php +++ b/lib/Google/vendor/ramsey/collection/src/Exception/ValueExtractionException.php @@ -17,10 +17,8 @@ use RuntimeException; /** - * Thrown when attempting to evaluate a property, method, or array key - * that doesn't exist on an element or cannot otherwise be evaluated in the - * current context. + * Thrown when attempting to extract a value for a method or property that does not exist. */ -class InvalidPropertyOrMethod extends RuntimeException implements CollectionException +class ValueExtractionException extends RuntimeException { } diff --git a/lib/Google/vendor/ramsey/collection/src/Map/AbstractMap.php b/lib/Google/vendor/ramsey/collection/src/Map/AbstractMap.php index 7a851a80f..378807289 100644 --- a/lib/Google/vendor/ramsey/collection/src/Map/AbstractMap.php +++ b/lib/Google/vendor/ramsey/collection/src/Map/AbstractMap.php @@ -16,7 +16,6 @@ use Ramsey\Collection\AbstractArray; use Ramsey\Collection\Exception\InvalidArgumentException; -use Traversable; use function array_key_exists; use function array_keys; @@ -27,37 +26,16 @@ * This class provides a basic implementation of `MapInterface`, to minimize the * effort required to implement this interface. * - * @template K of array-key * @template T * @extends AbstractArray - * @implements MapInterface + * @implements MapInterface */ abstract class AbstractMap extends AbstractArray implements MapInterface { /** - * @param array $data The initial items to add to this map. - */ - public function __construct(array $data = []) - { - parent::__construct($data); - } - - /** - * @return Traversable - */ - public function getIterator(): Traversable - { - return parent::getIterator(); - } - - /** - * @param K $offset The offset to set - * @param T $value The value to set at the given offset. - * * @inheritDoc - * @psalm-suppress MoreSpecificImplementedParamType,DocblockTypeContradiction */ - public function offsetSet(mixed $offset, mixed $value): void + public function offsetSet($offset, $value): void { if ($offset === null) { throw new InvalidArgumentException( @@ -69,12 +47,18 @@ public function offsetSet(mixed $offset, mixed $value): void $this->data[$offset] = $value; } - public function containsKey(int | string $key): bool + /** + * @inheritDoc + */ + public function containsKey($key): bool { return array_key_exists($key, $this->data); } - public function containsValue(mixed $value): bool + /** + * @inheritDoc + */ + public function containsValue($value): bool { return in_array($value, $this->data, true); } @@ -88,24 +72,21 @@ public function keys(): array } /** - * @param K $key The key to return from the map. - * @param T | null $defaultValue The default value to use if `$key` is not found. - * - * @return T | null the value or `null` if the key could not be found. + * @inheritDoc */ - public function get(int | string $key, mixed $defaultValue = null): mixed + public function get($key, $defaultValue = null) { - return $this[$key] ?? $defaultValue; + if (!$this->containsKey($key)) { + return $defaultValue; + } + + return $this[$key]; } /** - * @param K $key The key to put or replace in the map. - * @param T $value The value to store at `$key`. - * - * @return T | null the previous value associated with key, or `null` if - * there was no mapping for `$key`. + * @inheritDoc */ - public function put(int | string $key, mixed $value): mixed + public function put($key, $value) { $previousValue = $this->get($key); $this[$key] = $value; @@ -114,13 +95,9 @@ public function put(int | string $key, mixed $value): mixed } /** - * @param K $key The key to put in the map. - * @param T $value The value to store at `$key`. - * - * @return T | null the previous value associated with key, or `null` if - * there was no mapping for `$key`. + * @inheritDoc */ - public function putIfAbsent(int | string $key, mixed $value): mixed + public function putIfAbsent($key, $value) { $currentValue = $this->get($key); @@ -132,12 +109,9 @@ public function putIfAbsent(int | string $key, mixed $value): mixed } /** - * @param K $key The key to remove from the map. - * - * @return T | null the previous value associated with key, or `null` if - * there was no mapping for `$key`. + * @inheritDoc */ - public function remove(int | string $key): mixed + public function remove($key) { $previousValue = $this->get($key); unset($this[$key]); @@ -145,7 +119,10 @@ public function remove(int | string $key): mixed return $previousValue; } - public function removeIf(int | string $key, mixed $value): bool + /** + * @inheritDoc + */ + public function removeIf($key, $value): bool { if ($this->get($key) === $value) { unset($this[$key]); @@ -157,13 +134,9 @@ public function removeIf(int | string $key, mixed $value): bool } /** - * @param K $key The key to replace. - * @param T $value The value to set at `$key`. - * - * @return T | null the previous value associated with key, or `null` if - * there was no mapping for `$key`. + * @inheritDoc */ - public function replace(int | string $key, mixed $value): mixed + public function replace($key, $value) { $currentValue = $this->get($key); @@ -174,7 +147,10 @@ public function replace(int | string $key, mixed $value): mixed return $currentValue; } - public function replaceIf(int | string $key, mixed $oldValue, mixed $newValue): bool + /** + * @inheritDoc + */ + public function replaceIf($key, $oldValue, $newValue): bool { if ($this->get($key) === $oldValue) { $this[$key] = $newValue; @@ -184,20 +160,4 @@ public function replaceIf(int | string $key, mixed $oldValue, mixed $newValue): return false; } - - /** - * @return array - */ - public function __serialize(): array - { - return parent::__serialize(); - } - - /** - * @return array - */ - public function toArray(): array - { - return parent::toArray(); - } } diff --git a/lib/Google/vendor/ramsey/collection/src/Map/AbstractTypedMap.php b/lib/Google/vendor/ramsey/collection/src/Map/AbstractTypedMap.php index 92fdcd54c..486dc2e29 100644 --- a/lib/Google/vendor/ramsey/collection/src/Map/AbstractTypedMap.php +++ b/lib/Google/vendor/ramsey/collection/src/Map/AbstractTypedMap.php @@ -18,14 +18,16 @@ use Ramsey\Collection\Tool\TypeTrait; use Ramsey\Collection\Tool\ValueToStringTrait; +use function var_export; + /** * This class provides a basic implementation of `TypedMapInterface`, to * minimize the effort required to implement this interface. * * @template K of array-key * @template T - * @extends AbstractMap - * @implements TypedMapInterface + * @extends AbstractMap + * @implements TypedMapInterface */ abstract class AbstractTypedMap extends AbstractMap implements TypedMapInterface { @@ -33,14 +35,20 @@ abstract class AbstractTypedMap extends AbstractMap implements TypedMapInterface use ValueToStringTrait; /** - * @param K $offset + * @param K|null $offset * @param T $value * * @inheritDoc - * @psalm-suppress MoreSpecificImplementedParamType */ - public function offsetSet(mixed $offset, mixed $value): void + public function offsetSet($offset, $value): void { + if ($offset === null) { + throw new InvalidArgumentException( + 'Map elements are key/value pairs; a key must be provided for ' + . 'value ' . var_export($value, true), + ); + } + if ($this->checkType($this->getKeyType(), $offset) === false) { throw new InvalidArgumentException( 'Key must be of type ' . $this->getKeyType() . '; key is ' diff --git a/lib/Google/vendor/ramsey/collection/src/Map/AssociativeArrayMap.php b/lib/Google/vendor/ramsey/collection/src/Map/AssociativeArrayMap.php index 34e4e853b..79a314d96 100644 --- a/lib/Google/vendor/ramsey/collection/src/Map/AssociativeArrayMap.php +++ b/lib/Google/vendor/ramsey/collection/src/Map/AssociativeArrayMap.php @@ -17,7 +17,8 @@ /** * `AssociativeArrayMap` represents a standard associative array object. * - * @extends AbstractMap + * @template T + * @extends AbstractMap */ class AssociativeArrayMap extends AbstractMap { diff --git a/lib/Google/vendor/ramsey/collection/src/Map/MapInterface.php b/lib/Google/vendor/ramsey/collection/src/Map/MapInterface.php index 22ba1bdd1..6ed0b2967 100644 --- a/lib/Google/vendor/ramsey/collection/src/Map/MapInterface.php +++ b/lib/Google/vendor/ramsey/collection/src/Map/MapInterface.php @@ -21,7 +21,6 @@ * * A map cannot contain duplicate keys; each key can map to at most one value. * - * @template K of array-key * @template T * @extends ArrayInterface */ @@ -30,9 +29,9 @@ interface MapInterface extends ArrayInterface /** * Returns `true` if this map contains a mapping for the specified key. * - * @param K $key The key to check in the map. + * @param array-key $key The key to check in the map. */ - public function containsKey(int | string $key): bool; + public function containsKey($key): bool; /** * Returns `true` if this map maps one or more keys to the specified value. @@ -41,12 +40,13 @@ public function containsKey(int | string $key): bool; * * @param T $value The value to check in the map. */ - public function containsValue(mixed $value): bool; + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + public function containsValue($value): bool; /** * Return an array of the keys contained in this map. * - * @return list + * @return list */ public function keys(): array; @@ -55,12 +55,13 @@ public function keys(): array; * map contains no mapping for the key, or (optionally) `$defaultValue` if * this map contains no mapping for the key. * - * @param K $key The key to return from the map. - * @param T | null $defaultValue The default value to use if `$key` is not found. + * @param array-key $key The key to return from the map. + * @param T|null $defaultValue The default value to use if `$key` is not found. * - * @return T | null the value or `null` if the key could not be found. + * @return T|null the value or `null` if the key could not be found. */ - public function get(int | string $key, mixed $defaultValue = null): mixed; + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + public function get($key, $defaultValue = null); /** * Associates the specified value with the specified key in this map. @@ -68,13 +69,14 @@ public function get(int | string $key, mixed $defaultValue = null): mixed; * If the map previously contained a mapping for the key, the old value is * replaced by the specified value. * - * @param K $key The key to put or replace in the map. + * @param array-key $key The key to put or replace in the map. * @param T $value The value to store at `$key`. * - * @return T | null the previous value associated with key, or `null` if + * @return T|null the previous value associated with key, or `null` if * there was no mapping for `$key`. */ - public function put(int | string $key, mixed $value): mixed; + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + public function put($key, $value); /** * Associates the specified value with the specified key in this map only if @@ -83,23 +85,25 @@ public function put(int | string $key, mixed $value): mixed; * If there is already a value associated with `$key`, this returns that * value without replacing it. * - * @param K $key The key to put in the map. + * @param array-key $key The key to put in the map. * @param T $value The value to store at `$key`. * - * @return T | null the previous value associated with key, or `null` if + * @return T|null the previous value associated with key, or `null` if * there was no mapping for `$key`. */ - public function putIfAbsent(int | string $key, mixed $value): mixed; + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + public function putIfAbsent($key, $value); /** * Removes the mapping for a key from this map if it is present. * - * @param K $key The key to remove from the map. + * @param array-key $key The key to remove from the map. * - * @return T | null the previous value associated with key, or `null` if + * @return T|null the previous value associated with key, or `null` if * there was no mapping for `$key`. */ - public function remove(int | string $key): mixed; + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + public function remove($key); /** * Removes the entry for the specified key only if it is currently mapped to @@ -107,24 +111,26 @@ public function remove(int | string $key): mixed; * * This performs a strict type check on the value. * - * @param K $key The key to remove from the map. + * @param array-key $key The key to remove from the map. * @param T $value The value to match. * * @return bool true if the value was removed. */ - public function removeIf(int | string $key, mixed $value): bool; + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + public function removeIf($key, $value): bool; /** * Replaces the entry for the specified key only if it is currently mapped * to some value. * - * @param K $key The key to replace. + * @param array-key $key The key to replace. * @param T $value The value to set at `$key`. * - * @return T | null the previous value associated with key, or `null` if + * @return T|null the previous value associated with key, or `null` if * there was no mapping for `$key`. */ - public function replace(int | string $key, mixed $value): mixed; + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + public function replace($key, $value); /** * Replaces the entry for the specified key only if currently mapped to the @@ -132,11 +138,12 @@ public function replace(int | string $key, mixed $value): mixed; * * This performs a strict type check on the value. * - * @param K $key The key to remove from the map. + * @param array-key $key The key to remove from the map. * @param T $oldValue The value to match. * @param T $newValue The value to use as a replacement. * * @return bool true if the value was replaced. */ - public function replaceIf(int | string $key, mixed $oldValue, mixed $newValue): bool; + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + public function replaceIf($key, $oldValue, $newValue): bool; } diff --git a/lib/Google/vendor/ramsey/collection/src/Map/NamedParameterMap.php b/lib/Google/vendor/ramsey/collection/src/Map/NamedParameterMap.php index f948e476c..6e391e970 100644 --- a/lib/Google/vendor/ramsey/collection/src/Map/NamedParameterMap.php +++ b/lib/Google/vendor/ramsey/collection/src/Map/NamedParameterMap.php @@ -21,12 +21,13 @@ use function array_combine; use function array_key_exists; use function is_int; +use function var_export; /** * `NamedParameterMap` represents a mapping of values to a set of named keys * that may optionally be typed * - * @extends AbstractMap + * @extends AbstractMap */ class NamedParameterMap extends AbstractMap { @@ -38,13 +39,13 @@ class NamedParameterMap extends AbstractMap * * @var array */ - private readonly array $namedParameters; + protected array $namedParameters; /** * Constructs a new `NamedParameterMap`. * * @param array $namedParameters The named parameters defined for this map. - * @param array $data An initial set of data to set on this map. + * @param array $data An initial set of data to set on this map. */ public function __construct(array $namedParameters, array $data = []) { @@ -62,12 +63,22 @@ public function getNamedParameters(): array return $this->namedParameters; } - public function offsetSet(mixed $offset, mixed $value): void + /** + * @inheritDoc + */ + public function offsetSet($offset, $value): void { + if ($offset === null) { + throw new InvalidArgumentException( + 'Map elements are key/value pairs; a key must be provided for ' + . 'value ' . var_export($value, true), + ); + } + if (!array_key_exists($offset, $this->namedParameters)) { throw new InvalidArgumentException( 'Attempting to set value for unconfigured parameter \'' - . $this->toolValueToString($offset) . '\'', + . $offset . '\'', ); } diff --git a/lib/Google/vendor/ramsey/collection/src/Map/TypedMap.php b/lib/Google/vendor/ramsey/collection/src/Map/TypedMap.php index f914d9c70..77ef8d314 100644 --- a/lib/Google/vendor/ramsey/collection/src/Map/TypedMap.php +++ b/lib/Google/vendor/ramsey/collection/src/Map/TypedMap.php @@ -14,6 +14,8 @@ namespace Ramsey\Collection\Map; +use Ramsey\Collection\Tool\TypeTrait; + /** * A `TypedMap` represents a map of elements where key and value are typed. * @@ -84,6 +86,24 @@ */ class TypedMap extends AbstractTypedMap { + use TypeTrait; + + /** + * The data type of keys stored in this collection. + * + * A map key's type is immutable once it is set. For this reason, this + * property is set private. + */ + private string $keyType; + + /** + * The data type of values stored in this collection. + * + * A map value's type is immutable once it is set. For this reason, this + * property is set private. + */ + private string $valueType; + /** * Constructs a map object of the specified key and value types, * optionally with the specified data. @@ -92,11 +112,11 @@ class TypedMap extends AbstractTypedMap * @param string $valueType The data type of the map's values. * @param array $data The initial data to set for this map. */ - public function __construct( - private readonly string $keyType, - private readonly string $valueType, - array $data = [], - ) { + public function __construct(string $keyType, string $valueType, array $data = []) + { + $this->keyType = $keyType; + $this->valueType = $valueType; + parent::__construct($data); } diff --git a/lib/Google/vendor/ramsey/collection/src/Map/TypedMapInterface.php b/lib/Google/vendor/ramsey/collection/src/Map/TypedMapInterface.php index 5a44f0647..0308109cc 100644 --- a/lib/Google/vendor/ramsey/collection/src/Map/TypedMapInterface.php +++ b/lib/Google/vendor/ramsey/collection/src/Map/TypedMapInterface.php @@ -18,9 +18,8 @@ * A `TypedMapInterface` represents a map of elements where key and value are * typed. * - * @template K of array-key * @template T - * @extends MapInterface + * @extends MapInterface */ interface TypedMapInterface extends MapInterface { diff --git a/lib/Google/vendor/ramsey/collection/src/Queue.php b/lib/Google/vendor/ramsey/collection/src/Queue.php index 0f5b33740..bc8c24e1c 100644 --- a/lib/Google/vendor/ramsey/collection/src/Queue.php +++ b/lib/Google/vendor/ramsey/collection/src/Queue.php @@ -19,8 +19,6 @@ use Ramsey\Collection\Tool\TypeTrait; use Ramsey\Collection\Tool\ValueToStringTrait; -use function array_key_first; - /** * This class provides a basic implementation of `QueueInterface`, to minimize * the effort required to implement this interface. @@ -34,15 +32,29 @@ class Queue extends AbstractArray implements QueueInterface use TypeTrait; use ValueToStringTrait; + /** + * The type of elements stored in this queue. + * + * A queue's type is immutable once it is set. For this reason, this + * property is set private. + */ + private string $queueType; + + /** + * The index of the head of the queue. + */ + protected int $index = 0; + /** * Constructs a queue object of the specified type, optionally with the * specified data. * - * @param string $queueType The type or class name associated with this queue. - * @param array $data The initial items to store in the queue. + * @param string $queueType The type (FQCN) associated with this queue. + * @param array $data The initial items to store in the collection. */ - public function __construct(private readonly string $queueType, array $data = []) + public function __construct(string $queueType, array $data = []) { + $this->queueType = $queueType; parent::__construct($data); } @@ -53,9 +65,9 @@ public function __construct(private readonly string $queueType, array $data = [] * serves only to fulfill the `ArrayAccess` interface requirements. It is * invoked by other operations when adding values to the queue. * - * @throws InvalidArgumentException if $value is of the wrong type. + * @throws InvalidArgumentException if $value is of the wrong type */ - public function offsetSet(mixed $offset, mixed $value): void + public function offsetSet($offset, $value): void { if ($this->checkType($this->getType(), $value) === false) { throw new InvalidArgumentException( @@ -68,9 +80,11 @@ public function offsetSet(mixed $offset, mixed $value): void } /** - * @throws InvalidArgumentException if $value is of the wrong type. + * @throws InvalidArgumentException if $value is of the wrong type + * + * @inheritDoc */ - public function add(mixed $element): bool + public function add($element): bool { $this[] = $element; @@ -78,67 +92,74 @@ public function add(mixed $element): bool } /** - * @return T - * - * @throws NoSuchElementException if this queue is empty. + * @inheritDoc */ - public function element(): mixed + public function element() { - return $this->peek() ?? throw new NoSuchElementException( - 'Can\'t return element from Queue. Queue is empty.', - ); + $element = $this->peek(); + + if ($element === null) { + throw new NoSuchElementException( + 'Can\'t return element from Queue. Queue is empty.', + ); + } + + return $element; } - public function offer(mixed $element): bool + /** + * @inheritDoc + */ + public function offer($element): bool { try { return $this->add($element); - } catch (InvalidArgumentException) { + } catch (InvalidArgumentException $e) { return false; } } /** - * @return T | null + * @inheritDoc */ - public function peek(): mixed + public function peek() { - $index = array_key_first($this->data); - - if ($index === null) { + if ($this->count() === 0) { return null; } - return $this[$index]; + return $this[$this->index]; } /** - * @return T | null + * @inheritDoc */ - public function poll(): mixed + public function poll() { - $index = array_key_first($this->data); - - if ($index === null) { + if ($this->count() === 0) { return null; } - $head = $this[$index]; - unset($this[$index]); + $head = $this[$this->index]; + + unset($this[$this->index]); + $this->index++; return $head; } /** - * @return T - * - * @throws NoSuchElementException if this queue is empty. + * @inheritDoc */ - public function remove(): mixed + public function remove() { - return $this->poll() ?? throw new NoSuchElementException( - 'Can\'t return element from Queue. Queue is empty.', - ); + $head = $this->poll(); + + if ($head === null) { + throw new NoSuchElementException('Can\'t return element from Queue. Queue is empty.'); + } + + return $head; } public function getType(): string diff --git a/lib/Google/vendor/ramsey/collection/src/QueueInterface.php b/lib/Google/vendor/ramsey/collection/src/QueueInterface.php index f29ce43ab..4f91487fa 100644 --- a/lib/Google/vendor/ramsey/collection/src/QueueInterface.php +++ b/lib/Google/vendor/ramsey/collection/src/QueueInterface.php @@ -129,7 +129,8 @@ interface QueueInterface extends ArrayInterface * Implementations should use a more-specific exception that extends * `\RuntimeException`. */ - public function add(mixed $element): bool; + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + public function add($element): bool; /** * Retrieves, but does not remove, the head of this queue. @@ -143,7 +144,7 @@ public function add(mixed $element): bool; * * @throws NoSuchElementException if this queue is empty. */ - public function element(): mixed; + public function element(); /** * Inserts the specified element into this queue if it is possible to do so @@ -159,7 +160,8 @@ public function element(): mixed; * * @return bool `true` if the element was added to this queue, else `false`. */ - public function offer(mixed $element): bool; + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + public function offer($element): bool; /** * Retrieves, but does not remove, the head of this queue, or returns `null` @@ -167,9 +169,9 @@ public function offer(mixed $element): bool; * * @see self::element() * - * @return T | null the head of this queue, or `null` if this queue is empty. + * @return T|null the head of this queue, or `null` if this queue is empty. */ - public function peek(): mixed; + public function peek(); /** * Retrieves and removes the head of this queue, or returns `null` @@ -177,9 +179,9 @@ public function peek(): mixed; * * @see self::remove() * - * @return T | null the head of this queue, or `null` if this queue is empty. + * @return T|null the head of this queue, or `null` if this queue is empty. */ - public function poll(): mixed; + public function poll(); /** * Retrieves and removes the head of this queue. @@ -193,7 +195,7 @@ public function poll(): mixed; * * @throws NoSuchElementException if this queue is empty. */ - public function remove(): mixed; + public function remove(); /** * Returns the type associated with this queue. diff --git a/lib/Google/vendor/ramsey/collection/src/Set.php b/lib/Google/vendor/ramsey/collection/src/Set.php index aa93351c4..c1d37ccca 100644 --- a/lib/Google/vendor/ramsey/collection/src/Set.php +++ b/lib/Google/vendor/ramsey/collection/src/Set.php @@ -28,7 +28,7 @@ * $foo = new \My\Foo(); * $set = new Set(\My\Foo::class); * - * $set->add($foo); // returns TRUE, the element doesn't exist + * $set->add($foo); // returns TRUE, the element don't exists * $set->add($foo); // returns FALSE, the element already exists * * $bar = new \My\Foo(); @@ -40,15 +40,23 @@ */ class Set extends AbstractSet { + /** + * The type of elements stored in this set + * + * A set's type is immutable. For this reason, this property is private. + */ + private string $setType; + /** * Constructs a set object of the specified type, optionally with the * specified data. * - * @param string $setType The type or class name associated with this set. + * @param string $setType The type (FQCN) associated with this set. * @param array $data The initial items to store in the set. */ - public function __construct(private readonly string $setType, array $data = []) + public function __construct(string $setType, array $data = []) { + $this->setType = $setType; parent::__construct($data); } diff --git a/lib/Google/vendor/ramsey/collection/src/Sort.php b/lib/Google/vendor/ramsey/collection/src/Sort.php deleted file mode 100644 index 0c3c19213..000000000 --- a/lib/Google/vendor/ramsey/collection/src/Sort.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @license http://opensource.org/licenses/MIT MIT - */ - -declare(strict_types=1); - -namespace Ramsey\Collection; - -/** - * Collection sorting - */ -enum Sort: string -{ - /** - * Sort items in a collection in ascending order. - */ - case Ascending = 'asc'; - - /** - * Sort items in a collection in descending order. - */ - case Descending = 'desc'; -} diff --git a/lib/Google/vendor/ramsey/collection/src/Tool/TypeTrait.php b/lib/Google/vendor/ramsey/collection/src/Tool/TypeTrait.php index ac51b7f10..728d44b65 100644 --- a/lib/Google/vendor/ramsey/collection/src/Tool/TypeTrait.php +++ b/lib/Google/vendor/ramsey/collection/src/Tool/TypeTrait.php @@ -36,22 +36,39 @@ trait TypeTrait * @param string $type The type to check the value against. * @param mixed $value The value to check. */ - protected function checkType(string $type, mixed $value): bool + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + protected function checkType(string $type, $value): bool { - return match ($type) { - 'array' => is_array($value), - 'bool', 'boolean' => is_bool($value), - 'callable' => is_callable($value), - 'float', 'double' => is_float($value), - 'int', 'integer' => is_int($value), - 'null' => $value === null, - 'numeric' => is_numeric($value), - 'object' => is_object($value), - 'resource' => is_resource($value), - 'scalar' => is_scalar($value), - 'string' => is_string($value), - 'mixed' => true, - default => $value instanceof $type, - }; + switch ($type) { + case 'array': + return is_array($value); + case 'bool': + case 'boolean': + return is_bool($value); + case 'callable': + return is_callable($value); + case 'float': + case 'double': + return is_float($value); + case 'int': + case 'integer': + return is_int($value); + case 'null': + return $value === null; + case 'numeric': + return is_numeric($value); + case 'object': + return is_object($value); + case 'resource': + return is_resource($value); + case 'scalar': + return is_scalar($value); + case 'string': + return is_string($value); + case 'mixed': + return true; + default: + return $value instanceof $type; + } } } diff --git a/lib/Google/vendor/ramsey/collection/src/Tool/ValueExtractorTrait.php b/lib/Google/vendor/ramsey/collection/src/Tool/ValueExtractorTrait.php index 44c422252..e10824283 100644 --- a/lib/Google/vendor/ramsey/collection/src/Tool/ValueExtractorTrait.php +++ b/lib/Google/vendor/ramsey/collection/src/Tool/ValueExtractorTrait.php @@ -14,10 +14,9 @@ namespace Ramsey\Collection\Tool; -use Ramsey\Collection\Exception\InvalidPropertyOrMethod; -use Ramsey\Collection\Exception\UnsupportedOperationException; +use Ramsey\Collection\Exception\ValueExtractionException; -use function is_array; +use function get_class; use function is_object; use function method_exists; use function property_exists; @@ -29,53 +28,34 @@ trait ValueExtractorTrait { /** - * Extracts the value of the given property, method, or array key from the - * element. + * Extracts the value of the given property or method from the object. * - * If `$propertyOrMethod` is `null`, we return the element as-is. - * - * @param mixed $element The element to extract the value from. - * @param string | null $propertyOrMethod The property or method for which the + * @param mixed $object The object to extract the value from. + * @param string $propertyOrMethod The property or method for which the * value should be extracted. * - * @return mixed the value extracted from the specified property, method, - * or array key, or the element itself. + * @return mixed the value extracted from the specified property or method. * - * @throws InvalidPropertyOrMethod - * @throws UnsupportedOperationException + * @throws ValueExtractionException if the method or property is not defined. */ - protected function extractValue(mixed $element, ?string $propertyOrMethod): mixed + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + protected function extractValue($object, string $propertyOrMethod) { - if ($propertyOrMethod === null) { - return $element; - } - - if (!is_object($element) && !is_array($element)) { - throw new UnsupportedOperationException(sprintf( - 'The collection type "%s" does not support the $propertyOrMethod parameter', - $this->getType(), - )); - } - - if (is_array($element)) { - return $element[$propertyOrMethod] ?? throw new InvalidPropertyOrMethod(sprintf( - 'Key or index "%s" not found in collection elements', - $propertyOrMethod, - )); + if (!is_object($object)) { + throw new ValueExtractionException('Unable to extract a value from a non-object'); } - if (property_exists($element, $propertyOrMethod)) { - return $element->$propertyOrMethod; + if (property_exists($object, $propertyOrMethod)) { + return $object->$propertyOrMethod; } - if (method_exists($element, $propertyOrMethod)) { - return $element->{$propertyOrMethod}(); + if (method_exists($object, $propertyOrMethod)) { + return $object->{$propertyOrMethod}(); } - throw new InvalidPropertyOrMethod(sprintf( - 'Method or property "%s" not defined in %s', - $propertyOrMethod, - $element::class, - )); + throw new ValueExtractionException( + // phpcs:ignore SlevomatCodingStandard.Classes.ModernClassNameReference.ClassNameReferencedViaFunctionCall + sprintf('Method or property "%s" not defined in %s', $propertyOrMethod, get_class($object)), + ); } } diff --git a/lib/Google/vendor/ramsey/collection/src/Tool/ValueToStringTrait.php b/lib/Google/vendor/ramsey/collection/src/Tool/ValueToStringTrait.php index 64fc5fa42..cacefc8b6 100644 --- a/lib/Google/vendor/ramsey/collection/src/Tool/ValueToStringTrait.php +++ b/lib/Google/vendor/ramsey/collection/src/Tool/ValueToStringTrait.php @@ -16,7 +16,7 @@ use DateTimeInterface; -use function assert; +use function get_class; use function get_resource_type; use function is_array; use function is_bool; @@ -24,6 +24,7 @@ use function is_object; use function is_resource; use function is_scalar; +use function var_export; /** * Provides functionality to express a value as string @@ -45,7 +46,8 @@ trait ValueToStringTrait * * @param mixed $value the value to return as a string. */ - protected function toolValueToString(mixed $value): string + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + protected function toolValueToString($value): string { // null if ($value === null) { @@ -72,8 +74,12 @@ protected function toolValueToString(mixed $value): string return '(' . get_resource_type($value) . ' resource #' . (int) $value . ')'; } + // If we don't know what it is, use var_export(). + if (!is_object($value)) { + return '(' . var_export($value, true) . ')'; + } + // From here, $value should be an object. - assert(is_object($value)); // __toString() is implemented if (is_callable([$value, '__toString'])) { @@ -86,6 +92,7 @@ protected function toolValueToString(mixed $value): string } // unknown type - return '(' . $value::class . ' Object)'; + // phpcs:ignore SlevomatCodingStandard.Classes.ModernClassNameReference.ClassNameReferencedViaFunctionCall + return '(' . get_class($value) . ' Object)'; } } diff --git a/lib/Google/vendor/ramsey/uuid/src/Generator/UnixTimeGenerator.php b/lib/Google/vendor/ramsey/uuid/src/Generator/UnixTimeGenerator.php index af94decf2..d7c8ed4ee 100644 --- a/lib/Google/vendor/ramsey/uuid/src/Generator/UnixTimeGenerator.php +++ b/lib/Google/vendor/ramsey/uuid/src/Generator/UnixTimeGenerator.php @@ -142,7 +142,7 @@ private function increment(): string self::$seedIndex = 21; } - self::$rand[5] = 0xffff & $carry = self::$rand[5] + (self::$seedParts[self::$seedIndex--] & 0xffffff); + self::$rand[5] = 0xffff & $carry = self::$rand[5] + 1 + (self::$seedParts[self::$seedIndex--] & 0xffffff); self::$rand[4] = 0xffff & $carry = self::$rand[4] + ($carry >> 16); self::$rand[3] = 0xffff & $carry = self::$rand[3] + ($carry >> 16); self::$rand[2] = 0xffff & $carry = self::$rand[2] + ($carry >> 16); diff --git a/lib/Google/vendor/ramsey/uuid/src/Uuid.php b/lib/Google/vendor/ramsey/uuid/src/Uuid.php index 18525d0c0..e0384a50c 100644 --- a/lib/Google/vendor/ramsey/uuid/src/Uuid.php +++ b/lib/Google/vendor/ramsey/uuid/src/Uuid.php @@ -310,7 +310,7 @@ public function __serialize(): array * @param string $data The serialized PHP string to unserialize into * a UuidInterface instance */ - public function unserialize($data): void + public function unserialize(string $data): void { if (strlen($data) === 16) { /** @var Uuid $uuid */ diff --git a/lib/Google/vendor/ramsey/uuid/src/UuidInterface.php b/lib/Google/vendor/ramsey/uuid/src/UuidInterface.php index 0a9780805..cac9457de 100644 --- a/lib/Google/vendor/ramsey/uuid/src/UuidInterface.php +++ b/lib/Google/vendor/ramsey/uuid/src/UuidInterface.php @@ -46,7 +46,7 @@ interface UuidInterface extends * * @param UuidInterface $other The UUID to compare * - * @return int -1, 0, or 1 if the UUID is less than, equal to, or greater than $other + * @return int<-1,1> -1, 0, or 1 if the UUID is less than, equal to, or greater than $other */ public function compareTo(UuidInterface $other): int; diff --git a/lib/Google/vendor/symfony/deprecation-contracts/.gitignore b/lib/Google/vendor/symfony/deprecation-contracts/.gitignore new file mode 100644 index 000000000..c49a5d8df --- /dev/null +++ b/lib/Google/vendor/symfony/deprecation-contracts/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.lock +phpunit.xml diff --git a/lib/Google/vendor/symfony/deprecation-contracts/LICENSE b/lib/Google/vendor/symfony/deprecation-contracts/LICENSE index 0ed3a2465..406242ff2 100644 --- a/lib/Google/vendor/symfony/deprecation-contracts/LICENSE +++ b/lib/Google/vendor/symfony/deprecation-contracts/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020-present Fabien Potencier +Copyright (c) 2020-2022 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/lib/Google/vendor/symfony/deprecation-contracts/README.md b/lib/Google/vendor/symfony/deprecation-contracts/README.md index 9814864c0..4957933a6 100644 --- a/lib/Google/vendor/symfony/deprecation-contracts/README.md +++ b/lib/Google/vendor/symfony/deprecation-contracts/README.md @@ -22,5 +22,5 @@ trigger_deprecation('symfony/blockchain', '8.9', 'Using "%s" is deprecated, use This will generate the following message: `Since symfony/blockchain 8.9: Using "bitcoin" is deprecated, use "fabcoin" instead.` -While not recommended, the deprecation notices can be completely ignored by declaring an empty +While not necessarily recommended, the deprecation notices can be completely ignored by declaring an empty `function trigger_deprecation() {}` in your application. diff --git a/lib/Google/vendor/symfony/deprecation-contracts/composer.json b/lib/Google/vendor/symfony/deprecation-contracts/composer.json index 774200fdc..1c1b4ba0e 100644 --- a/lib/Google/vendor/symfony/deprecation-contracts/composer.json +++ b/lib/Google/vendor/symfony/deprecation-contracts/composer.json @@ -15,7 +15,7 @@ } ], "require": { - "php": ">=8.1" + "php": ">=8.0.2" }, "autoload": { "files": [ @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "3.3-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", diff --git a/vendor/symfony/deprecation-contracts/LICENSE b/lib/Google/vendor/symfony/polyfill-php81/LICENSE similarity index 95% rename from vendor/symfony/deprecation-contracts/LICENSE rename to lib/Google/vendor/symfony/polyfill-php81/LICENSE index 0ed3a2465..99c6bdf35 100644 --- a/vendor/symfony/deprecation-contracts/LICENSE +++ b/lib/Google/vendor/symfony/polyfill-php81/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020-present Fabien Potencier +Copyright (c) 2021-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/lib/Google/vendor/symfony/polyfill-php81/Php81.php b/lib/Google/vendor/symfony/polyfill-php81/Php81.php new file mode 100644 index 000000000..f0507b765 --- /dev/null +++ b/lib/Google/vendor/symfony/polyfill-php81/Php81.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Php81; + +/** + * @author Nicolas Grekas + * + * @internal + */ +final class Php81 +{ + public static function array_is_list(array $array): bool + { + if ([] === $array || $array === array_values($array)) { + return true; + } + + $nextKey = -1; + + foreach ($array as $k => $v) { + if ($k !== ++$nextKey) { + return false; + } + } + + return true; + } +} diff --git a/lib/Google/vendor/symfony/polyfill-php81/README.md b/lib/Google/vendor/symfony/polyfill-php81/README.md new file mode 100644 index 000000000..c07ef7820 --- /dev/null +++ b/lib/Google/vendor/symfony/polyfill-php81/README.md @@ -0,0 +1,18 @@ +Symfony Polyfill / Php81 +======================== + +This component provides features added to PHP 8.1 core: + +- [`array_is_list`](https://php.net/array_is_list) +- [`enum_exists`](https://php.net/enum-exists) +- [`MYSQLI_REFRESH_REPLICA`](https://php.net/mysqli.constants#constantmysqli-refresh-replica) constant +- [`ReturnTypeWillChange`](https://wiki.php.net/rfc/internal_method_return_types) +- [`CURLStringFile`](https://php.net/CURLStringFile) (but only if PHP >= 7.4 is used) + +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/lib/Google/vendor/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php b/lib/Google/vendor/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php new file mode 100644 index 000000000..eb5952ee3 --- /dev/null +++ b/lib/Google/vendor/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (\PHP_VERSION_ID >= 70400 && extension_loaded('curl')) { + /** + * @property string $data + */ + class CURLStringFile extends CURLFile + { + private $data; + + public function __construct(string $data, string $postname, string $mime = 'application/octet-stream') + { + $this->data = $data; + parent::__construct('data://application/octet-stream;base64,'.base64_encode($data), $mime, $postname); + } + + public function __set(string $name, $value): void + { + if ('data' !== $name) { + $this->$name = $value; + + return; + } + + if (is_object($value) ? !method_exists($value, '__toString') : !is_scalar($value)) { + throw new \TypeError('Cannot assign '.gettype($value).' to property CURLStringFile::$data of type string'); + } + + $this->name = 'data://application/octet-stream;base64,'.base64_encode($value); + } + + public function __isset(string $name): bool + { + return isset($this->$name); + } + + public function &__get(string $name) + { + return $this->$name; + } + } +} diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php b/lib/Google/vendor/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php similarity index 59% rename from vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php rename to lib/Google/vendor/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php index bd1212f6e..cb7720a8d 100644 --- a/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php +++ b/lib/Google/vendor/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php @@ -9,8 +9,12 @@ * file that was distributed with this source code. */ -if (\PHP_VERSION_ID < 80000 && extension_loaded('tokenizer')) { - class PhpToken extends Symfony\Polyfill\Php80\PhpToken +if (\PHP_VERSION_ID < 80100) { + #[Attribute(Attribute::TARGET_METHOD)] + final class ReturnTypeWillChange { + public function __construct() + { + } } } diff --git a/lib/Google/vendor/symfony/polyfill-php81/bootstrap.php b/lib/Google/vendor/symfony/polyfill-php81/bootstrap.php new file mode 100644 index 000000000..9f872e02f --- /dev/null +++ b/lib/Google/vendor/symfony/polyfill-php81/bootstrap.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Php81 as p; + +if (\PHP_VERSION_ID >= 80100) { + return; +} + +if (defined('MYSQLI_REFRESH_SLAVE') && !defined('MYSQLI_REFRESH_REPLICA')) { + define('MYSQLI_REFRESH_REPLICA', 64); +} + +if (!function_exists('array_is_list')) { + function array_is_list(array $array): bool { return p\Php81::array_is_list($array); } +} + +if (!function_exists('enum_exists')) { + function enum_exists(string $enum, bool $autoload = true): bool { return $autoload && class_exists($enum) && false; } +} diff --git a/vendor/symfony/polyfill-php73/composer.json b/lib/Google/vendor/symfony/polyfill-php81/composer.json similarity index 80% rename from vendor/symfony/polyfill-php73/composer.json rename to lib/Google/vendor/symfony/polyfill-php81/composer.json index b5c58ec19..e02d673d4 100644 --- a/vendor/symfony/polyfill-php73/composer.json +++ b/lib/Google/vendor/symfony/polyfill-php81/composer.json @@ -1,7 +1,7 @@ { - "name": "symfony/polyfill-php73", + "name": "symfony/polyfill-php81", "type": "library", - "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", "keywords": ["polyfill", "shim", "compatibility", "portable"], "homepage": "https://symfony.com", "license": "MIT", @@ -19,14 +19,14 @@ "php": ">=7.1" }, "autoload": { - "psr-4": { "Symfony\\Polyfill\\Php73\\": "" }, + "psr-4": { "Symfony\\Polyfill\\Php81\\": "" }, "files": [ "bootstrap.php" ], "classmap": [ "Resources/stubs" ] }, "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", diff --git a/lib/classes/batch/class-batch-task-manager.php b/lib/classes/batch/class-batch-task-manager.php new file mode 100644 index 000000000..1659d48c1 --- /dev/null +++ b/lib/classes/batch/class-batch-task-manager.php @@ -0,0 +1,351 @@ +path('lib/ns-vendor/classes/deliciousbrains/wp-background-processing/classes/wp-async-request.php', 'dir'); +} + +if (!class_exists('UDX_WP_Background_Process')) { + require_once ud_get_stateless_media()->path('lib/ns-vendor/classes/deliciousbrains/wp-background-processing/classes/wp-background-process.php', 'dir'); +} + +use wpCloud\StatelessMedia\Helper; +use wpCloud\StatelessMedia\Singleton; + +class BatchTaskManager extends \UDX_WP_Background_Process { + use Singleton; + + const STATE_KEY = '_state'; + const UPDATED_KEY = '_updated'; + const HEALTH_CHECK_INTERVAL = 60 * 5; // 5 minute + + protected $prefix = 'sm'; + protected $action = 'batch_process'; + + protected function __construct() { + parent::__construct(); + + $this->_init_hooks(); + $this->_check_force_continue(); + } + + private function _init_hooks() { + add_filter('wp_stateless_batch_state', [$this, 'get_state'], 10, 1); + add_filter('wp_stateless_batch_action_pause', [$this, 'pause_task'], 10, 2); + add_filter('wp_stateless_batch_action_resume', [$this, 'resume_task'], 10, 2); + add_filter('heartbeat_send', [$this, 'check_running_batch'], 10, 1 ); + } + + /** + * Check if we should force dispatch + * Check if the task is in progress and if the state was not updated last 5 minutes - try to continue the task + */ + private function _check_force_continue() { + $last_updated = $this->_get_last_updated(); + + if ( empty($last_updated) || $this->is_paused() ) { + return; + } + + $check_interval = self::HEALTH_CHECK_INTERVAL; + + if ( defined('WP_STATELESS_BATCH_HEALTHCHECK_INTERVAL') ) { + $check_interval = max($check_interval, WP_STATELESS_BATCH_HEALTHCHECK_INTERVAL * 60); + } + + if ( time() - $last_updated <= $check_interval ) { + return; + } + + Helper::log('Batch task freezed, trying to continue...'); + + // Forcing continue + $this->unlock_process(); + $this->handle(); + } + + /** + * Update current task state + * + * @return array + */ + private function _update_state($state) { + update_site_option( $this->identifier . self::STATE_KEY, $state ); + update_site_option( $this->identifier . self::UPDATED_KEY, time() ); + } + + /** + * Get current task state + * + * @return array + */ + private function _get_state() { + return get_site_option( $this->identifier . self::STATE_KEY, [] ); + } + + /** + * Get last state update of the current task + * + * @return int|null + */ + private function _get_last_updated() { + return get_site_option( $this->identifier . self::UPDATED_KEY, null ); + } + + /** + * Delete current task state + * + * @return array + */ + private function _delete_state() { + delete_site_option( $this->identifier . self::STATE_KEY ); + delete_site_option( $this->identifier . self::UPDATED_KEY ); + } + + /** + * Add new batch to the queue + * + * @param array $batch + */ + private function _add_batch($batch) { + if ( !empty($batch) ) { + $this->data( $batch )->save(); + } + } + + /** + * Get task object + * + * @param string $state|null + * @return IBatchTask + * @throws \Exception + */ + private function _get_batch_task_object($state = null) { + if ( empty($state) ) { + $state = $this->_get_state(); + } + + if ( !isset($state['class']) || !isset($state['file']) ) { + throw new \Exception("Can not get batch task file and class"); + } + + $class = $state['class']; + + if ( !class_exists($class) ) { + require_once $state['file']; + } + + $object = new $class(); + + if ( !is_a($object, '\wpCloud\StatelessMedia\Batch\IBatchTask') ) { + throw new \Exception("Batch task $class is not valid"); + } + + $object->set_state($state); + + return $object; + } + + /** + * Start the batch task + * + * @param string $class + * @param string|null $file + * @param string $email + */ + public function start_task($class, $file = null, $email = '') { + try { + // Prepare default state + $defaults = [ + 'class' => $class, + 'file' => $file, + 'email' => $email, + ]; + + $task_object = $this->_get_batch_task_object($defaults); + $task_object->init_state(); + + // Batch should be run prior to 'get_state' because it mutates the state + $this->_add_batch( $task_object->get_batch() ); + + // Save state + $state = wp_parse_args($task_object->get_state(), $defaults); + + $this->_update_state( $state ); + + Helper::log('Batch task started: ' . $class); + + do_action('wp_stateless_batch_task_started', $class, $file); + } catch (\Throwable $e) { + Helper::log("Batch task $class failed to start: " . $e->getMessage()); + + do_action('wp_stateless_batch_task_failed', $class, $file, $e->getMessage()); + + return; + } + + $this->dispatch(); + } + + /** + * Process batch task item. + * Returns false to remove item from queue + * Returns $item to repeat + * + * @param string $item + * @return bool|mixed + */ + public function task($item) { + $result = false; + + try { + $object = $this->_get_batch_task_object(); + + $result = $object->process_item($item); + $this->_update_state( $object->get_state() ); + + $result = apply_filters('wp_stateless_batch_task_item_processed', $result, $item); + } catch (\Throwable $e) { + Helper::log( "Batch task unable to handle item $item: " . $e->getMessage() ); + + $result = apply_filters('wp_stateless_batch_task_item_failed', $result, $item); + } + + return $result; + } + + /** + * Complete the batch task. Tries to get the next batch and continue + */ + protected function complete() { + $class = ''; + $description = 'Batch process'; + + // Check if we have more batched to run + try { + $object = $this->_get_batch_task_object(); + $class = $object::class; + $batch = $object->get_batch(); + $description = $object->get_description(); + + if ( !empty($batch) ) { + $this->_add_batch( $batch ); + $this->_update_state( $object->get_state() ); + + $this->dispatch(); + + return; + } + + Helper::log( 'Batch task completed: ' . $object::class ); + } catch (\Throwable $e) { + Helper::log( "Unable to process next batch: " . $e->getMessage() ); + } + + // If no more batches - delete state + $state = $this->_get_state(); + + parent::complete(); + $this->_delete_state(); + + do_action('wp_stateless_batch_task_finished', $class); + + $site = site_url(); + $subject = sprintf( __('Stateless %s complete successfully', ud_get_stateless_media()->domain), $description ); + $message = sprintf( + __("This is a simple notification to inform you that the WP-Stateless plugin has finished a %s process for %s.\n\nIf you have WP_DEBUG_LOG enabled, check those logs to review any errors that may have occurred during the process.", ud_get_stateless_media()->domain), + $description, + $site + ); + + do_action('wp_stateless_send_admin_email', $subject, $message, $state['email'] ?? ''); + } + + /** + * Check if batch task has a state, so it is in progress + * Because is_processing is true only while processing an item + * + * @param array|null $state + * @return bool + */ + public function is_running($state = null) { + if ( empty($state) ) { + $state = $this->_get_state(); + } + + return !empty($state); + } + + /** + * Get the state of the current batch process + * + * @param mixed $status + * @return mixed + */ + public function get_state($state) { + $state = $this->_get_state(); + + unset($state['class']); + unset($state['file']); + + $state['is_running'] = $this->is_running($state); + $state['is_paused'] = $this->is_paused(); + + return $state; + } + + /** + * Pause the batch task + * + * @param array $state + * @param array $params + * @return array + */ + public function pause_task($state, $params) { + $this->pause(); + + return apply_filters('wp_stateless_batch_state', $state, []); + } + + /** + * Resume the batch task + * + * @param array $state + * @param array $params + * @return array + */ + public function resume_task($state, $params) { + $this->resume(); + + return apply_filters('wp_stateless_batch_state', $state, []); + } + + /** + * Get the state key + * + * @return string + */ + public function get_state_key() { + return $this->identifier . self::STATE_KEY; + } + + /** + * Check if batch is running during WP heartbeat request + * + * @return array + */ + public function check_running_batch($response) { + if ( $this->is_running() ) { + $response['stateless-batch-running'] = true; + } + + return $response; + } +} diff --git a/lib/classes/batch/class-batch-task.php b/lib/classes/batch/class-batch-task.php new file mode 100644 index 000000000..a4bbc4a55 --- /dev/null +++ b/lib/classes/batch/class-batch-task.php @@ -0,0 +1,157 @@ +started = time(); + } + + /** + * Get human-friendly description + * + * @return string + */ + public function get_description() { + return $this->description; + } + + /** + * Get task state + * + * @return array + */ + public function get_state() { + if ( empty($this->started) ) { + $this->init_state(); + } + + // Calling process can add extra data to the state, so we should try to keep it + return wp_parse_args([ + 'id' => $this->id, + 'description' => $this->description, + 'total' => $this->total, + 'completed' => $this->completed, + 'limit' => $this->limit, + 'offset' => $this->offset, + 'started' => $this->started, + ], $this->state); + } + + /** + * Restore task state for processing between calls + * + * @param array $state + * @return array + */ + public function set_state($state) { + // Calling process can add extra data to the state, so we should try to keep it + $this->state = $state; + + // Restore state properties required for processing + if ( isset($state['description']) ) { + $this->description = $state['description']; + } + + if ( isset($state['started']) ) { + $this->started = $state['started']; + } + + if ( isset($state['total']) ) { + $this->total = $state['total']; + } + + if ( isset($state['completed']) ) { + $this->completed = $state['completed']; + } + + if ( isset($state['limit']) ) { + $this->limit = $state['limit']; + } + + if ( isset($state['offset']) ) { + $this->offset = $state['offset']; + } + } + + /** + * Get batch of data to process. False - no more data + * + * @return array|false + */ + abstract public function get_batch(); + + /** + * Process single item. If returns false - the item is removed from the queue. Otherwise repeated. + * + * @param mixed $item + * @return mixed|false + */ + abstract public function process_item($item); +} diff --git a/lib/classes/batch/class-migration.php b/lib/classes/batch/class-migration.php new file mode 100644 index 000000000..6a22d4891 --- /dev/null +++ b/lib/classes/batch/class-migration.php @@ -0,0 +1,28 @@ +id; + $state['is_migration'] = true; + + return $state; + } + + /** + * Can be used to test if the migration should run + * For example, if there are any old data that needs to be migrated + */ + public function should_run() { + return true; + } +} diff --git a/lib/classes/batch/interface-batch.php b/lib/classes/batch/interface-batch.php new file mode 100644 index 000000000..7125e366b --- /dev/null +++ b/lib/classes/batch/interface-batch.php @@ -0,0 +1,41 @@ +path('static/data/addons.php', 'dir'); + + if ( file_exists($addons_file) ) { + $this->addons = require_once($addons_file); + $this->addon_ids = array_keys($this->addons); + } + + add_action('sm::module::init', array($this, 'check_addons')); + add_action('sm::module::messages', array($this, 'show_messages'), 10, 3); + add_action('wp_stateless_addons_tab_content', array($this, 'tab_content')); + add_filter('wp_stateless_addons_tab_visible', array($this, 'addons_tab_visible'), 10, 1); + add_filter('wp_stateless_restrict_compatibility', array($this, 'restrict_compatibility'), 10, 3); + } + + /** + * Check current theme and installed plugins for recommended addons. + * Fires hok to display messages if recommended addons are not active. + * + */ + public function check_addons() { + $active_plugins = Helper::get_active_plugins(); + + foreach ($this->addons as $id => $addon) { + // Recommended theme addons + if ( isset($addon['theme_name']) ) { + if ( Helper::is_theme_name($addon['theme_name']) ) { + $this->addons[$id]['recommended'] = true; + $this->recommended++; + } + } + + // Recommended plugin addons + if ( isset($addon['plugin_files']) && is_array($addon['plugin_files']) ) { + foreach ($addon['plugin_files'] as $file) { + if ( in_array($file, $active_plugins) ) { + $this->addons[$id]['recommended'] = true; + $this->recommended++; + + break; + } + } + } + + // Active addons + if ( isset($addon['addon_file']) ) { + if ( in_array($addon['addon_file'], $active_plugins) ) { + $this->addons[$id]['active'] = true; + $this->active++; + } + } + + // Installed addons + if ( isset($addon['addon_file']) ) { + if ( file_exists( WP_PLUGIN_DIR . '/' . $addon['addon_file'] ) ) { + $this->addons[$id]['installed'] = true; + } + } + } + + // Show message if recommended addons are not active + do_action('sm::module::messages', $this->addons); + } + + /** + * Add messages for recommended addons. + * + * @param array $addons + * @param array $recommended + * @param array $active + * + */ + public function show_messages($addons) { + foreach ($addons as $id => $addon) { + if ( !isset($addon['recommended']) || isset($addon['active']) ) { + continue; + } + + $title = $addon['title']; + + ud_get_stateless_media()->errors->add([ + 'key' => $id, + 'title' => sprintf(__('WP-Stateless: Install the %s Addon', ud_get_stateless_media()->domain), $title), + 'button' => __('Download Addon', ud_get_stateless_media()->domain), + 'button_link' => admin_url('upload.php?page=stateless-settings&tab=stless_addons_tab'), + 'message' => sprintf(__('Download and activate the WP-Stateless addon for %s to ensure compatibility.', ud_get_stateless_media()->domain), $title), + ], 'notice'); + } + } + + /** + * Outputs 'Addons' tab content on the settings page. + * + */ + public function tab_content() { + // Prepare filters + $current_filter = isset($_GET['filter']) && !empty($_GET['filter']) ? $_GET['filter'] : 'all'; + + $url = ud_get_stateless_media()->get_settings_page_url('?page=stateless-settings') . '&tab=stless_addons_tab&filter=%s'; + + $filters = [ + 'all' => [ + 'title' => __('All (%d)', ud_get_stateless_media()->domain), + 'count' => count($this->addons), + ], + 'recommended' => [ + 'title' => __('Recommended (%d)', ud_get_stateless_media()->domain), + 'count' => $this->recommended, + ], + 'active' => [ + 'title' => __('Active (%d)', ud_get_stateless_media()->domain), + 'count' => $this->active, + ], + 'inactive' => [ + 'title' => __('Inactive (%d)', ud_get_stateless_media()->domain), + 'count' => count($this->addons) - $this->active, + ], + ]; + + $filters = Helper::array_of_objects($filters); + + // Filter addons + switch ($current_filter) { + case 'recommended': + $addons = array_filter($this->addons, function($addon) { + return isset($addon['recommended']); + }); + break; + case 'active': + $addons = array_filter($this->addons, function($addon) { + return isset($addon['active']); + }); + break; + case 'inactive': + $addons = array_filter($this->addons, function($addon) { + return !isset($addon['active']); + }); + break; + default: + $addons = $this->addons; + break; + } + + $addons = $this->sort_addons($addons); + $addons = $this->get_addons_view($addons); + $addons = Helper::array_of_objects($addons); + + include ud_get_stateless_media()->path('static/views/addons-tab.php', 'dir'); + } + + /** + * Prepare addon data for output. + * + * @param array $addons + * @return array + */ + private function get_addons_view($addons) { + $plugin_desc = __('Provides compatibility between the %s and the WP-Stateless plugins.', ud_get_stateless_media()->domain); + $theme_desc = __('Provides compatibility between the %s theme and the WP-Stateless plugin.', ud_get_stateless_media()->domain); + + $link = 'https://stateless.udx.io/addons/%s'; + + $defaults = [ + 'title' => '', + 'icon' => '', + 'description' => '', + 'recommended' => false, + 'active' => false, + 'installed' => false, + 'hubspot_id' => '', + 'hubspot_link' => '', + 'repo' => '', + 'docs' => '', + 'link' => '', + 'wp' => '', + 'card_class' => '', + 'status' => '', + ]; + + foreach ($addons as $id => $addon) { + if ( isset($addon['theme_name']) ) { + $addon['description'] = sprintf($theme_desc, $addon['title']); + } else { + $addon['description'] = sprintf($plugin_desc, $addon['title']); + } + + if ( isset($addon['active']) && $addon['active']) { + $addon['card_class'] = 'active'; + $addon['status'] = __('active', ud_get_stateless_media()->domain); + } elseif ( isset($addon['recommended']) && $addon['recommended']) { + $addon['card_class'] = 'recommended'; + $addon['status'] = __('recommended', ud_get_stateless_media()->domain); + } + + $addon['docs'] = sprintf($link, $id); + $addon['link'] = $addon['docs']; + + $addons[$id] = wp_parse_args($addon, $defaults); + } + + return $addons; + } + + /** + * Sort addons: + * - recommended not active + * - other + * - active + * + * @param array $addons + * @return array + */ + private function sort_addons($addons) { + uasort($addons, function($a1, $a2) { + $c1 = isset($a1['recommended']) ? -1 : 0; + $c1 += isset($a1['active']) ? 5 : 0; + + $c2 = isset($a2['recommended']) ? -1 : 0; + $c2 += isset($a2['active']) ? 5 : 0; + + if ( $c1 !== $c2 ) { + return $c1 > $c2 ? 1 : -1; + } + + return strcasecmp( $a1['title'], $a2['title'] ); + }); + + return $addons; + } + + /** + * Check if 'Addons' tab should be visible. + */ + public function addons_tab_visible($visible) { + return count($this->addons) > 0; + } + + /** + * Restrict internal compatibility. + */ + public function restrict_compatibility($restrict, $id, $is_internal) { + // If we have a plugin with the same ID as internal compatibility then disable internal compatibility + if ($is_internal) { + if ( in_array($id, $this->addon_ids) ) { + return true; + } + } + + return $restrict; + } + } +} \ No newline at end of file diff --git a/lib/classes/class-ajax.php b/lib/classes/class-ajax.php index 56bee4513..9b441e24c 100644 --- a/lib/classes/class-ajax.php +++ b/lib/classes/class-ajax.php @@ -48,6 +48,12 @@ public function __construct() { * @author peshkov@UD */ public function request() { + check_ajax_referer('sm_inline_sync'); + + if ( !is_user_logged_in() ) { + wp_send_json_error( array( 'error' => __( 'You are not allowed to do this action.', ud_get_stateless_media()->domain ) ) ); + } + global $doing_manual_sync; $response = array( @@ -85,7 +91,7 @@ public function request() { * Regenerate image sizes. */ public function action_stateless_process_image() { - @set_time_limit(-1); + set_time_limit(0); $image = Utility::process_image_by_id(intval($_REQUEST['id'])); @@ -97,7 +103,7 @@ public function action_stateless_process_image() { * @throws \Exception */ public function action_stateless_process_file() { - @set_time_limit(-1); + set_time_limit(0); $file = Utility::process_file_by_id(intval($_REQUEST['id'])); diff --git a/lib/classes/class-api.php b/lib/classes/class-api.php index eb0f7eaf1..263d49067 100644 --- a/lib/classes/class-api.php +++ b/lib/classes/class-api.php @@ -85,7 +85,7 @@ static public function updateSettings(\WP_REST_Request $request) { if (self::$tokenData === null || empty(self::$tokenData->user_id)) { return new \WP_Error('unauthorized', 'Auth token looks incorrect', ['status' => 401]); } - $is_gae = isset($_SERVER["GAE_VERSION"]) ? true : false; + $is_gae = apply_filters('wp_stateless_is_app_engine', false); $upload_dir = wp_upload_dir(); $is_upload_dir_writable = is_writable($upload_dir['basedir']); @@ -274,6 +274,55 @@ static public function syncStop(\WP_REST_Request $request) { return new \WP_Error('internal_server_error', $e->getMessage(), ['status' => 500]); } } + + /** + * Batch Status Endpoint. + * + * @param \WP_REST_Request $request + * @return \WP_REST_Response + */ + static public function batchState(\WP_REST_Request $request) { + try { + return new \WP_REST_Response(array( + 'ok' => true, + 'data' => apply_filters('wp_stateless_batch_state', [], $request->get_params()), + )); + } catch (\Throwable $e) { + return new \WP_Error('internal_server_error', $e->getMessage(), ['status' => 500]); + } + } + + /** + * Batch action (start/pause/resume) + * + * @param \WP_REST_Request $request + * @return \WP_Error|\WP_REST_Response + */ + static public function batchAction(\WP_REST_Request $request) { + try { + if (!user_can(self::$tokenData->user_id, 'manage_options')) { + return new \WP_Error('not_allowed', 'Sorry, you are not allowed to perform this action', ['status' => 403]); + } + + wp_set_current_user(self::$tokenData->user_id); + + $params = wp_parse_args($request->get_params(), [ + 'action' => '', + ]); + + if ( empty($params['action']) ) { + throw new \Exception('Batch action not set'); + } + + $action = $params['action']; + + return new \WP_REST_Response(array( + 'data' => apply_filters("wp_stateless_batch_action_$action", [], $params), + )); + } catch (\Throwable $e) { + return new \WP_Error('internal_server_error', $e->getMessage(), ['status' => 500]); + } + } } } } diff --git a/lib/classes/class-bootstrap.php b/lib/classes/class-bootstrap.php index 5708ce9bb..262e1b715 100644 --- a/lib/classes/class-bootstrap.php +++ b/lib/classes/class-bootstrap.php @@ -13,6 +13,7 @@ use wpCloud\StatelessMedia\Sync\FileSync; use wpCloud\StatelessMedia\Sync\ImageSync; use wpCloud\StatelessMedia\Sync\NonLibrarySync; + use wpCloud\StatelessMedia\Batch\BatchTaskManager; if (!class_exists('wpCloud\StatelessMedia\Bootstrap')) { @@ -54,6 +55,13 @@ final class Bootstrap extends \UsabilityDynamics\WP\Bootstrap_Plugin { * @author peshkov@UD */ protected function __construct($args) { + /** + * Need to be loaded before plugin initialization. + */ + if ( !(defined('WP_STATELESS_COMPATIBILITY_GAE') && !WP_STATELESS_COMPATIBILITY_GAE) ) { + AppEngine::instance(); + } + parent::__construct($args); /** @@ -72,8 +80,10 @@ protected function __construct($args) { // Initialize compatibility modules. add_action('plugins_loaded', function () { + Addons::instance(); new Module(); - }); + DynamicImageSupport::instance(); + }, 20); /** * Define settings and UI. @@ -87,6 +97,7 @@ protected function __construct($args) { * $this->set( 'sm.client_id', 'zxcvv12adffse' ); */ $this->settings = new Settings($this); + Status::instance(); } /** @@ -99,10 +110,19 @@ public function load_textdomain() { * Instantiate class. */ public function init() { - // Parse feature falgs, set constants. + // Parse feature flags, set constants. $this->parse_feature_flags(); $sm_mode = $this->get('sm.mode'); + /** + * Send admin email + */ + add_action('wp_stateless_send_admin_email', array($this, 'send_admin_email'), 10, 3); + + // Should be created unconditionally and as early as possible to handle batch migration requests + BatchTaskManager::instance(); + Migrator::instance(); + new SyncNonMedia(); ImageSync::instance(); @@ -171,7 +191,7 @@ public function init() { 'title' => __('Media Library Synchronization Underway', ud_get_stateless_media()->domain), 'message' => __('WP-Stateless is synchronizing your media library in accordance with the Mode setting. You can view progress or stop the process via the WP-Stateless Sync settings area.', ud_get_stateless_media()->domain), 'button' => __('View Synchronization', ud_get_stateless_media()->domain), - 'button_link' => admin_url('upload.php?page=stateless-settings#stless_sync_tab'), + 'button_link' => admin_url('upload.php?page=stateless-settings&tab=stless_sync_tab'), 'key' => 'processing-in-progress' ], 'message'); break; @@ -220,6 +240,19 @@ public function init() { * Replacing local path to gs:// for using it on StreamWrapper */ add_filter('upload_dir', array($this, 'filter_upload_dir'), 99); + + /** + * Stateless mode working only with GD library + */ + add_filter('wp_image_editors', array($this, 'select_wp_image_editors')); + + /** + * Init GS client + */ + global $gs_client; + if ($gs_client = $this->init_gs_client()) { + StreamWrapper::register($gs_client); + } } if ($this->get('sm.delete_remote') == 'true') { @@ -237,30 +270,51 @@ public function init() { } } elseif ($sm_mode == 'stateless') { /** - * Replacing local path to gs:// for using it on StreamWrapper + * Determine if we have issues with connection to Google Storage Bucket + * if SM is not disabled. */ - add_filter('upload_dir', array($this, 'filter_upload_dir'), 99); + $is_connected = $this->is_connected_to_gs(); - /** - * Stateless mode working only with GD library - */ - add_filter('wp_image_editors', array($this, 'select_wp_image_editors')); + if (is_wp_error($is_connected)) { + $this->errors->add($is_connected->get_error_message(), 'warning'); + } - //init GS client - global $gs_client; - if ($gs_client = $this->init_gs_client()) { - StreamWrapper::register($gs_client); + if ($googleSDKVersionConflictError = get_transient("wp_stateless_google_sdk_conflict")) { + $this->errors->add($googleSDKVersionConflictError, 'warning'); } /** - * init client's filters + * Carry on only if we do not have errors. */ - $this->_init_filters('client'); + if (!$this->has_errors()) { + /** + * Replacing local path to gs:// for using it on StreamWrapper + */ + add_filter('upload_dir', array($this, 'filter_upload_dir'), 99); - /** - * init main filters - */ - $this->_init_filters('main'); + /** + * Stateless mode working only with GD library + */ + add_filter('wp_image_editors', array($this, 'select_wp_image_editors')); + + /** + * Init GS client + */ + global $gs_client; + if ($gs_client = $this->init_gs_client()) { + StreamWrapper::register($gs_client); + } + + /** + * init client's filters + */ + $this->_init_filters('client'); + + /** + * init main filters + */ + $this->_init_filters('main'); + } } } @@ -648,7 +702,9 @@ public function add_custom_row_actions($actions, $post, $detached) { if (!current_user_can('upload_files')) return $actions; - $sm_cloud = get_post_meta($post->ID, 'sm_cloud', 1); + $sm_cloud = apply_filters('wp_stateless_get_file', [], $post->ID); + + $sm_mode = $this->get('sm.mode'); if (!empty($sm_cloud) && $sm_mode === 'stateless') return $actions; @@ -714,7 +770,19 @@ public function api_init() { 'callback' => array($api_namespace, 'syncStop'), 'permission_callback' => array($api_namespace, 'authCheck') )); - } + + register_rest_route($route_namespace, '/batch/state', array( + 'methods' => \WP_REST_Server::READABLE, + 'callback' => array($api_namespace, 'batchState'), + 'permission_callback' => array($api_namespace, 'authCheck') + )); + + register_rest_route($route_namespace, '/batch/action', array( + 'methods' => \WP_REST_Server::CREATABLE, + 'callback' => array($api_namespace, 'batchAction'), + 'permission_callback' => array($api_namespace, 'authCheck') + )); + } /** * Metabox for media modal page @@ -723,9 +791,9 @@ public function api_init() { * @return array */ public function attachment_modal_meta_box_callback($form_fields, $post) { - - //do not show on media edit page, only on modal - if (isset($_GET['post'])) { + // Do not show on media edit page, only on modal + // Do not show if we are not in Media Library + if ( isset($_GET['post']) || wp_doing_ajax() ) { return $form_fields; } @@ -768,7 +836,7 @@ public function attachment_meta_box_callback($meta_boxes) { */ private function _prepare_data_for_metabox($meta_boxes, $post_id) { $post = get_post($post_id); - $sm_cloud = get_post_meta($post_id, 'sm_cloud', 1); + $sm_cloud = apply_filters('wp_stateless_get_file', [], $post_id, true); $sm_mode = $this->get('sm.mode'); if (empty($post)) { @@ -1173,6 +1241,9 @@ public function admin_init() { /* Attachment or upload page */ wp_register_script('wp-stateless-uploads-js', $this->path('static/scripts/wp-stateless-uploads.js', 'url'), array('jquery'), self::$version); + wp_localize_script('wp-stateless-uploads-js', 'stateless_upload', [ + 'inline_sync_nonce' => wp_create_nonce('sm_inline_sync'), + ]); /* Setup wizard styles. */ wp_register_style('wp-stateless-setup-wizard', $this->path('static/styles/wp-stateless-setup-wizard.css', 'url'), array(), self::$version); @@ -1184,10 +1255,10 @@ public function admin_init() { wp_localize_script('wp-stateless-settings', 'stateless_l10n', $this->get_l10n_data()); wp_register_style('wp-stateless-settings', $this->path('static/styles/wp-stateless-settings.css', 'url'), array(), self::$version); + wp_register_style('wp-stateless-addons', $this->path('static/styles/wp-stateless-addons.css', 'url'), array(), self::$version); + wp_register_style('wp-stateless-status', $this->path('static/styles/wp-stateless-status.css', 'url'), array(), self::$version); // Sync tab - wp_register_script('wp-stateless-angular', ud_get_stateless_media()->path('static/scripts/angular.min.js', 'url'), array(), '1.8.0', true); - wp_register_script('wp-stateless-angular-sanitize', ud_get_stateless_media()->path('static/scripts/angular-sanitize.min.js', 'url'), array('wp-stateless-angular'), '1.8.0', true); wp_register_script('wp-stateless', ud_get_stateless_media()->path('static/scripts/wp-stateless.js', 'url'), array('jquery-ui-core', 'wp-stateless-settings', 'wp-api-request'), self::$version, true); wp_localize_script('wp-stateless', 'stateless_l10n', $this->get_l10n_data()); @@ -1204,7 +1275,13 @@ public function admin_init() { $settings['key_json'] = "Currently configured via a constant."; } wp_localize_script('wp-stateless', 'wp_stateless_settings', $settings); - wp_localize_script('wp-stateless', 'wp_stateless_compatibility', Module::get_modules()); + + // Batch processes tab + wp_register_script('wp-stateless-batch', ud_get_stateless_media()->path('static/scripts/wp-stateless-batch.js', 'url'), array('wp-api-request'), self::$version, true); + wp_localize_script('wp-stateless-batch', 'wp_stateless_batch', array( + 'REST_API_TOKEN' => Utility::generate_jwt_token(['user_id' => get_current_user_id()], DAY_IN_SECONDS), + 'is_running' => BatchTaskManager::instance()->is_running(), + )); } /** @@ -1260,12 +1337,17 @@ public function admin_enqueue_scripts($hook) { wp_enqueue_script('wp-stateless-settings'); wp_enqueue_script('wp-stateless-select2'); wp_enqueue_style('wp-stateless-settings'); + wp_enqueue_style('wp-stateless-addons'); + wp_enqueue_style('wp-stateless-status'); // Sync tab - wp_enqueue_script('wp-stateless-angular'); - wp_enqueue_script('wp-stateless-angular-sanitize'); wp_enqueue_script('wp-stateless'); + // Data updates + wp_enqueue_script('jquery-ui-dialog'); + wp_enqueue_style('wp-jquery-ui-dialog'); + wp_enqueue_script('wp-stateless-batch'); + wp_enqueue_style('wp-pointer'); wp_enqueue_script('wp-pointer'); @@ -1275,7 +1357,7 @@ public function admin_enqueue_scripts($hook) { 'title' => sprintf(__("Stateless and Ephemeral modes enables and requires the Cache-Busting option.", ud_get_stateless_media()->domain)), 'message' => sprintf(__("WordPress looks at local files to prevent files with the same filenames. Since Stateless mode bypasses this check, there is a potential for files to be stored with the same file name. We enforce the Cache-Busting option to prevent this. - Override with the %s constant.", ud_get_stateless_media()->domain), "https://wp-stateless.github.io/docs/constants/#wp_stateless_media_cache_busting", "WP_STATELESS_MEDIA_CACHE_BUSTING"), + Override with the %s constant.", ud_get_stateless_media()->domain), "https://stateless.udx.io/docs/constants/#wp_stateless_media_cache_busting", "WP_STATELESS_MEDIA_CACHE_BUSTING"), ); echo " - diff --git a/vendor/udx/lib-settings/static/views/upgrade-splash.xhtml b/vendor/udx/lib-settings/static/views/upgrade-splash.xhtml deleted file mode 100644 index a26335535..000000000 --- a/vendor/udx/lib-settings/static/views/upgrade-splash.xhtml +++ /dev/null @@ -1,121 +0,0 @@ -
-
-
-
- icon goes here -

title goes here

-
-
-
-
- - -
-
-
-

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

Welcome to WP-Property version something something

-
-

Nam consectetuer. Sed aliquam, nunc eget euismod ullamcorper, lectus nunc ullamcorper orci, fermentum bibendum enim nibh eget ipsum. Donec porttitor ligula eu dolor. Maecenas vitae nulla consequat libero cursus venenatis. Nam magna enim, accumsan eu, blandit sed, blandit a, eros.

-
-
-
-
- -
-
- -
-
    -
  • My listings are
    - - -
    , configure my listings to use local currency and formatting.
  • -
  • My role is best described as a
    - - -
    on this project.
  • -
  • I am planning to use this website to showcase the following types of listings:
    - - -
  • -
-
- -
- -
-
    -
  • -
  • -
  • -
-
-
- -
-
- Some miscellaneous options -
Nam consectetuer. Sed aliquam, nunc eget euismod ullamcorper, lectus nunc ullamcorper orci, fermentum bibendum enim nibh eget ipsum. Donec porttitor ligula eu dolor.
-
-
-
    -
  • -
  • -
  • -
  • -
-
-
- - - - -
-
- - - -
-
-
- -
-
-
-
    -
  • Premium Features you might like.
  • -
  • XML Property Importer

    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi commodo, ipsum sed pharetra gravida, orci magna rhoncus neque, id pulvinar odio lorem non turpis. Nullam sit amet enim. Suspendisse id velit vitae ligula volutpat condimentum. Aliquam erat volutpat. Sed quis velit. Nulla facilisi. Nulla libero. Vivamus pharetra posuere sapien.

  • -
  • XML Property Importer

    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi commodo, ipsum sed pharetra gravida, orci magna rhoncus neque, id pulvinar odio lorem non turpis. Nullam sit amet enim. Suspendisse id velit vitae ligula volutpat condimentum. Aliquam erat volutpat. Sed quis velit. Nulla facilisi. Nulla libero. Vivamus pharetra posuere sapien.

  • -
  • XML Property Importer

    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi commodo, ipsum sed pharetra gravida, orci magna rhoncus neque, id pulvinar odio lorem non turpis. Nullam sit amet enim. Suspendisse id velit vitae ligula volutpat condimentum. Aliquam erat volutpat. Sed quis velit. Nulla facilisi. Nulla libero. Vivamus pharetra posuere sapien.

  • -
- -
-
-
-
-
\ No newline at end of file diff --git a/vendor/udx/lib-settings/test/basic.php b/vendor/udx/lib-settings/test/basic.php deleted file mode 100644 index a372ca990..000000000 --- a/vendor/udx/lib-settings/test/basic.php +++ /dev/null @@ -1,36 +0,0 @@ - "options", - "key" => "settings_test", - "format" => "object" -)); - -$settings->set( 'make', 'Chevy' ); -$settings->set( 'model', 'Tahoe' ); -$settings->set( 'features', array( - 'ac', - 'stuff' -)); - -$settings->set( 'features', array( - 'dvd', - 'sunroof' -)); - -$settings->set( 'options', array( - "rims" => '24', - "towing" => true, - "onstar" => 'active' -)); - -$settings->set( 'options', array( - "gps" => 'standard' -)); - -//echo '
get all:
' . print_r( $settings->get(), true ) . '
'; -echo '
get make: ' . print_r( $settings->get( 'make' ), true ); -echo '
get options.gps: ' . print_r( $settings->get( 'options.gps' ), true ); -echo '
get features: ' . print_r( $settings->get( 'features' ), true ); -die( '
get all' . print_r( $settings->get(), true ) . '
' ); diff --git a/vendor/udx/lib-settings/test/mocha.opts b/vendor/udx/lib-settings/test/mocha.opts deleted file mode 100644 index f1d544e17..000000000 --- a/vendor/udx/lib-settings/test/mocha.opts +++ /dev/null @@ -1,37 +0,0 @@ -REPORTER = list -JSON_FILE = static/all.json -HTML_FILE = static/coverage.html - -test-all: - clean - document - lib-cov - test-code - -document: - yuidoc -q - -test-code: - @NODE_ENV=test mocha \ - --timeout 200 \ - --ui exports \ - --reporter $(REPORTER) \ - test/*.js - -test-cov: - lib-cov - @APP_COVERAGE=1 $(MAKE) test \ - REPORTER=html-cov > $(HTML_FILE) - -lib-cov: - jscoverage lib static/lib-cov - -clean: - rm -fr static/lib-cov - rm -fr static/assets - rm -fr static/classes - rm -fr static/files - rm -fr static/modules - rm -f static/api.js - rm -f static/data.json - rm -f static/index.html diff --git a/vendor/udx/lib-ud-api-client/changes.md b/vendor/udx/lib-ud-api-client/changes.md new file mode 100644 index 000000000..8faaf0d15 --- /dev/null +++ b/vendor/udx/lib-ud-api-client/changes.md @@ -0,0 +1,11 @@ +### 1.2.4 + +* Require user to be logged in while dismissing Admin Panel notices. + +### 1.2.3 + +* Improve security while processing AJAX requests in Admin Panel. + +### 1.2.2 + +* Remove dependency from `udx/lib-utility`. diff --git a/vendor/udx/lib-ud-api-client/gruntfile.js b/vendor/udx/lib-ud-api-client/gruntfile.js index e1b95dc30..4deb0ebf1 100644 --- a/vendor/udx/lib-ud-api-client/gruntfile.js +++ b/vendor/udx/lib-ud-api-client/gruntfile.js @@ -2,7 +2,7 @@ * Build Plugin. * * @author potanin@UD - * @version 1.2.1 + * @version 1.2.4 * @param grunt */ module.exports = function( grunt ) { diff --git a/vendor/udx/lib-ud-api-client/lib/classes/class-admin.php b/vendor/udx/lib-ud-api-client/lib/classes/class-admin.php index e45a87a54..6cbdeb0b9 100644 --- a/vendor/udx/lib-ud-api-client/lib/classes/class-admin.php +++ b/vendor/udx/lib-ud-api-client/lib/classes/class-admin.php @@ -283,7 +283,7 @@ public function process_request () { $status = 'true'; } - $redirect_url = \UsabilityDynamics\Utility::current_url( array( 'type' => urlencode( $type ), 'status' => urlencode( $status ) ), array( 'action', 'filepath', '_wpnonce' ) ); + $redirect_url = Utility::current_url( array( 'type' => urlencode( $type ), 'status' => urlencode( $status ) ), array( 'action', 'filepath', '_wpnonce' ) ); wp_safe_redirect( $redirect_url ); exit; } @@ -472,7 +472,7 @@ public function load_updater_instances () { } //echo "
"; print_r( $v ); echo "
"; //die(); if( !empty( $api_key ) ) { - new License_Checker( array( + new Update_Checker( array( 'type' => $this->type, 'upgrade_url' => $this->api_url, 'name' => $v[ 'product_name' ], diff --git a/vendor/udx/lib-ud-api-client/lib/classes/class-bootstrap.php b/vendor/udx/lib-ud-api-client/lib/classes/class-bootstrap.php index 74e359cc2..ced9fdeb5 100644 --- a/vendor/udx/lib-ud-api-client/lib/classes/class-bootstrap.php +++ b/vendor/udx/lib-ud-api-client/lib/classes/class-bootstrap.php @@ -18,7 +18,7 @@ class Bootstrap extends Scaffold { /** * */ - public static $version = '1.2.1'; + public static $version = '1.2.4'; /** * diff --git a/vendor/udx/lib-ud-api-client/lib/classes/class-licenses-table.php b/vendor/udx/lib-ud-api-client/lib/classes/class-licenses-table.php index e2a5717dc..64258aca4 100644 --- a/vendor/udx/lib-ud-api-client/lib/classes/class-licenses-table.php +++ b/vendor/udx/lib-ud-api-client/lib/classes/class-licenses-table.php @@ -138,7 +138,7 @@ public function column_product_version ( $item ) { public function column_product_status ( $item ) { $response = ''; if ( 'active' == $item['product_status'] ) { - $deactivate_url = wp_nonce_url(\UsabilityDynamics\Utility::current_url( array( + $deactivate_url = wp_nonce_url(Utility::current_url( array( 'action' => 'deactivate-product', 'filepath' => urlencode( $item['product_file_path'] ), ) ), 'bulk-licenses' ); diff --git a/vendor/udx/lib-ud-api-client/lib/classes/class-license-checker.php b/vendor/udx/lib-ud-api-client/lib/classes/class-update-checker.php similarity index 82% rename from vendor/udx/lib-ud-api-client/lib/classes/class-license-checker.php rename to vendor/udx/lib-ud-api-client/lib/classes/class-update-checker.php index 491aa55c1..8f96ebeff 100644 --- a/vendor/udx/lib-ud-api-client/lib/classes/class-license-checker.php +++ b/vendor/udx/lib-ud-api-client/lib/classes/class-update-checker.php @@ -1,23 +1,19 @@ type == 'plugin' ) { - //** Check For Plugin License Updates */ - add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'license_check' ) ); + //** Check For Plugin Updates */ + add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'update_check' ) ); //** Check For Plugin/Theme Information to display on the update details page */ add_filter( 'plugins_api', array( $this, 'request' ), 10, 3 ); } /** - * Check For Theme License Updates + * Theme Updates */ elseif ( $this->type == 'theme' ) { - add_filter( 'pre_set_site_transient_update_themes', array( $this, 'license_check' ) ); + add_filter( 'pre_set_site_transient_update_themes', array( $this, 'update_check' ) ); } add_action( 'wp_ajax_ud_api_dismiss', array( $this, 'dismiss_notices' ) ); @@ -189,14 +185,14 @@ private function create_upgrade_api_url( $args ) { } /** - * Check for License updates against the remote server. + * Check for updates against the remote server. * * @access public * @since 1.0.0 * @param object $transient * @return object $transient */ - public function license_check( $transient ) { + public function update_check( $transient ) { //** Check if the transient contains the 'checked' information */ //** If no, just return its value without hacking it */ @@ -223,6 +219,38 @@ public function license_check( $transient ) { //** Displays an admin error message in the WordPress dashboard */ $this->check_response_for_errors( $response ); + //** Set version variables */ + if ( isset( $response ) && is_object( $response ) && $response !== false ) { + //** New plugin version from the API */ + $new_ver = (string)$response->new_version; + //** Current installed plugin version */ + $curr_ver = (string)$this->software_version; + //$curr_ver = (string)$transient->checked[$this->name]; + } + + //** If there is a new version, modify the transient to reflect an update is available */ + if ( isset( $new_ver ) && isset( $curr_ver ) ) { + if ( $response !== false && version_compare( $new_ver, $curr_ver, '>' ) ) { + if( $this->type == 'plugin' ) { + if( isset( $response->slug ) ) { + $response->slug = sanitize_title( $response->slug ); + } + $transient->response[$this->file] = $response; + } else { + $theme = basename( dirname( $this->file ) ); + $response = (array)$response; + if( empty( $response[ 'url' ] ) ) { + $response[ 'url' ] = !empty( $this->changelog ) ? $this->changelog : 'https://www.usabilitydynamics.com'; + } + $transient->response[$theme] = (array)$response; + } + + } + } + + //echo "
"; print_r( $this ); echo "
"; die(); + //echo "
"; print_r( $transient ); echo "
"; die(); + return $transient; } @@ -321,19 +349,20 @@ public function check_response_for_errors( $response ) { $plugins = get_plugins(); $name = isset( $plugins[$this->name] ) ? $plugins[$this->name]['Name'] : $this->name; + $nonce = wp_create_nonce( 'ud_api_dismiss' ); if ( isset( $response->errors['no_key'] ) && $response->errors['no_key'] == 'no_key' && isset( $response->errors['no_subscription'] ) && $response->errors['no_subscription'] == 'no_subscription' ) { $no_key_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_no_key', '' ); $show_no_key_error = $this->check_dismiss_time( $no_key_dismissed ); if( $show_no_key_error ) { - $this->errors[] = sprintf( __( 'A license key for %s could not be found. Maybe you forgot to enter a license key when setting up %s, or the key was deactivated in your account. You can reactivate or purchase a license key from your account Licences | dismiss.', $this->text_domain ), $name, $name, $this->renew_license_url, sanitize_key( $name ) ); + $this->errors[] = sprintf( __( 'A license key for %s could not be found. Maybe you forgot to enter a license key when setting up %s, or the key was deactivated in your account. You can reactivate or purchase a license key from your account Licences | dismiss.', $this->text_domain ), $name, $name, $this->renew_license_url, sanitize_key( $name ), $nonce ); } $no_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_no_subscription', '' ); $show_no_subscription_error = $this->check_dismiss_time( $no_subscription_dismissed ); if( $show_no_subscription_error ) { - $this->errors[] = sprintf( __( 'A subscription for %s could not be found. You can purchase a subscription from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) ); + $this->errors[] = sprintf( __( 'A subscription for %s could not be found. You can purchase a subscription from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ); } } else if ( isset( $response->errors['exp_license'] ) && $response->errors['exp_license'] == 'exp_license' ) { @@ -341,7 +370,7 @@ public function check_response_for_errors( $response ) { $exp_license_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_exp_license', '' ); $show_exp_license_error = $this->check_dismiss_time( $exp_license_dismissed ); if( $show_exp_license_error ) { - $this->errors[] = sprintf( __( 'The license key for %s has expired. You can reactivate or get a license key from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) ); + $this->errors[] = sprintf( __( 'The license key for %s has expired. You can reactivate or get a license key from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ); } } else if ( isset( $response->errors['hold_subscription'] ) && $response->errors['hold_subscription'] == 'hold_subscription' ) { @@ -349,7 +378,7 @@ public function check_response_for_errors( $response ) { $hold_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_hold_subscription', '' ); $show_hold_subscription_error = $this->check_dismiss_time( $hold_subscription_dismissed ); if( $show_hold_subscription_error ) { - $this->errors[] = sprintf( __( 'The subscription for %s is on-hold. You can reactivate the subscription from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) ); + $this->errors[] = sprintf( __( 'The subscription for %s is on-hold. You can reactivate the subscription from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ); } } else if ( isset( $response->errors['cancelled_subscription'] ) && $response->errors['cancelled_subscription'] == 'cancelled_subscription' ) { @@ -357,7 +386,7 @@ public function check_response_for_errors( $response ) { $cancelled_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_cancelled_subscription', '' ); $show_cancelled_subscription_error = $this->check_dismiss_time( $cancelled_subscription_dismissed ); if( $show_cancelled_subscription_error ) { - $this->errors[] = sprintf( __( 'The subscription for %s has been cancelled. You can renew the subscription from your account dashboard. A new license key will be emailed to you after your order has been completed. dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) ); + $this->errors[] = sprintf( __( 'The subscription for %s has been cancelled. You can renew the subscription from your account dashboard. A new license key will be emailed to you after your order has been completed. dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ); } } else if ( isset( $response->errors['exp_subscription'] ) && $response->errors['exp_subscription'] == 'exp_subscription' ) { @@ -365,7 +394,7 @@ public function check_response_for_errors( $response ) { $exp_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_exp_subscription', '' ); $show_exp_subscription_error = $this->check_dismiss_time( $exp_subscription_dismissed ); if( $show_exp_subscription_error ) { - $this->errors[] = sprintf( __( 'The subscription for %s has expired. You can reactivate the subscription from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) ) ; + $this->errors[] = sprintf( __( 'The subscription for %s has expired. You can reactivate the subscription from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ) ; } } else if ( isset( $response->errors['suspended_subscription'] ) && $response->errors['suspended_subscription'] == 'suspended_subscription' ) { @@ -373,7 +402,7 @@ public function check_response_for_errors( $response ) { $suspended_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_suspended_subscription', '' ); $show_suspended_subscription_error = $this->check_dismiss_time( $suspended_subscription_dismissed ); if( $show_suspended_subscription_error ) { - $this->errors[] = sprintf( __( 'The subscription for %s has been suspended. You can reactivate the subscription from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) ) ; + $this->errors[] = sprintf( __( 'The subscription for %s has been suspended. You can reactivate the subscription from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ) ; } } else if ( isset( $response->errors['pending_subscription'] ) && $response->errors['pending_subscription'] == 'pending_subscription' ) { @@ -381,7 +410,7 @@ public function check_response_for_errors( $response ) { $pending_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_pending_subscription', '' ); $show_pending_subscription_error = $this->check_dismiss_time( $pending_subscription_dismissed ); if( $show_pending_subscription_error ) { - $this->errors[] = sprintf( __( 'The subscription for %s is still pending. You can check on the status of the subscription from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) ) ; + $this->errors[] = sprintf( __( 'The subscription for %s is still pending. You can check on the status of the subscription from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ) ; } } else if ( isset( $response->errors['trash_subscription'] ) && $response->errors['trash_subscription'] == 'trash_subscription' ) { @@ -389,7 +418,7 @@ public function check_response_for_errors( $response ) { $trash_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_trash_subscription', '' ); $show_trash_subscription_error = $this->check_dismiss_time( $trash_subscription_dismissed ); if( $show_trash_subscription_error ) { - $this->errors[] = sprintf( __( 'The subscription for %s has been placed in the trash and will be deleted soon. You can get a new subscription from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) ) ; + $this->errors[] = sprintf( __( 'The subscription for %s has been placed in the trash and will be deleted soon. You can get a new subscription from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ) ; } } else if ( isset( $response->errors['no_subscription'] ) && $response->errors['no_subscription'] == 'no_subscription' ) { @@ -397,7 +426,7 @@ public function check_response_for_errors( $response ) { $no_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_no_subscription', '' ); $show_no_subscription_error = $this->check_dismiss_time( $no_subscription_dismissed ); if( $show_no_subscription_error ) { - $this->errors[] = sprintf( __( 'A subscription for %s could not be found. You can get a subscription from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) ); + $this->errors[] = sprintf( __( 'A subscription for %s could not be found. You can get a subscription from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ); } } else if ( isset( $response->errors['no_activation'] ) && $response->errors['no_activation'] == 'no_activation' ) { @@ -405,7 +434,7 @@ public function check_response_for_errors( $response ) { $no_activation_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_no_activation', '' ); $show_no_activation_error = $this->check_dismiss_time( $no_activation_dismissed ); if( $show_no_activation_error ) { - $this->errors[] = sprintf( __( '%s has not been activated. Go to the settings page and enter the license key and license email to activate %s. dismiss.', $this->text_domain ), $name, $name, sanitize_key( $name ) ) ; + $this->errors[] = sprintf( __( '%s has not been activated. Go to the settings page and enter the license key and license email to activate %s. dismiss.', $this->text_domain ), $name, $name, sanitize_key( $name ), $nonce ) ; } } else if ( isset( $response->errors['no_key'] ) && $response->errors['no_key'] == 'no_key' ) { @@ -413,7 +442,7 @@ public function check_response_for_errors( $response ) { $no_key_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_no_key', '' ); $show_no_key_error = $this->check_dismiss_time( $no_key_dismissed ); if( $show_no_key_error ) { - $this->errors[] = sprintf( __( 'A license key for %s could not be found. Maybe you forgot to enter a license key when setting up %s, or the key was deactivated in your account. You can reactivate or get a license key from your account Licences | dismiss.', $this->text_domain ), $name, $name, $this->renew_license_url, sanitize_key( $name ) ); + $this->errors[] = sprintf( __( 'A license key for %s could not be found. Maybe you forgot to enter a license key when setting up %s, or the key was deactivated in your account. You can reactivate or get a license key from your account Licences | dismiss.', $this->text_domain ), $name, $name, $this->renew_license_url, sanitize_key( $name ), $nonce ); } } else if ( isset( $response->errors['download_revoked'] ) && $response->errors['download_revoked'] == 'download_revoked' ) { @@ -421,7 +450,7 @@ public function check_response_for_errors( $response ) { $download_revoked_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_download_revoked', '' ); $show_download_revoked_error = $this->check_dismiss_time( $download_revoked_dismissed ); if( $show_download_revoked_error ) { - $this->errors[] = sprintf( __( 'Download permission for %s has been revoked possibly due to a license key or subscription expiring. You can reactivate or get a license key from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) ) ; + $this->errors[] = sprintf( __( 'Download permission for %s has been revoked possibly due to a license key or subscription expiring. You can reactivate or get a license key from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ) ; } } else if ( isset( $response->errors['switched_subscription'] ) && $response->errors['switched_subscription'] == 'switched_subscription' ) { @@ -429,7 +458,7 @@ public function check_response_for_errors( $response ) { $switched_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_switched_subscription', '' ); $show_switched_subscription_error = $this->check_dismiss_time( $switched_subscription_dismissed ); if( $show_switched_subscription_error ) { - $this->errors[] = sprintf( __( 'You changed the subscription for %s, so you will need to enter your new API License Key in the settings page. The License Key should have arrived in your email inbox, if not you can get it by logging into your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) ) ; + $this->errors[] = sprintf( __( 'You changed the subscription for %s, so you will need to enter your new API License Key in the settings page. The License Key should have arrived in your email inbox, if not you can get it by logging into your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ) ; } } @@ -471,6 +500,7 @@ public function print_scripts() { var data = { action: 'ud_api_dismiss', key: _this.data('key'), + _ajax_nonce: _this.data('nonce'), } jQuery.post( "", data, function ( result_data ) { @@ -513,21 +543,31 @@ public function check_dismiss_time( $time = '' ) { * @throws \Exception */ public function dismiss_notices(){ + check_ajax_referer('ud_api_dismiss'); + + if ( !is_user_logged_in() ) { + wp_send_json_error( array( 'error' => __( 'You are not allowed to do this action.', $this->text_domain ) ) ); + } + $response = array( 'success' => '0', 'error' => __( 'There was an error in request.', $this->text_domain ), ); + $error = false; - if( empty($_POST['key']) ) { - $response['error'] = __( 'Invalid key', $this->text_domain ); + $option_key = isset($_POST['key']) ? sanitize_key($_POST['key']) : ''; + + if ( strpos($option_key, 'dismissed_') !== 0 ) { + $response['error'] = __( 'Invalid key', $this->domain ); $error = true; } - - if ( ! $error && update_option( ( $_POST['key'] ), time() ) ) { + + if ( !$error && update_option( $option_key, time() ) ) { $response['success'] = '1'; + $response['error'] = null; } - + wp_send_json( $response ); } diff --git a/vendor/udx/lib-ud-api-client/lib/classes/class-utility.php b/vendor/udx/lib-ud-api-client/lib/classes/class-utility.php new file mode 100644 index 000000000..8e859092c --- /dev/null +++ b/vendor/udx/lib-ud-api-client/lib/classes/class-utility.php @@ -0,0 +1,53 @@ + $v ) { + if( is_string( $v ) ) $url = add_query_arg( $k, $v, $url ); + } + } + + if( !empty( $except_args ) ) { + foreach( (array) $except_args as $arg ) { + if( is_string( $arg ) ) $url = remove_query_arg( $arg, $url ); + } + } + + return $url; + } + + } + + } + +} \ No newline at end of file diff --git a/vendor/udx/lib-ud-api-client/package.json b/vendor/udx/lib-ud-api-client/package.json index bcd255c4d..938163b99 100644 --- a/vendor/udx/lib-ud-api-client/package.json +++ b/vendor/udx/lib-ud-api-client/package.json @@ -1,6 +1,6 @@ { "name": "lib-ud-api-client", - "version": "1.2.1", + "version": "1.2.4", "description": "UD Client for WooCommerce API Manager", "repository": { "type": "git", diff --git a/vendor/udx/lib-ud-api-client/readme.md b/vendor/udx/lib-ud-api-client/readme.md index c6f4aa314..b1bac3db4 100644 --- a/vendor/udx/lib-ud-api-client/readme.md +++ b/vendor/udx/lib-ud-api-client/readme.md @@ -80,9 +80,9 @@ $api->deactivate( array( ), $product ); ``` -#### License Checker +#### Update Checker -License Checker is being initialized only for installed and activated plugins / theme. +Update Checker is being initialized only for installed and activated plugins / theme. Responses are being cached via transient up to one hour. @@ -92,19 +92,19 @@ Attention, be sure, that temp download link expires more then in one hour ( UD g Adds the following filters ```php -$license_checker = new UsabilityDynamics\UD_API\License_Checker($args); +$update_checker = new UsabilityDynamics\UD_API\Update_Checker($args); -//** Check For Plugin License Updates */ -add_filter( 'pre_set_site_transient_update_plugins', array( $license_checker, 'license_check' ) ); +//** Check For Plugin Updates */ +add_filter( 'pre_set_site_transient_update_plugins', array( $update_checker, 'update_check' ) ); //** Check For Plugin Information to display on the update details page */ -add_filter( 'plugins_api', array( $license_checker, 'request' ), 10, 3 ); +add_filter( 'plugins_api', array( $update_checker, 'request' ), 10, 3 ); ``` ##### Theme Adds the following filters ```php -$license_checker = new UsabilityDynamics\UD_API\License_Checker($args); +$update_checker = new UsabilityDynamics\UD_API\Update_Checker($args); -//** Check For Theme License Updates */ -add_filter( 'pre_set_site_transient_update_themes', array( $license_checker, 'license_check' ) ); +//** Check For Plugin Updates */ +add_filter( 'pre_set_site_transient_update_themes', array( $update_checker, 'update_check' ) ); diff --git a/vendor/udx/lib-utility/.gitignore b/vendor/udx/lib-utility/.gitignore deleted file mode 100644 index f01ac072f..000000000 --- a/vendor/udx/lib-utility/.gitignore +++ /dev/null @@ -1,20 +0,0 @@ -temp -node_modules -npm-debug.log -static/codex -vendor -.svn -.idea -.idea/workspace.xml -.DS_Store -.dynamic -.Trashes -*.sublime-project -*.sublime-workspace -*.seed -*.log -*.csv -*.dat -*.out -*.pid -*.gz \ No newline at end of file diff --git a/vendor/udx/lib-utility/.gitmodules b/vendor/udx/lib-utility/.gitmodules deleted file mode 100644 index ff8dbced6..000000000 --- a/vendor/udx/lib-utility/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "static/wiki"] - path = static/wiki - url = git@github.com:UsabilityDynamics/lib-utility.wiki.git diff --git a/vendor/udx/lib-utility/composer.json b/vendor/udx/lib-utility/composer.json deleted file mode 100644 index 02f995949..000000000 --- a/vendor/udx/lib-utility/composer.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "udx/lib-utility", - "keywords": [ - "utility", - "process", - "job" - ], - "version": "0.4.0", - "type": "library", - "minimum-stability": "dev", - "repositories": [ - { - "type": "composer", - "url": "https://repository.usabilitydynamics.com" - } - ], - "require": {}, - "require-dev": { - "phpunit/phpunit": "4.1.*" - }, - "autoload": { - "classmap": [ "lib" ] - }, - "authors": [ - { - "name": "Andy Potanin", - "email": "andy.potanin@usabilitydynamics.com", - "homepage": "https://www.usabilitydynamics.com", - "role": "Developer" - }, - { - "name": "Maxim Peshkov", - "email": "maxim.peshkov@usabilitydynamics.com", - "homepage": "https://www.usabilitydynamics.com", - "role": "Developer" - }, - { - "name": "Anton Korotkov", - "email": "anton.korotkov@usabilitydynamics.com", - "homepage": "https://www.usabilitydynamics.com", - "role": "Developer" - } - ], - "extra": { - "installer-name": "lib-utility", - "component": { - "name": "utility", - "scripts": [ "scripts/*.js" ] - } - }, - "license": "MIT" -} diff --git a/vendor/udx/lib-utility/composer.lock b/vendor/udx/lib-utility/composer.lock deleted file mode 100644 index 2f960f3c0..000000000 --- a/vendor/udx/lib-utility/composer.lock +++ /dev/null @@ -1,720 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" - ], - "hash": "859a04bbecf3bef6e6d4e7cefc281f0f", - "packages": [ - - ], - "packages-dev": [ - { - "name": "phpunit/php-code-coverage", - "version": "2.0.x-dev", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "99a530363b6cf50efc18e1a7cbb12d42b6b22a0b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/99a530363b6cf50efc18e1a7cbb12d42b6b22a0b", - "reference": "99a530363b6cf50efc18e1a7cbb12d42b6b22a0b", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-file-iterator": "~1.3.1", - "phpunit/php-text-template": "~1.2.0", - "phpunit/php-token-stream": "~1.2.2", - "sebastian/environment": "~1.0.0", - "sebastian/version": "~1.0.3" - }, - "require-dev": { - "ext-xdebug": ">=2.1.4", - "phpunit/phpunit": "~4.0.14" - }, - "suggest": { - "ext-dom": "*", - "ext-xdebug": ">=2.2.1", - "ext-xmlwriter": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "time": "2014-05-19 02:25:07" - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.3.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb", - "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "File/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "time": "2013-10-10 15:34:57" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", - "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "Text/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "time": "2014-01-30 17:20:04" - }, - { - "name": "phpunit/php-timer", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c", - "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "PHP/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "time": "2013-08-02 07:42:54" - }, - { - "name": "phpunit/php-token-stream", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "955c24b708f8bfd6a05f303217a8dac3a443d531" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/955c24b708f8bfd6a05f303217a8dac3a443d531", - "reference": "955c24b708f8bfd6a05f303217a8dac3a443d531", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2-dev" - } - }, - "autoload": { - "classmap": [ - "PHP/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "time": "2014-05-12 05:34:42" - }, - { - "name": "phpunit/phpunit", - "version": "4.1.x-dev", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "069d57f964bb6a0f2cd360cfcf231d767e2996bb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/069d57f964bb6a0f2cd360cfcf231d767e2996bb", - "reference": "069d57f964bb6a0f2cd360cfcf231d767e2996bb", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=5.3.3", - "phpunit/php-code-coverage": "~2.0", - "phpunit/php-file-iterator": "~1.3.1", - "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": "~1.0.2", - "phpunit/phpunit-mock-objects": "~2.1", - "sebastian/comparator": "~1.0", - "sebastian/diff": "~1.1", - "sebastian/environment": "~1.0", - "sebastian/exporter": "~1.0", - "sebastian/version": "~1.0", - "symfony/yaml": "~2.0" - }, - "suggest": { - "phpunit/php-invoker": "~1.1" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "", - "../../symfony/yaml/" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "http://www.phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "time": "2014-05-13 14:01:48" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "4dada9d8762055e292d79142adbdde56c113b21a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/4dada9d8762055e292d79142adbdde56c113b21a", - "reference": "4dada9d8762055e292d79142adbdde56c113b21a", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-text-template": "~1.2" - }, - "require-dev": { - "phpunit/phpunit": "4.2.*@dev" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "time": "2014-05-09 09:09:30" - }, - { - "name": "sebastian/comparator", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "e54a01c0da1b87db3c5a3c4c5277ddf331da4aef" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/e54a01c0da1b87db3c5a3c4c5277ddf331da4aef", - "reference": "e54a01c0da1b87db3c5a3c4c5277ddf331da4aef", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "sebastian/diff": "~1.1", - "sebastian/exporter": "~1.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "http://www.github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "time": "2014-05-11 23:00:21" - }, - { - "name": "sebastian/diff", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "ac84cfdec593945f36f24074d6ea17d296e86f76" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ac84cfdec593945f36f24074d6ea17d296e86f76", - "reference": "ac84cfdec593945f36f24074d6ea17d296e86f76", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "Diff implementation", - "homepage": "http://www.github.com/sebastianbergmann/diff", - "keywords": [ - "diff" - ], - "time": "2014-05-12 05:21:40" - }, - { - "name": "sebastian/environment", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "10c7467da0622f7848cc5cadc0828c3359254df4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/10c7467da0622f7848cc5cadc0828c3359254df4", - "reference": "10c7467da0622f7848cc5cadc0828c3359254df4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "time": "2014-05-04 17:56:05" - }, - { - "name": "sebastian/exporter", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "eb54a69388e5b7ea48561a65588f067fdda0c886" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/eb54a69388e5b7ea48561a65588f067fdda0c886", - "reference": "eb54a69388e5b7ea48561a65588f067fdda0c886", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "time": "2014-05-05 08:31:02" - }, - { - "name": "sebastian/version", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43", - "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43", - "shasum": "" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "time": "2014-03-07 15:35:33" - }, - { - "name": "symfony/yaml", - "version": "dev-master", - "target-dir": "Symfony/Component/Yaml", - "source": { - "type": "git", - "url": "https://github.com/symfony/Yaml.git", - "reference": "2158ca824145bd01877f58c987aff828bccddefa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/2158ca824145bd01877f58c987aff828bccddefa", - "reference": "2158ca824145bd01877f58c987aff828bccddefa", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Yaml\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Yaml Component", - "homepage": "http://symfony.com", - "time": "2014-05-16 14:25:18" - } - ], - "aliases": [ - - ], - "minimum-stability": "dev", - "stability-flags": [ - - ], - "platform": [ - - ], - "platform-dev": [ - - ] -} diff --git a/vendor/udx/lib-utility/gruntfile.js b/vendor/udx/lib-utility/gruntfile.js deleted file mode 100644 index 9bc70cf74..000000000 --- a/vendor/udx/lib-utility/gruntfile.js +++ /dev/null @@ -1,229 +0,0 @@ -/** - * Library Build. - * - * @author potanin@UD - * @version 1.2.0 - * @param grunt - */ -module.exports = function buildLibrary( grunt ) { - - // Require Utility Modules. - var joinPath = require( 'path' ).join; - var findup = require( 'findup-sync' ); - - // Determine Paths. - var _paths = { - composer: findup( 'composer.json' ), - vendor: findup( 'vendor' ), - phpTests: findup( 'test/php' ), - jsTests: findup( 'test/js' ), - autoload: findup( 'vendor/autoload.php' ) || findup( '**/autoload.php' ) - }; - - grunt.initConfig({ - - // Read Composer File. - package: grunt.file.readJSON( _paths.composer ), - - // PHP Unit Tests. - phpunit: { - classes: { - dir: joinPath( _paths.phpTests, '*.php' ) - }, - options: { - bin: 'phpunit', - bootstrap: _paths.autoload, - colors: true - } - }, - - // Generate Documentation. - yuidoc: { - compile: { - name: '<%= package.name %>', - description: '<%= package.description %>', - version: '<%= package.version %>', - url: '<%= package.homepage %>', - options: { - paths: [ 'lib', 'scripts' ], - outdir: 'static/codex/' - } - } - }, - - // Compile LESS. - less: { - development: { - options: { - relativeUrls: true - }, - files: { - //'styles/requires.dev.css': [ 'styles/src/requires.less' ] - } - }, - production: { - options: { - yuicompress: true, - relativeUrls: true - }, - files: { - //'styles/requires.css': [ 'styles/src/requires.less' ] - } - } - }, - - // Development Watch. - watch: { - options: { - interval: 100, - debounceDelay: 500 - }, - php: { - files: [ 'lib/class-*.php' ], - tasks: [ 'phpunit' ] - }, - less: { - files: [ 'styles/src/*.*' ], - tasks: [ 'less' ] - }, - js: { - files: [ 'scripts/src/*.*' ], - tasks: [ 'uglify' ] - } - }, - - // Uglify Scripts. - uglify: { - development: { - options: { - preserveComments: true, - beautify: true, - wrap: false - }, - files: [ - { - expand: true, - cwd: 'scripts/src', - src: [ '*.js' ], - dest: 'scripts' - } - ] - }, - production: { - options: { - preserveComments: false, - wrap: false - }, - files: [ - { - expand: true, - cwd: 'scripts/src', - src: [ '*.js' ], - dest: 'scripts' - } - ] - } - }, - - // Generate Markdown. - markdown: { - all: { - files: [ - { - expand: true, - src: 'readme.md', - dest: 'static/', - ext: '.html' - } - ], - options: { - markdownOptions: { - gfm: true, - codeLines: { - before: '', - after: '' - } - } - } - } - }, - - // Clean for Development. - clean: { - all: [ - "vendor", - "static/readme.md", - "composer.lock", - "styles/*.css", - "scripts/*.js" - ], - update: [ - "composer.lock" - ] - }, - - // CLI Commands. - shell: { - update: { - options: { - stdout: true - }, - command: 'composer update --prefer-source' - } - }, - - // Coverage Tests. - mochacov: { - options: { - reporter: 'list', - requires: [ 'should' ] - }, - all: [ joinPath( _paths.jsTests, '*.js' ) ] - }, - - // Usage Tests. - mochacli: { - options: { - requires: [ 'should' ], - reporter: 'list', - ui: 'exports', - bail: false - }, - all: [ joinPath( _paths.jsTests, '*.js' ) ] - } - - }); - - // Load NPM Tasks. - grunt.loadNpmTasks( 'grunt-markdown' ); - grunt.loadNpmTasks( 'grunt-requirejs' ); - grunt.loadNpmTasks( 'grunt-contrib-yuidoc' ); - grunt.loadNpmTasks( 'grunt-contrib-uglify' ); - grunt.loadNpmTasks( 'grunt-contrib-watch' ); - grunt.loadNpmTasks( 'grunt-contrib-less' ); - grunt.loadNpmTasks( 'grunt-contrib-concat' ); - grunt.loadNpmTasks( 'grunt-contrib-clean' ); - grunt.loadNpmTasks( 'grunt-shell' ); - grunt.loadNpmTasks( 'grunt-mocha-cli' ); - grunt.loadNpmTasks( 'grunt-mocha-cov' ); - grunt.loadNpmTasks( 'grunt-phpunit' ); - - // Register NPM Tasks. - grunt.registerTask( 'default', [ 'build' ] ); - - // Installation. - grunt.registerTask( 'install', [ 'build' ] ); - - // Build Task. - grunt.registerTask( 'build', [ 'markdown', 'less' , 'yuidoc', 'uglify' ] ); - - // Run Unit Tests. - grunt.registerTask( 'test', [ 'phpunit', 'mochacli:all', 'mochacov:all' ] ); - - // Build Distribution. - grunt.registerTask( 'distribution', [ 'mochacli:all', 'mochacov:all', 'clean:all', 'markdown', 'less:production', 'uglify:production' ] ); - - // Update Environment. - grunt.registerTask( 'update', [ 'clean:update', 'shell:update' ] ); - -}; \ No newline at end of file diff --git a/vendor/udx/lib-utility/lib/class-guid-fix.php b/vendor/udx/lib-utility/lib/class-guid-fix.php deleted file mode 100644 index 6ae9d8fb2..000000000 --- a/vendor/udx/lib-utility/lib/class-guid-fix.php +++ /dev/null @@ -1,205 +0,0 @@ -non-unique GUID bug. - * - * @source http://crowdfavorite.com/wordpress/plugins/cf-guid-fix/ - * - */ -namespace UsabilityDynamics\Utility { - - if( !class_exists( 'UsabilityDynamics\Utility\Guid_Fix' ) ) { - - class Guid_Fix { - - function __construct() { - - if( is_admin() ) { - $this->add_actions(); - } - - $this->menu_page_slug = 'cf_guid_fix'; - $this->page_url = admin_url( 'tools.php?page=' . $this->menu_page_slug ); - $this->errors = array(); - $this->error_msgs = array( - '1' => __( 'Could not create index on your posts table for the `guid` column', 'cf_guid_fix' ), - '2' => __( 'Could not update a post’s GUID', 'cf_guid_fix' ), - '3' => __( 'Could not remove the index from `guid`', 'cf_guid_fix' ), - ); - } - - function add_actions() { - add_action( 'admin_init', array( $this, 'admin_init' ) ); - add_action( 'admin_menu', array( $this, 'register_admin_menu' ) ); - add_filter( 'plugin_action_links', array( $this, 'plugin_action_links' ), 10, 2 ); - } - - function plugin_action_links( $links, $file ) { - $plugin_file = basename( __FILE__ ); - if( basename( $file ) == $plugin_file ) { - $tools_link = '' . __( 'Run GUID-fix', 'cf_guid_fix' ) . ''; - array_unshift( $links, $tools_link ); - } - - return $links; - } - - function register_admin_menu() { - add_submenu_page( - 'tools.php', // parent slug - 'GUID Fix', // page title - 'GUID Fix', // menu title - 'manage_options', // capability - $this->menu_page_slug, // menu item slug - array( $this, 'output_admin_page' ) // callback function - ); - } - - function output_admin_page() { - ?> -
-

- -

You should now disable and remove this plugin.', 'cf_guid_fix' ); ?>

- -
- ' . esc_html( $this->error_msgs[ intval( $num ) ] ) . '

'; - } - ?> -
- -

non-unique GUID bug.', 'cf_guid_fix' ); ?>

-

-
- - - -
-
- fix_guids(); - if( empty( $this->errors ) ) { - wp_redirect( add_query_arg( array( 'success' => '' ), $this->page_url ) ); - } else { - wp_redirect( add_query_arg( array( 'error' => implode( ',', $this->errors ) ), $this->page_url ) ); - } - exit; - break; - } - } - } - - private function fix_guids() { - global $wpdb; - - // add index on GUID column - $r = $wpdb->query( " - ALTER TABLE $wpdb->posts - ADD INDEX (guid) - " ); - - // Error Handling - if( $r === false ) { - $this->add_error( 1 ); - } - - // find non-unique GUID values - - // NOTE: not including revisions since that's a whole other mess to - // try to get the numbering right if we change the GUID - - // this gets the GUIDs - // SELECT guid - // FROM $wpdb->posts - // WHERE post_type != 'revision' - // GROUP BY guid - // HAVING COUNT(guid) > 1 - - // WORKS - but is very slow - // SELECT ID - // FROM $wpdb->posts - // WHERE guid IN ( - // SELECT guid - // FROM $wpdb->posts - // WHERE post_type != 'revision' - // GROUP BY guid - // HAVING COUNT(guid) > 1 - // ) - // AND post_type != 'revision' - - $non_unique_guids = $wpdb->get_col( $wpdb->prepare( " - SELECT p1.ID - FROM $wpdb->posts p1 - WHERE 1 < ( - SELECT COUNT(ID) - FROM $wpdb->posts p2 - WHERE p1.post_type != 'revision' - AND p1.guid = p2.guid - ) - AND p1.post_type != 'revision' - " ) ); - - // make them unique - if( count( $non_unique_guids ) ) { - foreach( $non_unique_guids as $post_id ) { - $url = site_url( '?p=' . $post_id ); - $r = $wpdb->query( $wpdb->prepare( " - UPDATE $wpdb->posts - SET guid = %s - WHERE ID = %d - ", $url, $post_id ) ); - - // Error Handling - if( $r === false ) { - $this->add_error( 2 ); - } - } - } - - // remove index from GUID column - $r = $wpdb->query( " - ALTER TABLE $wpdb->posts - DROP INDEX guid - " ); - - // Error Handling - if( $r === false ) { - $this->add_error( 3 ); - } - - } - - function add_error( $error_num ) { - if( !in_array( $error_num, $this->errors ) ) { - $this->errors[ ] = intval( $error_num ); - } - } - - } - } - -} - diff --git a/vendor/udx/lib-utility/lib/class-job.php b/vendor/udx/lib-utility/lib/class-job.php deleted file mode 100644 index 94242cb93..000000000 --- a/vendor/udx/lib-utility/lib/class-job.php +++ /dev/null @@ -1,417 +0,0 @@ - '_default', - 'post_title' => null, - 'post_password' => null, - 'post_status' => 'job-ready', - 'post_type' => '_ud_job' - ); - - /** - * Meta Keys. - * - * self::$_meta - * - * @property $_meta - * @private - * @type {Array} - */ - public static $_meta = array( - 'type' => array( 'is_single' => true ), - 'status' => array( 'is_single' => true ), - 'callback::worker' => array( 'is_single' => true ), - 'callback::complete' => array( 'is_single' => true ) - ); - - /** - * Job Instance ID. - * - * @property $id - * @private - * @type {Integer} - */ - public $id = null; - - /** - * Job Status. - * - * @property $status - * @private - * @type {Integer} - */ - private $status = null; - - /** - * Job Type. - * - * @property $type - * @private - * @type {Integer} - */ - private $type = null; - - /** - * Job Batches. - * - * @property $batches - * @private - * @type {Array} - */ - private $batches = array(); - - /** - * Job Instance Settings. - * - * @property $_settings - * @private - * @type {Object} - */ - private $_settings = stdClass; - - /** - * Constructor for the Job class. - * - * - * @todo Finish job loading. - * - * @method __construct - * @for Job - * @constructor - * @param array|\UsabilityDynamics\object $settings array - * @return \UsabilityDynamics\Job - * @version 0.0.1 - * @since 0.0.1 - */ - public function __construct( $settings = array() ) { - - // Register Job Post Type, if needed. - $this->_register_post_type(); - - // Save Settings to Instance, applying defaults, returns deeply-converted object. - $this->_settings = self::defaults( $settings, self::$defaults ); - - // Load job if ID is set. - if( $this->_settings->id ) { - return Job::query( array( "id" => $this->_settings->id ) ); - } - - // Generate Title. - $this->_settings->post_title = sprintf( __( 'Job %s', self::$text_domain ), $this->_settings->type ); - - // Generate public job hash. - $this->_settings->post_password = uniqid( $this->_settings->type . '-' ); - - // Encode payload. - $this->_settings->post_content = json_encode( (array) $this->_settings->post_content ); - - // Insert Job, get job ID. - $this->id = wp_insert_post( $this->_settings ); - - // Handle creation error. - if( $this->id instanceof WP_Error ) { - return $this->id; - } - - // Commit Meta Key. - foreach( (array) self::$_meta as $_key => $_options ) { - - $_value = $this->_settings->{$_key}; - - if( $_value ) { - update_post_meta( $this->id, 'job::' . $_key, $_value ); - } - - } - - - // Worker. - return $this; - - } - - /** - * Load Job. - * - * Parses post object and adds declared meta. - * - * @param null $job - * - * @internal param null $id - * - * @return object - */ - public function load_meta( $job = null ) { - - if( !$job ) { - $_id = $this->id; - } - - if( is_object( $job ) && $job->id ) { - $_id = $job->id; - } - - if( is_integer( $job ) ) { - $_id = $job; - } - - if( !$_id ) { - return new WP_Error( __( 'Could not load job with unknown ID.', self::$text_domain ) ); - } - - $_meta = array(); - - foreach( (array) self::$_meta as $_key => $_options ) { - $_value = get_post_meta( $_id, 'job::' . $_key, $_options[ 'is_single' ] ? true : false ); - - if( $_value ) { - $_meta[ $_key ] = $_value; - } - - } - - return $_meta; - - } - - /** - * Delete Job Instance. - * - */ - public function delete() { - global $wpdb; - - // Kill Babies. - foreach( (array) $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_parent=%d;", $this->id ) ) as $_child ) { - $_post = wp_delete_post( $_child, true ); - } - - // Kill Parent. - $_post = wp_delete_post( $this->id, true ); - - // Return object. - return $_post; - - } - - /** - * Push Batch Cargo. - * - * @param array $data - * @param array $args - * - * @return int|void|\WP_Error - */ - public function push( $data = array(), $args = array() ) { - - // Convert to JSON String. - $_data = json_encode( (array) $data ); - - // Generate public job hash. - $_batchid = wp_insert_post( self::defaults( $args, array( - 'post_parent' => $this->id, - 'post_status' => 'job-ready', - 'post_title' => sprintf( __( 'Job Batch %s', self::$text_domain ), $this->_settings->type ), - 'post_password' => uniqid( $this->_settings->type . '-' ), - 'post_type' => $this->_settings->post_type, - 'post_content' => $_data - )) ); - - // Add to batch list if not an error. - if( !is_wp_error( $_batchid ) ) { - $this->batches[ $_batchid ] = json_decode( $_data ); - } - - return $_batchid; - - } - - /** - * Process Mutiple Jobs. - * - * - * @param string $type Job type. - * @param array $args - * - * @return null - */ - public static function process_jobs( $type = null, $args = array() ) { - - $_results = array(); - - foreach( self::query( $type ) as $_count => $_job ) { - - $_batches = self::query( $_job->type, array( - "post_parent" => $_job->ID, - "post_status" => 'job-ready', - - )); - - //die( '
' . print_r( $_batches, true ) . '
' ); - // Get Batches - - // $_results[ $_count ] = apply_filters( 'job::' . $_job->type, $_job, $_results[ $_count ] = $_results[ $_count ] || array(), $_count ); - - } - - return $_results; - - } - - /** - * Query Job Instance(s) - * - * @todo Should use instances of Job instead of WP_Post. - * - * @param null $type - * @param array $args - * - * @return array - */ - public static function query( $type = null, $args = array() ) { - - // Build get_posts query. - $args = self::defaults( $args, array( - 'posts_per_page' => 100, - 'offset' => 0, - 'post_parent' => 0, - 'orderby' => 'post_date', - 'order' => 'DESC', - 'post_type' => '_ud_job', - 'post_status' => 'job-ready' - )); - - // Query by ID. - if( is_numeric( $type ) ) { - $args->ID = $type; - } - - // Query by type. - if( is_string( $type ) ) { - $args->meta_key = 'job::type'; - $args->meta_value = $type; - } - - // Get all top-level jobs. - $_jobs = get_posts( (array) $args ); - - // Extend Job objects with meta. - foreach( (array) $_jobs as $_count => $_job ) { - - // Remove unused keys. - unset( $_jobs[ $_count ]->ping_status ); - unset( $_jobs[ $_count ]->to_ping ); - unset( $_jobs[ $_count ]->pinged ); - unset( $_jobs[ $_count ]->pinged ); - unset( $_jobs[ $_count ]->guid ); - unset( $_jobs[ $_count ]->menu_order ); - unset( $_jobs[ $_count ]->post_mime_type ); - unset( $_jobs[ $_count ]->filter ); - - // Decode cargo. - $_jobs[ $_count ]->post_content = json_decode( $_jobs[ $_count ]->post_content ? $_jobs[ $_count ]->post_content : array() ); - $_jobs[ $_count ]->post_excerpt = json_decode( $_jobs[ $_count ]->post_excerpt ? $_jobs[ $_count ]->post_excerpt : array() ); - - // Load Meta into Object. - foreach( self::load_meta( $_job->ID ) as $_key => $_value ) { - $_jobs[ $_count ]->{$_key} = $_value; - } - - } - - // Return formatted jobs result. - return (object) $_jobs; - - } - - /** - * Register Job Post Type - * - * @private - * @uses get_post_type_object - * @uses register_post_type - */ - private function _register_post_type() { - - // Return if already registered. - if( get_post_type_object( $this->_settings->post_type ) ) { - return get_post_type_object( $this->_settings->post_type ); - } - - // Register; - register_post_type( $this->_settings->post_type, array( - 'labels' => array( - 'name' => __( 'Jobs', self::$text_domain ), - 'singular_name' => __( 'Jobs', self::$text_domain ), - 'new_item' => __( 'New Job', self::$text_domain ), - 'view_item' => __( 'View Job', self::$text_domain ), - 'all_items' => __( 'Jobs', self::$text_domain ) - ), - 'description' => __( 'UsabilityDynamics Jobs.', self::$text_domain ), - 'public' => false, - 'hierarchical' => true, - 'exclude_from_search' => true, - 'publicly_queryable' => false, - 'show_ui' => false, - 'show_in_menu' => false, - 'show_in_nav_menus' => false, - 'show_in_admin_bar' => false, - 'map_meta_cap' => false, - 'supports' => array( 'raas' ), - 'has_archive' => false, - 'rewrite' => false, - 'query_var' => false, - 'can_export' => true, - 'delete_with_user' => false, - '_edit_link' => 'veneer/?job=%d', - )); - - // Return post type object. - return get_post_type_object( $this->_settings->post_type ); - - } - - } - - } - -} - diff --git a/vendor/udx/lib-utility/lib/class-loader.php b/vendor/udx/lib-utility/lib/class-loader.php deleted file mode 100644 index d89e63836..000000000 --- a/vendor/udx/lib-utility/lib/class-loader.php +++ /dev/null @@ -1,445 +0,0 @@ -add( 'Symfony', __DIR__ . '/framework' ); - * - * // register classes with namespaces by passing an array - * $loader->add( array( - * 'UsabilityDynamics\\' => __DIR__ . '/usabilitydynamics' - * 'JsonSchema\\' => __DIR__ . '/jsonschema/src' - * )); - * - * // activate the autoloader - * $loader->register(); - * - * This class is loosely based on the Symfony UniversalClassLoader. - * - * @class Loader - * @author potanin@UD - */ - class Loader { - - /** - * Loader Class version. - * - * @property $version - * @type {Object} - */ - public static $version = '0.0.3'; - - /** - * Extra header parameters. - * - * @property $headers - * @type {Object} - */ - public static $headers = array( - 'theme' => array( - 'Name' => 'Theme Name', - 'ThemeURI' => 'Theme URI', - 'Description' => 'Description', - 'Author' => 'Author', - 'AuthorURI' => 'Author URI', - 'Version' => 'Version', - 'Template' => 'Template', - 'Status' => 'Status', - 'Tags' => 'Tags' - ) - ); - - /** - * Configuration. - * - * @property $settings - * @type {Object} - */ - public $settings = array(); - - /** - * Array with fallback directories for auto-loading. - * - * @property $fallback_directories - * @type {Object} - */ - public $fallback_directories = array(); - - /** - * Array of stored namespace prefixes. - * - * @property $prefixes - * @type {Object} - */ - public $prefixes = array(); - - /** - * Array of stored class mappings. - * - * @property $class_map - * @type {Object} - */ - public $class_map = array(); - - /** - * Constructor for the Loader class. - * - * @method __construct - * @for Loader - * @constructor - * - * @param $settings array - * - * @return \UsabilityDynamics\Loader - * @version 0.0.2 - * @since 0.0.2 - */ - function __construct( $settings = array() ) { - - // Save Loader Settings. - $this->settings = json_decode( json_encode( $settings ) ); - - // Load libraries that use namespaces. - if( isset( $this->settings->controllers ) ) { - $this->set_namespace( $this->settings->controllers ); - } - - // Loads libraries that do not use namespaces. - if( isset( $this->settings->helpders ) ) { - $this->add_class_map( $this->settings->helpers ); - } - - // Register Autoloader. - $this->register( true ); - - // Prepare Filters. - add_filter( 'template_redirect', array( $this, 'template_redirect' ) ); - - // Utility. - add_filter( 'extra_theme_headers', array( $this, 'extra_theme_headers' ) ); - - // @chainable - return $this; - - } - - /** - * Fronted Setup - * - * @return $this - * - * @method template_redirect - * @for Loader - * - * @author potanin@UD - * @version 0.0.2 - * @since 0.0.2 - */ - function template_redirect() { - - // Unrefister Autoloader. - $this->unregister(); - - // @chainable - return $this; - - } - - /** - * Add Color Scheme - * - * @method extra_theme_headers - * @for Loader - * - * @author potanin@UD - * @version 0.0.2 - * @since 0.0.2 - */ - function extra_theme_headers() { - return (array) $this->headers; - } - - /** - * Add Class Map - * - * @param array $class_map Class to filename map - * - * @return $this - * - * @method add_class_map - * @for Loader - * - * @author potanin@UD - * @version 0.0.2 - * @since 0.0.2 - */ - public function add_class_map( array $class_map ) { - - if( $this->class_map ) { - $this->class_map = array_merge( $this->class_map, $class_map ); - } else { - $this->class_map = $class_map; - } - - return $this; - - } - - /** - * Registers a set of classes, merging with any others previously set. - * - * @param string $prefix The classes prefix - * @param array|string $paths The location(s) of the classes - * @param bool $prepend Prepend the location(s) - * - * @return $this - * - * @method add_class - * @for Loader - * - * @author potanin@UD - * @version 0.0.2 - * @since 0.0.2 - */ - public function add_class( $prefix, $paths, $prepend = false ) { - - if( !$prefix ) { - if( $prepend ) { - $this->fallback_directories = array_merge( (array) $paths, (array) $this->fallback_directories ); - } else { - $this->fallback_directories = array_merge( (array) $this->fallback_directories, (array) $paths ); - } - - return $this; - } - - $first = $prefix[ 0 ]; - - if( !isset( $this->prefixes[ $first ][ $prefix ] ) ) { - $this->prefixes[ $first ][ $prefix ] = (array) $paths; - - return $this; - } - if( $prepend ) { - $this->prefixes[ $first ][ $prefix ] = array_merge( (array) $paths, $this->prefixes[ $first ][ $prefix ] ); - } else { - $this->prefixes[ $first ][ $prefix ] = array_merge( $this->prefixes[ $first ][ $prefix ], (array) $paths ); - } - - return $this; - - } - - /** - * Registers a set of classes, replacing any others previously set. - * - * @param string|array $prefix The classes prefix or an object containing prefixes and strings. - * @param array|string $paths The location(s) of the classes - * - * @return $this - * - * @method set_namespace - * @for Loader - * - * @author potanin@UD - * @version 0.0.2 - * @since 0.0.2 - */ - public function set_namespace( $prefix, $paths = null ) { - - if( is_array( $prefix ) || is_object( $prefix ) ) { - - foreach( $prefix as $namespace => $path ) { - $this->set_namespace( $namespace, $path ); - } - - return $this; - - } - - if( !$prefix ) { - $this->fallback_directories = (array) $paths; - } else { - $this->prefixes[ substr( $prefix, 0, 1 ) ][ $prefix ] = (array) $paths; - } - - return $this; - - } - - /** - * Registers this instance as an autoloader. - * - * @param callback $autoload_function [optional]. The autoload function being registered. - * @param bool $throw This parameter specifies whether spl_autoload_register() should throw exceptions when the autoload_function cannot be registered. - * @param bool $prepend If true, spl_autoload_register() will prepend the autoloader on the autoload stack instead of appending it. - * - * @method register - * @for Loader - * - * @author potanin@UD - * @version 0.0.2 - * @since 0.0.2 - */ - public function register( $throw = false, $prepend = false ) { - spl_autoload_register( array( $this, 'load_class' ), $throw, $prepend ); - } - - /** - * Unregisters this instance as an autoloader. - * - * @method unregister - * @for Loader - * - * @author potanin@UD - * @version 0.0.2 - * @since 0.0.2 - */ - public function unregister() { - spl_autoload_unregister( array( $this, 'load_class' ) ); - } - - /** - * Loads the given class or interface. - * - * @param string $class The name of the class - * - * @return bool|null True if loaded, null otherwise - * - * @method load_class - * @for Loader - * - * @author potanin@UD - * @version 0.0.2 - * @since 0.0.2 - */ - public function load_class( $class ) { - - if( $file = $this->find_file( $class ) ) { - include $file; - - return true; - } - - } - - /** - * Finds the path to the file where the class is defined. - * - * - $namespace Raw namespace. - * - $class_path Fully reoslved name. - * - $class_name Just the class name. - * - * @param string $class The name of the class - * - * @return string|false The path if found, false otherwise - * - * @method find_file - * @for Loader - * - * @author potanin@UD - * @version 0.0.2 - * @since 0.0.2 - */ - public function find_file( $class ) { - - // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731 - if( '\\' == $class[ 0 ] ) { - $class = substr( $class, 1 ); - } - - // $class = str_replace( 'Flawless\\', '\\', $class ); - - if( isset( $this->class_map[ $class ] ) ) { - return $this->class_map[ $class ]; - } - - if( false !== $pos = strrpos( $class, '\\' ) ) { - $class_path = strtr( substr( $class, 0, $pos ), '\\', DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR; - $class_name = substr( $class, $pos + 1 ); - } else { - $class_path = null; - $class_name = $class; - } - - $namespace = $class_path; - $class_path .= strtr( $class_name, '_', DIRECTORY_SEPARATOR ) . '.php'; - - $first = $class[ 0 ]; - - if( isset( $this->prefixes[ $first ] ) ) { - - //die( '
' . print_r( $this->prefixes[ $first ], true ) . '
' ); - - foreach( $this->prefixes[ $first ] as $prefix => $dirs ) { - if( 0 === strpos( $class, $prefix ) ) { - foreach( $dirs as $dir ) { - - if( file_exists( $dir . DIRECTORY_SEPARATOR . $class_path ) ) { - return $dir . DIRECTORY_SEPARATOR . $class_path; - } - - // If file not found, try with the namespace stripped - if( file_exists( $dir . DIRECTORY_SEPARATOR . str_replace( $namespace, '', $class_path ) ) ) { - return $dir . DIRECTORY_SEPARATOR . str_replace( $namespace, '', $class_path ); - } - - } - } - } - } - - foreach( $this->fallback_directories as $dir ) { - if( file_exists( $dir . DIRECTORY_SEPARATOR . $class_path ) ) { - return $dir . DIRECTORY_SEPARATOR . $class_path; - } - } - - return $this->class_map[ $class ] = false; - - } - - /** - * Parse File Headers - * - * @example - * - * Loader::get_file_data( 'style.css' ); - * Loader::get_file_data( 'my-module/my-module.php', 'module' ); - * - * @method get_file_data - * @for Loader - * - * @author potanin@UD - * @version 0.0.2 - * @since 0.0.2 - * - * @param string $path Full path to the target file. - * @param string $type Type of target file, defaults to theme, must be defined in Loader::$headers. - * - * @return array - */ - public static function get_file_data( $path = '', $type = 'theme' ) { - return array_filter( (array) get_file_data( $path, is_string( $type ) ? Loader::$headers[ $type ] : Loader::$headers[ 'theme' ], $type ) ); - } - - } - - } - -} - diff --git a/vendor/udx/lib-utility/lib/class-structure.php b/vendor/udx/lib-utility/lib/class-structure.php deleted file mode 100644 index 8f8d0f120..000000000 --- a/vendor/udx/lib-utility/lib/class-structure.php +++ /dev/null @@ -1,229 +0,0 @@ - - * @package Theme - * @author peshkov@UD - */ -namespace UsabilityDynamics { - - if( !class_exists( 'UsabilityDynamics\Structure' ) ) { - - class Structure { - - /** - * - * - */ - static private $args = array(); - - /** - * - * - */ - static private $structure = array(); - - /** - * Define Data Structure - * - * @param $args - * @param $args.types (array) Post type definitions - * @param $args.meta (array) Meta definitions. - * @param $args.taxonomies (array) Taxonomy fields. - * - * @return array|bool - */ - static public function define( $args = array() ) { - - self::$args = wp_parse_args( $args, array( - 'types' => array(), // Custom post types - 'meta' => array(), // Meta fields - 'taxonomies' => array(), // Taxonomies - ) ); - - $structure = array(); - - foreach( (array) self::$args[ 'types' ] as $object_type => $type ) { - - $object_type = sanitize_key( $object_type ); - - self::$structure[ $object_type ] = array( - 'meta' => array(), - 'terms' => array(), - ); - - // STEP 1. Register post_type - - // Register Post Type - $data = ( isset( $type[ 'data' ] ) && is_array( $type[ 'data' ] ) ) ? $type[ 'data' ] : array(); - - if( !post_type_exists( $object_type ) ) { - register_post_type( $object_type, self::_prepare_post_type( $object_type, $data )); - } - - // STEP 2. Register taxonomy ( and Taxonomy's Post Type if theme supports 'extended-taxonomies' feature ) - - // Define post type's taxonomies - $taxonomies = ( isset( $type[ 'taxonomies' ] ) && is_array( $type[ 'taxonomies' ] ) ) ? $type[ 'taxonomies' ] : array( - 'post_tag', - 'category', - ); - - // Initialize taxonomies if they don't exist and assign them to the current post type - foreach( (array) $taxonomies as $taxonomy ) { - - if( empty( $taxonomy ) || !is_string( $taxonomy ) ) { - continue; - } - - if( !taxonomy_exists( $taxonomy ) ) { - $data = self::_prepare_taxonomy( $taxonomy ); - register_taxonomy( $taxonomy, null, $data ); - } - - register_taxonomy_for_object_type( $taxonomy, $object_type ); - - //** Add custom post type for our taxonomy if theme supports extended-taxonomies */ - $taxonomy_post_type = '_tp_' . $taxonomy; - if( current_theme_supports( 'extended-taxonomies' ) && !post_type_exists( $taxonomy_post_type ) ) { - register_post_type( $taxonomy_post_type, array( - 'label' => $data[ 'label' ], - 'public' => false, - 'rewrite' => false, - 'labels' => array( - 'name' => $data[ 'label' ], - 'edit_item' => 'Edit Term: ' . $data[ 'label' ] - ), - 'supports' => array( 'title', 'editor' ), - )); - } - - if( isset( $structure[ $object_type ] ) && isset( $structure[ $object_type ]['terms' ] ) && is_array( $structure[ $object_type ]['terms' ] ) ) { - array_push( $structure[ $object_type ][ 'terms' ], $taxonomy ); - } - - } - - // STEP 3. Set meta fields and meta boxes - - // Stop here if Meta Box class doesn't exist - if( !class_exists( '\RW_Meta_Box' ) ) { - continue; - } - - // Init \RW_Meta_Box defines if needed - if ( !defined( 'RWMB_VER' ) ) { - - $reflector = new \ReflectionClass( '\RW_Meta_Box' ); - - $file = dirname( dirname( $reflector->getFileName() ) ) . '/meta-box.php'; - if( !file_exists( $file ) ) { - continue; - } - include_once( $file ); - } - - $metaboxes = ( isset( $type[ 'meta' ] ) && is_array( $type[ 'meta' ] ) ) ? $type[ 'meta' ] : array(); - - foreach( $metaboxes as $key => $data ) { - $data = self::_prepare_metabox( $key, $object_type, $data ); - - if( $data ) { - new \RW_Meta_Box( $data ); - } - } - - } - - // STEP 4. reset static vars and return structure data. - $structure = array( - 'post_types' => self::$structure, - 'schema' => self::$args, - ); - - self::$args = array(); - self::$structure = array(); - - return $structure; - } - - /** - * - * - */ - static private function _prepare_metabox( $key, $object_type, $data ) { - $label = \UsabilityDynamics\Utility::de_slug( $key ); - - $data = wp_parse_args( $data, array( - 'id' => $key, - 'title' => $label, - 'pages' => array( $object_type ), - 'context' => 'normal', - 'priority' => 'high', - 'autosave' => false, - 'fields' => array(), - ) ); - - // There is no sense to init empty metabox - if( !is_array( $data[ 'fields' ] ) || empty( $data[ 'fields' ] ) ) { - return false; - } - - $fields = array(); - foreach( $data[ 'fields' ] as $field ) { - array_push( self::$structure[ $object_type ][ 'meta' ], $field ); - $fields[] = self::_prepare_metafield( $field ); - } - - $data[ 'fields' ] = $fields; - - return $data; - } - - /** - * - * - */ - static private function _prepare_metafield( $key ) { - $data = isset( self::$args[ 'meta' ][ $key ] ) ? (array) self::$args[ 'meta' ][ $key ] : array(); - $data = wp_parse_args( $data, array( - 'id' => $key, - 'name' => \UsabilityDynamics\Utility::de_slug( $key ), - 'type' => 'text', - ) ); - return $data; - } - - /** - * - * - */ - static private function _prepare_taxonomy( $key ) { - $data = isset( self::$args[ 'taxonomies' ][ $key ] ) && is_array( self::$args[ 'taxonomies' ][ $key ] ) ? self::$args[ 'taxonomies' ][ $key ] : array(); - $data = wp_parse_args( $data, array( - 'label' => \UsabilityDynamics\Utility::de_slug( $key ), - ) ); - return $data; - } - - /** - * - * - */ - static private function _prepare_post_type( $key, $args = array() ) { - $args = wp_parse_args( $args, array( - 'label' => \UsabilityDynamics\Utility::de_slug( $key ), - 'exclude_from_search' => false, - ) ); - return $args; - } - - } - - } - -} - - - diff --git a/vendor/udx/lib-utility/lib/class-term.php b/vendor/udx/lib-utility/lib/class-term.php deleted file mode 100644 index 62b662e30..000000000 --- a/vendor/udx/lib-utility/lib/class-term.php +++ /dev/null @@ -1,127 +0,0 @@ - - * @package Theme - * @author potanin@UD - * @author peshkov@UD - */ -namespace UsabilityDynamics { - - if( !class_exists( 'UsabilityDynamics\Term' ) ) { - - class Term { - - /** - * Add meta data field to a term. - * - */ - static public function add_meta( $term_id, $meta_key, $meta_value, $unique = false ) { - - if( current_theme_supports( 'extended-taxonomies' ) ) { - return add_post_meta( self::get_post_for_extended_term( $term_id )->ID, $meta_key, $meta_value, $unique ); - } - - return add_metadata( 'taxonomy', $term_id, $meta_key, $meta_value, $unique ); - } - - /** - * Remove metadata matching criteria from a term. - * - * - */ - static public function delete_meta( $term_id, $meta_key, $meta_value = '' ) { - - if( current_theme_supports( 'extended-taxonomies' ) ) { - return delete_post_meta( self::get_post_for_extended_term( $term_id )->ID, $meta_key, $meta_value ); - } - - return delete_metadata( 'taxonomy', $term_id, $meta_key, $meta_value ); - } - - /** - * Retrieve term meta field for a term. - * - */ - static public function get_meta( $term_id, $key, $single = false ) { - - if( current_theme_supports( 'extended-taxonomies' ) ) { - return get_post_meta( self::get_post_for_extended_term( $term_id )->ID, $key, $single ); - } - - return get_metadata( 'taxonomy', $term_id, $key, $single ); - } - - /** - * Update term meta field based on term ID. - * - */ - static public function update_meta( $term_id, $meta_key, $meta_value, $prev_value = '' ) { - - if( current_theme_supports( 'extended-taxonomies' ) ) { - return update_post_meta( self::get_post_for_extended_term( $term_id )->ID, $meta_key, $meta_value, $prev_value ); - } - - return update_metadata( 'taxonomy', $term_id, $meta_key, $meta_value, $prev_value ); - } - - /** - * {} - * - * @author potanin@UD - */ - static public function get_post_for_extended_term( $term_id = false, $taxonomy = false ) { - global $wpdb; - - if( !$term_id ) { - return false; - } - - if( is_object( $term_id ) ) { - $term_id = $term_id->term_id; - $taxonomy = $taxonomy ? $taxonomy : $term_id->taxonomy; - } - - //** Try to get taxonomy -if this term only has one relationship, it's a good guess */ - if( !$taxonomy ) { - $taxonomy = $wpdb->get_col( "SELECT taxonomy FROM {$wpdb->term_taxonomy} WHERE term_id = {$term_id}" ); - - if( count( $taxonomy ) > 1 ) { - return false; - } else { - $taxonomy = $taxonomy[0]; - } - } - - if( !is_numeric( $term_id ) || empty( $taxonomy ) ) { - return false; - } - - $post_id = $wpdb->get_var( "SELECT post_id FROM {$wpdb->postmeta} pm LEFT JOIN {$wpdb->posts} p ON pm.post_id = p.ID WHERE meta_key = 'extended_term_id' AND meta_value = '{$term_id}' AND post_type = '_tp_{$taxonomy}' " ); - - if( !$post_id ) { - return false; - } - - if( $post_id ) { - $post = get_post( $post_id ); - } - - if( !$post ) { - return false; - } - - return $post; - - } - - } - - } - -} - - - diff --git a/vendor/udx/lib-utility/lib/class-utility.php b/vendor/udx/lib-utility/lib/class-utility.php deleted file mode 100644 index be11f8a7e..000000000 --- a/vendor/udx/lib-utility/lib/class-utility.php +++ /dev/null @@ -1,2595 +0,0 @@ - 10, - "offset" => 10, - "post_type" => 'any', - "post_status" => 'any' - )); - - foreach ( $allposts as $_post ) { - - $postmeta = get_post_meta($postinfo->ID, $key); - - die( '
' . print_r( $postmeta, true ) . '
'); - - } - - $keys = array('address', 'address2', 'city', 'state', 'zip'); //Add post meta keys here - - foreach ( $keys as $key ) { - - foreach( $allposts as $postinfo) { - - // Fetch array of custom field values - - - //print_r($postinfo); - - if (!empty($postmeta) ) { - - // Delete the custom field for this post (all occurrences) - delete_post_meta($postinfo->ID, $key); - - // Insert one and only one custom field - update_post_meta($postinfo->ID, $key, $postmeta[0]); - - } - } - - } - - - break; - - default: - - break; - - } - - //$wpdb->query( "DELETE a,b,c FROM {$wpdb->posts} a LEFT JOIN wp_term_relationships b ON (a.ID = b.object_id) LEFT JOIN {$wpdb->postmeta} c ON (a.ID = c.post_id) WHERE a.post_type = 'revision'" ); - //$wpdb->query( "DELETE pm FROM wp_postmeta pm LEFT JOIN wp_posts wp ON wp.ID = pm.post_id WHERE wp.ID IS NULL;" ); - //$wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE ('_site_transient_%');" ); - //$wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE ('_transient_%');" ); - - - } - - /** - * Looks for a json or a php file in specified directory, if the file is not found traverse up and look for it again until its found or until a document root is reached - * - * - * @todo Honor the "nocase" option setting. - * @todo Perhaps wrap simplexml_load_file into - potanin@UD - * - * @since 0.3.2 - * @method findUp - * @param string $name - Name of file to find. - * @param string $cwd - Directory to start seeking from. Defaults to __DIR__ - * @param string $required - If the file is required - if not found, will trigger an error. - * @author tosheen@UD - * @return array|bool|mixed|\SimpleXMLElement - */ - static public function findUp( $name = false, $cwd = false, $required = false ) { - - // No name provided, bail. - if( !$name ) { - return false; - } - - // If first argument appears to be an object/array, treat it as a configuration object. - if( is_array( $name ) || is_object( $name ) ) { - - // Apply default settings to passed argument. - $_settings = self::defaults( $name, array( - "cwd" => $cwd ? $cwd : null, - "required" => $required ? $required : false, - "nocase" => true - )); - - $name = $_settings->name; - $cwd = $_settings->cwd; - $required = $_settings->required; - $nocase = $_settings->nocase; - - } - - // No CWD set, backtrace to determine caller. - $cwd = $cwd ? $cwd : dirname( self::backtrace_caller()->file ); - - // Determine if file is JSON - $fileData = explode( '.', $name ); - $fileExtension = $fileData[ count( $fileData ) - 1 ]; - - // Determine traverse path - $_path = ( !empty( $cwd ) ? $cwd : $_SERVER[ 'DOCUMENT_ROOT' ] ); - - $file = $_path . DIRECTORY_SEPARATOR . $name; - - // Trigger Error and bail on failures. - if( !is_dir( $_path ) ) { - - // Trigger error if required, otherwise fail silently. - if( $required ) { - trigger_error( __( 'Required file not found.', self::$text_domain ), E_USER_ERROR ); - } - - return false; - - } - - if( file_exists( $file ) ) { - - // Fetch and parse JSON. - if( $fileExtension === 'json' ) { - return json_decode( file_get_contents( $file ) ); - } - - // Fetch and parse XML. - if( $fileExtension === 'xml' ) { - return simplexml_load_file( $file ); - } - - // Include all others. - return include_once( $file ); - - } - - if( $_path != $_SERVER[ 'DOCUMENT_ROOT' ] ) { - $lastDirSeparator = strrpos( $_path, DIRECTORY_SEPARATOR, -1 ); - $_path = substr( $_path, 0, $lastDirSeparator ); - return self::findUp( $name, $_path ); - } - - // Trigger error if file was required. - if( $required ) { - trigger_error( __( 'Required file not found.', self::$text_domain ), E_USER_ERROR ); - } - - // Couldn't find anything - return false; - - } - - /** - * Get Caller Object - * - * @method backtrace_caller - * @since 0.3.2 - * @author potanin@UD - * @param int $depth - * @return object - */ - static public function backtrace_caller( $depth = 1 ) { - - // Always add one level to backtrace. - $_backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, ( $depth ? $depth : 1 ) + 1 ); - - // Return first hit as object, or a scaffolded object. - return $_backtrace[1] ? (object) $_backtrace[1] : (object) array( 'file' => null ); - - } - - /** - * Set Dot-Notated Array Value - * - * @param array $arr - * @param $path - * @param $val - * - * @return mixed - */ - static public function _set_val( array &$arr, $path, $val ) { - $loc = & $arr; - - foreach( explode( '.', $path ) as $step ) { - $loc = & $loc[ $step ]; - } - - return $loc = $val; - - } - - /** - * Convert dot-notated array key->value items to nested object - * - * @param $items - * @return array - */ - static public function unwrap( $items ) { - - $_result = array(); - - foreach( (array) $items as $key => $value ) { - self::_set_val( $_result, $key, $value ); - } - - return (array) $_result; - - } - - /** - * Wrapper for wp_parse_args. - * - * @author potanin@UD - * @since 0.3.0 - * @param $args - * @param $defaults - * - * @return object - */ - static public function parse_args( $args, $defaults ) { - - return (object) wp_parse_args( $args, $defaults ); - - } - - /** - * Parses Query. - * HACK. The current logic solves the issue of max_input_vars in the case if query is huge. - * - * @see parse_str() Default PHP function - * @version 1.1 - * @author peshkov@UD - * @param $request - * @return array|mixed - */ - static public function parse_str( $request ) { - $data = array(); - $tokens = explode( "&", $request ); - foreach ( $tokens as $token ) { - $token = str_replace( '%2B', md5( '%2B' ), $token ); - $arr = array(); - parse_str( $token, $arr ); - array_walk_recursive( $arr, function( &$value,$key ) { - $value = str_replace( md5( "%2B" ), "+", $value ); - }); - $data = self::extend( $data, $arr ); - } - return $data; - } - - /** - * Deep Conversion - * - * @updated 2.0 - * @since 0.1 - */ - static public function array_to_object( $array = array() ) { - return json_decode( json_encode( $array ) ); - } - - /** - * Recursively converts object to array - * - * @since 2.0 - * @author peshkov@UD - */ - static public function object_to_array( $data ) { - - if ( is_object( $data ) ) { - $data = get_object_vars( $data ); - } - - if ( is_array( $data ) ) { - foreach ( $data as $k => $v ) { - if ( is_object( $v ) ) { - $data[ $k ] = self::object_to_array( $v ); - } - } - } - - return $data; - - } - - /** - * Parse standard WordPress readme file - * - * @source Readme Parser ( http://www.tomsdimension.de/wp-plugins/readme-parser ) - * @author potanin@UD - */ - static public function parse_readme( $readme_file = false ) { - - if( !$readme_file ) { - $readme_file = untrailingslashit( TEMPLATEPATH ) . '/readme.txt'; - } - - $file = @file_get_contents( $readme_file ); - - if( !$file ) { - return false; - } - - $file = preg_replace( "/(\n\r|\r\n|\r|\n)/", "\n", $file ); - - // headlines - $s = array( '===', '==', '=' ); - $r = array( 'h2', 'h3', 'h4' ); - for( $x = 0; $x < sizeof( $s ); $x++ ) { - $file = preg_replace( '/(.*?)' . $s[ $x ] . '(?!\")(.*?)' . $s[ $x ] . '(.*?)/', '$1<' . $r[ $x ] . '>$2$3', $file ); - } - - // inline - $s = array( '\*\*', '\'' ); - $r = array( 'b', 'code' ); - for( $x = 0; $x < sizeof( $s ); $x++ ) { - $file = preg_replace( '/(.*?)' . $s[ $x ] . '(?!\s)(.*?)(?!\s )' . $s[ $x ] . '(.*?)/', '$1<' . $r[ $x ] . '>$2$3', $file ); - } - - // ' _italic_ ' - $file = preg_replace( '/(\s)_(\S.*?\S)_(\s|$)/', '$2 ', $file ); - - // ul lists - $s = array( '\*', '\+', '\-' ); - for( $x = 0; $x < sizeof( $s ); $x++ ) { - $file = preg_replace( '/^[ ' . $s[ $x ] . ' ](\s)(.*?)(\n|$)/m', '
  • $2
  • ', $file ); - } - - $file = preg_replace( '/\n
  • (.*?)/', '
    • $1', $file ); - $file = preg_replace( '/(<\/li>)(?!
    • )/', '$1
    ', $file ); - - // ol lists - $file = preg_replace( '/(\d{1,2}\. )\s(.*?)(\n|$)/', '
  • $2
  • ', $file ); - $file = preg_replace( '/\n
  • (.*?)/', '
    1. $1', $file ); - $file = preg_replace( '/(<\/li>)(?!(\|\<\/ul\> ))/', '$1
    ', $file ); - - // ol screenshots style - $file = preg_replace( '/(?=Screenshots)(.*?)
      /', '$1
        ', $file ); - - // line breaks - $file = preg_replace( '/(.*?)(\n)/', "$1
        \n", $file ); - $file = preg_replace( '/(1|2|3|4)(>)/', '$1>', $file ); - $file = str_replace( '
        ', '', $file ); - $file = str_replace( '

        ', '
        ', $file ); - - // urls - $file = str_replace( 'http://www.', 'www.', $file ); - $file = str_replace( 'www.', 'http://www.', $file ); - $file = preg_replace( '#(^|[^\"=]{1})(http://|ftp://|mailto:|https://)([^\s<>]+)([\s\n<>]|$)#', '$1$3$4', $file ); - - // divs - $file = preg_replace( '/(

        Description <\/h3>)/', "$1\n
        \n", $file ); - $file = preg_replace( '/(

        Installation <\/h3>)/', "

        \n$1\n
        \n", $file ); - $file = preg_replace( '/(

        Frequently Asked Questions <\/h3>)/', "

        \n$1\n
        \n", $file ); - $file = preg_replace( '/(

        Screenshots <\/h3>)/', "

        \n$1\n
        \n", $file ); - $file = preg_replace( '/(

        Arbitrary section <\/h3>)/', "

        \n$1\n
        \n", $file ); - $file = preg_replace( '/(

        Changelog <\/h3>)/', "

        \n$1\n
        \n", $file ); - $file = $file . '
        '; - - return $file; - - } - - /** - * Detects Variable Type. - * - * Distinguishes between object and array based on associative status. - * - * @source http://php.net/manual/en/function.gettype.php - * @since 1.0.4 - */ - static public function get_type( $var ) { - - if( is_object( $var ) ) return get_class( $var ); - if( is_null( $var ) ) return 'null'; - if( is_string( $var ) ) return 'string'; - - if( is_array( $var ) ) { - - if( self::is_associative( $var ) ) { - return 'object'; - } - - return 'array'; - - } - - if( is_int( $var ) ) return 'integer'; - if( is_bool( $var ) ) return 'boolean'; - if( is_float( $var ) ) return 'float'; - if( is_resource( $var ) ) return 'resource'; - - } - - /** - * Test if Array is Associative - * - * @param $arr - * @return bool - */ - static public function is_associative( $arr ) { - - if( !$arr ) { - return false; - } - - return array_keys($arr) !== range(0, count($arr) - 1) ? true : false; - - } - - /** - * Port of Lo-dash defaults function. - * - * Basically switches the order of arguments used by Utility::extend(); - * - * @method defaults - * - * @param array $data Data to be applied against defaults. $data Data to be applied against defaults. - * @param array $defaults Default array|object. $defaults Default array|object. - * - * @return object Extended data wtih defaults.@since 0.2.5 - */ - static public function defaults( $data = array(), $defaults = array() ) { - - // Extend and return data object/arary with defaults. - return (object) self::extend( (array) $defaults, (array) $data ); - - } - - /** - * Fix Serialized (Broken) Array Strings - * - * @example - * - * foreach( $wpdb->get_results( "SELECT meta_id, meta_value from {$wpdb->postmeta} WHERE meta_key = '_cfct_build_data'" ) as $row ) { - * $fixed = \UsabilityDynamics\Utility::repair_serialized_object( $row->meta_value ); - * $wpdb->query("UPDATE {$wpdb->postmeta} SET meta_value = {$fixed} WHERE meta_key = {$row->meta_key}"); - * } - * - * @param $input - * - * @return mixed - */ - static public function repair_serialized_object( $input ) { - return preg_replace( '!s:(\d+):"(.*?)";!e', "'s:'.strlen('$2').':\"$2\";'", $input ); - } - - /** - * Rename uploaded files as the hash of their original. - * - * @public - * @since 0.2.4 - * @method hashify_file_name - * @for UsabilityDynamics\Utility - * - * @param string $filename Original filename to hashify.. - * @param array|object $args Configuration arguments. - * - * @return string - * @author sopp@ID - */ - public static function hashify_file_name( $filename = null, $args = array() ) { - - if( !$filename ) { - return ''; - } - - $args = wp_parse_args( $args, array( - 'limit' => 99 - ) ); - - $info = pathinfo( $filename ); - $ext = empty( $info[ 'extension' ] ) ? '' : '.' . $info[ 'extension' ]; - - return md5( basename( $filename, $ext ) ) . rand( 0, $args[ 'limit' ] ) . $ext; - } - - /** - * Tests if remote image can be loaded. - * - * Returns URL to image if valid. - * Return false if image is invalid or could not be reached. - * - * @example - * - * // Try to load image. - * if( $url = Utility::can_get_image( $theme_settings->logo_url ) ) { - * echo "Image Found: $url."; - * } - * - * - * @method can_get_image - * @for Utility - * - * @param bool $url Valid URL to an image. - * - * @since 0.2.2 - * @return bool|int|string - */ - static public function can_get_image( $url = false ) { - - if( !is_string( $url ) ) { - return false; - } - - if( empty( $url ) ) { - return false; - } - - //** Test if post_id */ - if( is_numeric( $url ) && $image_attributes = wp_get_attachment_image_src( $url, 'full' ) ) { - $url = $image_attributes[ 0 ]; - } - - $result = wp_remote_get( $url, array( 'timeout' => 10 ) ); - - if( is_wp_error( $result ) ) { - return false; - } - - //** Image content types should always begin with 'image' ( I hope ) */ - if( strpos( $result[ 'headers' ][ 'content-type' ], 'image' ) !== 0 ) { - return false; - } - - return $url; - - } - - /** - * Return array of active plugins for current instance - * - * Improvement over wp_get_active_and_valid_plugins() which doesn't return any plugins when in MS - * - * @method get_active_plugins - * @for Utility - * - * @since 0.2.0 - */ - static public function get_active_plugins() { - $mu_plugins = (array) wp_get_mu_plugins(); - $regular_plugins = (array) wp_get_active_and_valid_plugins(); - - if( is_multisite() ) { - $network_plugins = (array) wp_get_active_network_plugins(); - } else { - $network_plugins = array(); - } - - return array_merge( $regular_plugins, $mu_plugins, $network_plugins ); - - } - - /** - * Validate URL - * - * @for Utility - * @since 0.1.1 - * - * @param string $url - * - * @param string $url - * - * @return bool - */ - static public function is_url( $url = '' ) { - return esc_url( $url ); - } - - /** - * Strip out protected keys from an associative array. - * - * Example below will remove all keys from array that being with $$: - * - * - * strip_protected_keys( $my_array, array( 'prefix' => '$$' ) ); - * - * - * @since 2.0 - * @author potanin@UD - */ - static public function strip_protected_keys( $array, $args = '' ) { - - $args = wp_parse_args( $args, array( 'prefix' => '_' ) ); - - foreach( (array) $array as $key => $value ) { - - if( strpos( $key, $args[ 'prefix' ] ) === 0 ) { - unset( $array[ $key ] ); - continue; - } - - if( is_array( $value ) ) { - $array[ $key ] = self::strip_protected_keys( $value, $args ); - } - - } - - $array = array_filter( $array ); - - return $array; - - } - - /** - * Recursively remove empty values from array. - * - * @method array_filter_deep - * @for Utility - * - * @version 1.0.1 - * @since 1.0.3 - * @author potanin@UD - */ - static public function array_filter_deep( $haystack = array() ) { - - foreach( (array) $haystack as $key => $value ) { - - if( is_object( $value ) || is_array( $value ) ) { - - if( is_object( $haystack ) ) { - $haystack->{$key} = self::array_filter_deep( (array) $value ); - } else if( is_array( $haystack ) ) { - $haystack[ $key ] = self::array_filter_deep( (array) $value ); - } - - } - - } - - return array_filter( (array) $haystack ); - - } - - /** - * Determines if a passed timestamp is newer than a requirement. - * - * Usage: UD_API::is_fresher_than( $timestamp, '5 minutes' ); - * - * @since 1.0.3 - */ - static public function fresher_than( $time, $ago = '1 week' ) { - return ( strtotime( "-" . $ago ) < $time ) ? true : false; - } - - /** - * Starts a timer for the passed string. - * - * @since 1.0.0.2 - * @author potanin@UD - */ - static public function timer_start( $function = 'global' ) { - global $ud_api; - - return $ud_api[ 'timers' ][ $function ][ 'start' ] = microtime( true ); - } - - /** - * Stop a timer. - * - * @since 1.0.0.2 - * @author potanin@UD - */ - static public function timer_stop( $function = 'global', $precision = 2 ) { - global $ud_api; - - return $ud_api[ 'timers' ][ $function ][ 'start' ] ? round( microtime( true ) - $ud_api[ 'timers' ][ $function ][ 'start' ], $precision ) : false; - } - - /** - * Start Profiling, can also double as timer. - * - * Profiling will only start if another profiling process is not already running. - * XHProf is required, other profilers may be added later. - * - * @updated 1.0.4 - * @since 1.0.0.2 - * @author potanin@UD - */ - static public function profiler_start( $method = false, $args = false ) { - global $ud_api; - - if( $ud_api[ 'profiling_now' ] && ( $ud_api[ 'profiling_now' ] != $method ) ) { - return; - } - - define( 'UD_API_Profiling', true ); - - if( extension_loaded( 'xhprof' ) && function_exists( 'xhprof_enable' ) ) { - xhprof_enable( XHPROF_FLAGS_CPU | XHPROF_FLAGS_NO_BUILTINS | XHPROF_FLAGS_MEMORY, $args ); - } - - return self::timer_start( $ud_api[ 'profiling_now' ] = $method ); - - } - - /** - * Stop Profiling. - * - * @since 1.0.0.2 - * @author potanin@UD - */ - static public function profiler_stop( $method = false, $args = false ) { - global $ud_api; - - if( $ud_api[ 'profiling_now' ] && ( $ud_api[ 'profiling_now' ] != $method ) ) { - return; - } - - if( extension_loaded( 'xhprof' ) && class_exists( 'XHProfRuns_Default' ) ) { - $xhprof_data = xhprof_disable(); - $xhprof_runs = new XHProfRuns_Default(); - $xhprof_runs->save_run( $xhprof_data, $method ); - } - - unset( $ud_api[ 'profiling_now' ] ); - - return self::timer_stop( $method ); - - } - - /** - * Attempt to download a remote files attachments - * - * @param bool $images - * @param array $args - * - * @return bool|object - */ - static public function image_fetch( $images = false, $args = array() ) { - - $images = array_filter( (array) $images ); - - //** Image URLs may be passed as string or array, or none at all */ - if( count( $images ) < 1 ) { - return false; - } - - self::timer_start( __METHOD__ ); - - $args = wp_parse_args( $args, array( - 'upload_dir' => false, - 'timeout' => 30, - ) ); - - /** - * Regular Image Download. - */ - foreach( (array) $images as $count => $url ) { - - $url = esc_url_raw( $url ); - - $_image = array( - 'source_url' => $url, - 'error' => false - ); - - //** Set correct filename ( some URLs can have not valid file extensions ) */ - $filename = sanitize_file_name( basename( $url ) ); - $ext = false; - $filetype = wp_check_filetype( $filename ); - if( !$filetype[ 'ext' ] ) { - $file_headers = get_headers( $url, 1 ); - if( strpos( $file_headers[ 0 ], '200 OK' ) ) { - if( isset( $file_headers[ 'Content-Type' ] ) ) { - $file_mime = sanitize_mime_type( $file_headers[ 'Content-Type' ] ); - switch( $file_mime ) { - case "image/gif": - $ext = 'gif'; - break; - case "image/jpeg": - $ext = 'jpg'; - break; - case "image/png": - $ext = 'png'; - break; - case "image/bmp": - $ext = 'bmp'; - break; - } - if( $ext ) { - $filename .= '.' . $ext; - } - } - } - } else { - $ext = $filetype[ 'ext' ]; - } - - $_wp_error_data = array( - 'url' => $url, - 'filename' => $filename, - 'file_type' => $ext, - ); - - //** We MUST NOT allow to upload not-image files */ - if( !$ext || !in_array( $ext, array( 'gif', 'jpg', 'png', 'bmp', 'jpeg' ) ) ) { - $_image[ 'error' ] = new WP_Error( __METHOD__, __( 'Invalid file type.', self::$text_domain ), $_wp_error_data ); - } - - //** Set file path */ - if( !empty( $args[ 'upload_dir' ] ) ) { - - if( wp_mkdir_p( $args[ 'upload_dir' ] ) ) { - $_image[ 'file' ] = trailingslashit( $args[ 'upload_dir' ] ) . wp_unique_filename( $args[ 'upload_dir' ], $filename ); - } else { - $_image[ 'error' ] = new WP_Error( __METHOD__, __( 'Could not create mentioned directory.', self::$text_domain ) ); - } - - } else { - - $wp_upload_bits = wp_upload_bits( $filename, null, '' ); - if( $wp_upload_bits[ 'error' ] ) { - $_image[ 'error' ] = new WP_Error( __METHOD__, $wp_upload_bits[ 'error' ], $wp_upload_bits ); - } - $_image = self::extend( $_image, $wp_upload_bits ); - - } - - if( !is_wp_error( $_image[ 'error' ] ) ) { - - $wp_remote_request = wp_remote_request( $url, array_filter( array( - 'method' => 'GET', - 'timeout' => $args[ 'timeout' ], - 'stream' => true, - 'filename' => $_image[ 'file' ] - ) ) ); - - if( is_wp_error( $wp_remote_request ) ) { - $wp_remote_request->add_data( $_wp_error_data ); - $_image[ 'error' ] = $wp_remote_request; - } else { - - $_image[ 'file' ] = $wp_remote_request[ 'filename' ]; - $_image[ 'filesize' ] = filesize( $_image[ 'file' ] ); - - /* Disabled. Was failing multiple images - if( isset( $wp_remote_request[ 'headers' ][ 'content-length'] ) && $_image[ 'filesize' ] != $wp_remote_request[ 'headers' ][ 'content-length'] ) { - $_image[ 'error' ] = new WP_Error( 'image_fetch', __( 'Remote file has incorrect size', self::$text_domain ), array( - 'headers' => $wp_remote_request[ 'headers' ], - 'image' => $_image - )); - }*/ - - if( 0 == $_image[ 'filesize' ] ) { - $_image[ 'error' ] = new WP_Error( __METHOD__, __( 'Zero size file downloaded', self::$text_domain ) ); - } - - $_image = self::extend( $_image, wp_check_filetype( $_image[ 'file' ] ) ); - - //require_once( ABSPATH . 'wp-admin/includes/image.php' ); - //wp_update_attachment_metadata( $row->attachment_id, wp_generate_attachment_metadata( $row->attachment_id, $upload[ 'file' ] ) ); - } - - } - - if( is_wp_error( $_image[ 'error' ] ) ) { - @unlink( $_image[ 'file' ] ); - } - - $return[ $count ] = (object) array_filter( $_image ); - - } //** End foreach */ - - return (object) array( - 'images' => $return, - 'timer' => self::timer_stop( __METHOD__ ) - ); - - } - - /** - * Checks if images exist and returns images dimensions - * - * @param mixed $images Image url - * @param mixed $args - * - * @return array - * @author peshkov@UD - */ - static public function image_dimensions( $images = false, $args = array() ) { - - $result = array(); - $images = array_filter( (array) $images ); - - //** Image URLs may be passed as string or array, or none at all */ - if( count( $images ) < 1 ) { - return $result; - } - - self::timer_start( __METHOD__ ); - - //** Params below are used only by RIM ( getMultiImageTypeAndSize ) **/ - $args = wp_parse_args( $args, array( - 'max_num_of_threads' => 10, - 'time_limit' => 30, - 'curl_connect_timeout' => 2, - 'curl_timeout' => 3, - ) ); - - //** If PHP 5.3.0, and rim class found, we use it. In other case we use default function getimagesize() */ - if( version_compare( PHP_VERSION, '5.3.0' ) >= 0 && method_exists( 'rim', 'getMultiImageTypeAndSize' ) ) { - $rim = new rim(); - $response = $rim->getMultiImageTypeAndSize( $images, $args ); - if( is_array( $response ) ) { - foreach( $response as $r ) { - $result[ ] = array( - 'width' => isset( $r[ 'image_data' ][ 'width' ] ) ? $r[ 'image_data' ][ 'width' ] : 0, - 'height' => isset( $r[ 'image_data' ][ 'height' ] ) ? $r[ 'image_data' ][ 'height' ] : 0, - 'url' => isset( $r[ 'url' ] ) ? $r[ 'url' ] : false, - 'error' => !empty( $r[ 'error' ] ) ? new WP_Error( 'image_fetch', __( 'Could not get image dimensions (headers)', 'wpp' ), $r[ 'error' ] ) : false - ); - } - } - } else { - $result = array(); - foreach( $images as $image ) { - $r = @getimagesize( $image ); - $result[ ] = array( - 'width' => isset( $r[ 0 ] ) ? $r[ 0 ] : 0, - 'height' => isset( $r[ 1 ] ) ? $r[ 1 ] : 0, - 'url' => $image, - 'error' => empty( $r ) ? new WP_Error( 'image_fetch', __( 'Could not get image dimensions (headers)', 'wpp' ) ) : false - ); - } - - } - - return $result; - } - - /** - * Converts slashes for Windows paths. - * - * @since 1.0.0.0 - * @source Flawless - * @author potanin@UD - */ - static public function fix_path( $path ) { - return str_replace( '\\', '/', $path ); - } - - /** - * Applies trim() function to all values in an array - * - * @source WP-Property - * @since 0.6.0 - */ - static public function trim_array( $array = array() ) { - - foreach( (array) $array as $key => $value ) { - - if( is_object( $value ) ) { - continue; - } - - $array[ $key ] = is_array( $value ) ? self::trim_array( $value ) : trim( $value ); - } - - return $array; - - } - - /** - * Returns all available image sizes - * - * @method all_image_sizes - * @for Utility - * - * @param $size {String} - * - * @returns array keys: 'width' and 'height' - */ - static public function all_image_sizes( $size = '' ) { - global $_wp_additional_image_sizes; - - $image_sizes = (array) $_wp_additional_image_sizes; - - $image_sizes[ 'thumbnail' ] = array( - 'width' => intval( get_option( 'thumbnail_size_w' ) ), - 'height' => intval( get_option( 'thumbnail_size_h' ) ) - ); - - $image_sizes[ 'medium' ] = array( - 'width' => intval( get_option( 'medium_size_w' ) ), - 'height' => intval( get_option( 'medium_size_h' ) ) - ); - - $image_sizes[ 'large' ] = array( - 'width' => intval( get_option( 'large_size_w' ) ), - 'height' => intval( get_option( 'large_size_h' ) ) - ); - - foreach( (array) $image_sizes as $_size => $data ) { - $image_sizes[ $_size ] = array_filter( (array) $data ); - $image_sizes[ $_size ][ 'label' ] = self::de_slug( $_size ); - $image_sizes[ $_size ][ 'crop' ] = isset( $image_sizes[ $_size ][ 'crop' ] ) && $image_sizes[ $_size ][ 'crop' ] ? $image_sizes[ $_size ][ 'crop' ] : false; - } - - if( $size ) { - return array_filter( (array) $image_sizes[ $size ] ); - } - - return array_filter( (array) $image_sizes ); - - } - - /** - * Retrieves the attachment ID from the file URL ( guid ) - * - * @global object $wpdb - * - * @param string $guid - * - * @return string - * @author peshkovUD - */ - static public function get_image_id_by_guid( $guid ) { - global $wpdb; - $attachment = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM {$wpdb->prefix}posts WHERE guid='%s';", $guid ) ); - - return !empty( $attachment[ 0 ] ) ? $attachment[ 0 ] : false; - } - - /** - * Returns Image link (url) - * - * If image with the current size doesn't exist, we try to generate it. - * If image cannot be resized, the URL to the main image (original) is returned. - * - * @todo Add something to check if requested image size is bigger than the original, in which case cannot be "resized" - * @todo Add a check to see if the specified image dimensions have changed. Right now only checks if slug exists, not the actualy size. - * - * @param bool $attachment_id - * @param bool $size - * @param array $args - * - * @return array|bool|mixed - */ - static public function get_image_link( $attachment_id = false, $size = false, $args = array() ) { - global $wp_properties; - - if( !$size || !$attachment_id ) { - return false; - } - - $image_sizes = self::all_image_sizes( $size ); - - $args = wp_parse_args( $args, array( - 'cache_id' => sanitize_title( $attachment_id . $size ), - 'return' => 'string', - 'default' => '', - 'cache_group' => 'ud_api' - ) ); - - //** Added 'return' arg to avoid cache problems odokienko@UD */ - $args[ 'cache_id' ] .= $args[ 'return' ]; - - if( $return = wp_cache_get( $args[ 'cache_id' ], $args[ 'cache_group' ] ) ) { - return $return; - } - - $attachment_image_src = ( array ) wp_get_attachment_image_src( $attachment_id, $size ); - - //** If wp_get_attachment_image_src() returned the information we need, we return it */ - if( empty( $image_sizes ) || ( is_array( $attachment_image_src ) && $attachment_image_src[ 1 ] == $image_sizes[ $size ][ 'width' ] ) ) { - - $return = $args[ 'return' ] == 'string' ? $attachment_image_src[ 0 ] : array( - 'url' => $attachment_image_src[ 0 ], - 'link' => $attachment_image_src[ 0 ], - 'width' => $attachment_image_src[ 1 ], - 'height' => $attachment_image_src[ 2 ], - 'crop' => $attachment_image_src[ 3 ] - ); - - wp_cache_set( $args[ 'cache_id' ], $return, $args[ 'cache_group' ] ); - - return $return; - } - - //** If we are this far, that means that the returned image, if any, was not the right size, so we regenreate */ - $image_resize = image_resize( get_attached_file( $attachment_id, true ), $image_sizes[ $size ][ 'width' ], $image_sizes[ $size ][ 'height' ], $image_sizes[ $size ][ 'crop' ] ); - - if( is_wp_error( $image_resize ) || !file_exists( $image_resize ) ) { - - if( $attachment_image_src[ 0 ] ) { - $return = $args[ 'default' ] ? $args[ 'default' ] : $attachment_image_src[ 0 ]; - } else { - $return = $args[ 'default' ]; - } - - } - - //** If image was resized, we update metadata, cache our result, and return */ - require_once( ABSPATH . 'wp-admin/includes/image.php' ); - - if( function_exists( 'wp_update_attachment_metadata' ) ) { - wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, get_attached_file( $attachment_id, true ) ) ); - } - - $attachment_image_src = (array) wp_get_attachment_image_src( $attachment_id, $size ); - - $return = $args[ 'return' ] == 'string' ? $attachment_image_src[ 0 ] : array( - 'url' => $attachment_image_src[ 0 ], - 'link' => $attachment_image_src[ 0 ], - 'width' => $attachment_image_src[ 1 ], - 'height' => $attachment_image_src[ 2 ], - 'crop' => $attachment_image_src[ 3 ] - ); - - wp_cache_set( $args[ 'cache_id' ], $return, $args[ 'cache_group' ] ); - - return $return; - - } - - /** - * Returns Image link (url) with custom size. - * Almost the same as get_image_link, but the current function can generate images with custom sizes. - * It generates image with custom size only once. - * - * @global $wpdb - * - * @param type $atts - * - * @return string - * @author peshkov@UD - * @since 0.2.5 - */ - static function get_image_link_with_custom_size( $attachment_id, $width, $height, $crop = false ) { - global $wpdb; - - // Sanitize - $height = absint( $height ); - $width = absint( $width ); - $needs_resize = true; - - // Look through the attachment meta data for an image that fits our size. - $meta = wp_get_attachment_metadata( $attachment_id ); - $upload_dir = wp_upload_dir(); - $base_url = strtolower( $upload_dir[ 'baseurl' ] ); - $src = trailingslashit( $base_url ) . $meta[ 'file' ]; - foreach( $meta[ 'sizes' ] as $key => $size ) { - if( ( $size[ 'width' ] == $width && $size[ 'height' ] == $height ) || $key == sprintf( 'resized-%dx%d', $width, $height ) ) { - if( !empty( $size[ 'file' ] ) ) { - $src = str_replace( basename( $src ), $size[ 'file' ], $src ); - } - $needs_resize = false; - break; - } - } - - // If an image of such size was not found, we can create one. - if( $needs_resize ) { - $attached_file = get_attached_file( $attachment_id ); - $resized = image_make_intermediate_size( $attached_file, $width, $height, $crop ); - if( is_wp_error( $resized ) ) { - return $resized; - } - - // Let metadata know about our new size. - $key = sprintf( 'resized-%dx%d', $width, $height ); - $meta[ 'sizes' ][ $key ] = $resized; - if( !empty( $resized[ 'file' ] ) ) { - $src = str_replace( basename( $src ), $resized[ 'file' ], $src ); - } - wp_update_attachment_metadata( $attachment_id, $meta ); - - // Record in backup sizes so everything's cleaned up when attachment is deleted. - $backup_sizes = get_post_meta( $attachment_id, '_wp_attachment_backup_sizes', true ); - if( !is_array( $backup_sizes ) ) $backup_sizes = array(); - $backup_sizes[ $key ] = $resized; - update_post_meta( $attachment_id, '_wp_attachment_backup_sizes', $backup_sizes ); - - } - - return array( - 'url' => esc_url( $src ), - 'width' => absint( $width ), - 'height' => absint( $height ), - ); - } - - /** - * Insert array into an associative array before a specific key - * - * @source http://stackoverflow.com/questions/6501845/php-need-help-inserting-arrays-into-associative-arrays-at-given-keys - * @author potanin@UD - */ - static public function array_insert_before( $array, $key, $new ) { - $array = (array) $array; - $keys = array_keys( $array ); - $pos = (int) array_search( $key, $keys ); - - return array_merge( - array_slice( $array, 0, $pos ), - $new, - array_slice( $array, $pos ) - ); - } - - /** - * Insert array into an associative array after a specific key - * - * @source http://stackoverflow.com/questions/6501845/php-need-help-inserting-arrays-into-associative-arrays-at-given-keys - * @author potanin@UD - */ - static public function array_insert_after( $array, $key, $new ) { - $array = (array) $array; - $keys = array_keys( $array ); - $pos = (int) array_search( $key, $keys ) + 1; - - return array_merge( - array_slice( $array, 0, $pos ), - $new, - array_slice( $array, $pos ) - ); - } - - /** - * Attemp to convert a plural US word into a singular. - * - * @todo API Service Candidate since we ideally need a dictionary reference. - * @author potanin@UD - */ - static public function depluralize( $word ) { - $rules = array( 'ss' => false, 'os' => 'o', 'ies' => 'y', 'xes' => 'x', 'oes' => 'o', 'ies' => 'y', 'ves' => 'f', 's' => '' ); - - foreach( array_keys( $rules ) as $key ) { - - if( substr( $word, ( strlen( $key ) * -1 ) ) != $key ) - continue; - - if( $key === false ) - return $word; - - return substr( $word, 0, strlen( $word ) - strlen( $key ) ) . $rules[ $key ]; - - } - - return $word; - - } - - /** - * Convert bytes into the logical unit of measure based on size. - * - * @source Flawless - * @since 1.0.0.0 - * @author potanin@UD - */ - static public function format_bytes( $bytes, $precision = 2 ) { - _deprecated_function( __FUNCTION__, '2.3.0', 'size_format()' ); - - return size_format( $bytes, $precision ); - } - - /** - * Used to enable/disable/print SQL log - * - * Usage: - * self::sql_log( 'enable' ); - * self::sql_log( 'disable' ); - * $queries= self::sql_log( 'print_log' ); - * - * @since 0.1.0 - */ - static public function sql_log( $action = 'attach_filter' ) { - global $wpdb; - - if( !in_array( $action, array( 'enable', 'disable', 'print_log' ) ) ) { - $wpdb->ud_queries[ ] = array( $action, $wpdb->timer_stop(), $wpdb->get_caller() ); - - return $action; - } - - if( $action == 'enable' ) { - add_filter( 'query', array( __CLASS__, 'sql_log' ), 75 ); - } - - if( $action == 'disable' ) { - remove_filter( 'query', array( __CLASS__, 'sql_log' ), 75 ); - } - - if( $action == 'print_log' ) { - $result = array(); - foreach( (array) $wpdb->ud_queries as $query ) { - $result[ ] = $query[ 0 ] ? $query[ 0 ] . ' (' . $query[ 1 ] . ')' : $query[ 2 ]; - } - - return $result; - } - - } - - /** - * Return data for UD Log - * - * @updated 1.04 - * @sincde 1.03 - * @note This is a proof of concept, in future it should be able to support AJAX calls so can be displayed via Dynamic Filter. - * @author potanin@UD - */ - static public function log( $message = '', $args = array() ) { - global $wpdb; - - //** Prevents MySQL Gone Away. @todo Should check if connection exists before automatically connecting. */ - //$wpdb->db_connect(); - - //** Create Log if it does not exist */ - if( !$wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->prefix}ud_log';" ) ) { - require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); - dbDelta( "CREATE TABLE {$wpdb->prefix}ud_log ( - id mediumint(9) NOT NULL AUTO_INCREMENT, - post_id mediumint(9) DEFAULT NULL COMMENT 'ID of related post.', - product VARCHAR(100) DEFAULT '' NOT NULL COMMENT 'Slug of related product.', - feature VARCHAR(100) DEFAULT '' NOT NULL COMMENT 'Slug of specific feature, if applicable.', - message text NOT NULL COMMENT 'Long description of log entry.', - type VARCHAR(100) DEFAULT '' NOT NULL COMMENT 'Type of variable stored in message. May be concatentaetd with other data for additional information.', - action VARCHAR(128) DEFAULT '' NOT NULL COMMENT 'If applicable, a slug for a specific action that triggered the entry.', - method VARCHAR(128) DEFAULT '' NOT NULL COMMENT 'If applicable, PHP method that triggered log entry.', - time int(11) NOT NULL, - UNIQUE KEY id (id), - KEY post_id (post_id), - KEY type (type) - );" ); - } - - $args = array_filter( (array) shortcode_atts( array( - 'post_id' => null, - 'type' => gettype( $message ), - 'message' => maybe_serialize( $message ), - 'product' => null, - 'feature' => null, - 'action' => null, - 'method' => null, - 'time' => time() - ), $args ) ); - - //** Only the keys below may be updated via $args */ - $wpdb->insert( $wpdb->prefix . 'ud_log', $args ); - - return $wpdb->insert_id ? $message : false; - } - - /** - * Return data for UD Log - * - * @note This is a proof of concept, in future it should be able to support AJAX calls so can be displayed via Dynamic Filter. - * @author potanin@UD - */ - static public function get_log( $args = false ) { - global $wpdb; - - $args = wp_parse_args( $args, array( - 'offset' => 0, - 'limit' => 100, - 'last_id' => false, - 'sort_type' => 'ASC', - 'direction' => 'greater', - 'product' => '', - 'post_id' => false, - ) ); - - $where = array(); - if( $args[ 'last_id' ] && $args[ 'last_id' ] > 1 ) { - $direction = ''; - switch( $args[ 'direction' ] ) { - case 'greater': - $direction = '>'; - break; - case 'less': - $direction = '<'; - break; - } - if( !empty( $direction ) ) { - $where[ ] = " l.id {$direction} {$args['last_id']} "; - } - } - - foreach( $args as $k => $v ) { - if( in_array( $k, array( 'product', 'post_id' ) ) && !empty( $v ) ) { - if( is_array( $v ) ) { - $where[ ] = " l.{$k} IN ( '" . implode( "','", $v ) . "' ) "; - } else { - $where[ ] = " l.{$k} = '{$v}' "; - } - } - } - - if( !empty( $where ) ) { - $where = " WHERE " . implode( " AND ", $where ) . " "; - } else { - $where = ''; - } - - $response = $wpdb->get_results( " - SELECT l.*, p.post_title - FROM {$wpdb->prefix}ud_log l - LEFT JOIN {$wpdb->posts} p ON l.post_id = p.ID - {$where} - ORDER BY l.id {$args['sort_type']} - LIMIT {$args['offset']}, {$args['limit']}; - " ); - - //die( '
        ' . print_r( $wpdb->last_query ,true) . '
        ' ); - - return $response; - - } - - /** - * Removes data from Logs table - * - * @param mixed $args - * - * @author peshkov@UD - */ - static public function clear_log( $args = array() ) { - global $wpdb; - - $args = array_filter( self::prepare_to_sql( wp_parse_args( $args, array( - 'id' => false, - 'product' => false, - 'feature' => false, - 'product_id' => false, - 'type' => false, - 'action' => false, - ) ) ) ); - - $where = ""; - foreach( $args as $k => $v ) { - $where .= empty( $where ) ? " WHERE " : " AND "; - $where .= " {$k} = '{$v}' "; - } - - return $wpdb->query( "DELETE FROM {$wpdb->prefix}ud_log {$where}" ); - } - - /** - * Add an entry to the plugin-specifig log. - * - * Creates log if one does not exist. - * - * - * UD\Utility::log( "Settings updated." ); - * - * - * @depreciated peshkov@UD - */ - static public function _log( $message = false, $args = array() ) { - - $args = wp_parse_args( $args, array( - 'type' => 'default', - 'object' => false, - 'prefix' => 'ud', - ) ); - - extract( $args ); - - $log = "{$prefix}_log"; - - if( !did_action( 'init' ) ) { - _doing_it_wrong( __FUNCTION__, sprintf( __( 'You cannot call UD\Utility::log() before the %1$s hook, since the current user is not yet known.' ), 'init' ), '3.4' ); - } - - $current_user = wp_get_current_user(); - - $this_log = get_option( $log ); - - if( empty( $this_log ) ) { - - $this_log = array(); - - $entry = array( - 'time' => time(), - 'message' => __( 'Log Started.', self::$text_domain ), - 'user' => $current_user->ID, - 'type' => $type - ); - - } - - if( $message ) { - - $entry = array( - 'time' => time(), - 'message' => $message, - 'user' => $type == 'system' ? 'system' : $current_user->ID, - 'type' => $type, - 'object' => $object - ); - - } - - if( !is_array( $entry ) ) { - return false; - } - - array_push( $this_log, $entry ); - - $this_log = array_filter( $this_log ); - - update_option( $log, $this_log ); - - return true; - - } - - /** - * Helpder function for figuring out if another specific function is a predecesor of current function. - * - * @since 1.0.0.0 - * @author potanin@UD - */ - static public function _backtrace_function( $function = false ) { - - foreach( debug_backtrace() as $step ) { - if( $function && $step[ 'function' ] == $function ) { - return true; - } - } - - } - - /** - * Helpder function for figuring out if a specific file is a predecesor of current file. - * - * @since 1.0.0.0 - * @author potanin@UD - */ - static public function _backtrace_file( $file = false ) { - - foreach( debug_backtrace() as $step ) { - if( $file && basename( $step[ 'file' ] ) == $file ) { - return true; - } - } - - } - - /** - * Fixed serialized arrays which sometimes get messed up in WordPress - * - * @source http://shauninman.com/archive/2008/01/08/recovering_truncated_php_serialized_arrays - */ - static public function repair_serialized_array( $serialized ) { - $tmp = preg_replace( '/^a:\d+:\{/', '', $serialized ); - - return self::repair_serialized_array_callback( $tmp ); // operates on and whittles down the actual argument - } - - /** - * The recursive function that does all of the heavy lifing. Do not call directly. - - - */ - static public function repair_serialized_array_callback( &$broken ) { - - $data = array(); - $index = null; - $len = strlen( $broken ); - $i = 0; - - while( strlen( $broken ) ) { - $i++; - if( $i > $len ) { - break; - } - - if( substr( $broken, 0, 1 ) == '}' ) // end of array - { - $broken = substr( $broken, 1 ); - - return $data; - } else { - $bite = substr( $broken, 0, 2 ); - switch( $bite ) { - case 's:': // key or value - $re = '/^s:\d+:"([^\"]*)";/'; - if( preg_match( $re, $broken, $m ) ) { - if( $index === null ) { - $index = $m[ 1 ]; - } else { - $data[ $index ] = $m[ 1 ]; - $index = null; - } - $broken = preg_replace( $re, '', $broken ); - } - break; - - case 'i:': // key or value - $re = '/^i:(\d+);/'; - if( preg_match( $re, $broken, $m ) ) { - if( $index === null ) { - $index = (int) $m[ 1 ]; - } else { - $data[ $index ] = (int) $m[ 1 ]; - $index = null; - } - $broken = preg_replace( $re, '', $broken ); - } - break; - - case 'b:': // value only - $re = '/^b:[01];/'; - if( preg_match( $re, $broken, $m ) ) { - $data[ $index ] = (bool) $m[ 1 ]; - $index = null; - $broken = preg_replace( $re, '', $broken ); - } - break; - - case 'a:': // value only - $re = '/^a:\d+:\{/'; - if( preg_match( $re, $broken, $m ) ) { - $broken = preg_replace( '/^a:\d+:\{/', '', $broken ); - $data[ $index ] = self::repair_serialized_array_callback( $broken ); - $index = null; - } - break; - - case 'N;': // value only - $broken = substr( $broken, 2 ); - $data[ $index ] = null; - $index = null; - break; - } - } - } - - return $data; - } - - /** - * Determine if an item is in array and return checked - * - * @since 0.5.0 - */ - static public function checked_in_array( $item, $array ) { - - if( is_array( $array ) && in_array( $item, $array ) ) { - echo ' checked="checked" '; - } - - } - - /** - * Check if the current WP version is older then given parameter $version. - * - * @param string $version - * - * @return bool - * @since 1.0.0.0 - * @author peshkov@UD - */ - static public function is_older_wp_version( $version = '' ) { - if( empty( $version ) || (float) $version == 0 ) return false; - $current_version = get_bloginfo( 'version' ); - /** Clear version numbers */ - $current_version = preg_replace( "/^([0-9\.]+)-(.)+$/", "$1", $current_version ); - $version = preg_replace( "/^([0-9\.]+)-(.)+$/", "$1", $version ); - - return ( (float) $current_version < (float) $version ) ? true : false; - } - - /** - * Determine if any requested template exists and return path to it. - * - * == Usage == - * The function will search through: STYLESHEETPATH, TEMPLATEPATH, and any custom paths you pass as second argument. - * - * $best_template = UD\Utility::get_template_part( array( - * 'template-ideal-match', - * 'template-default', - * ), array( PATH_TO_MY_TEMPLATES ); - * - * Note: load_template() extracts $wp_query->query_vars into the loaded template, so to add any global variables to the template, add them to - * $wp_query->query_vars prior to calling this function. - * - * @param mixed $name List of requested templates. Will be return the first found - * @param array $path [optional]. Method tries to find template in theme, but also it can be found in given list of pathes. - * @param array $opts [optional]. Set of additional params: - * - string $instance. Template can depend on instance. For example: facebook, PDF, etc. Uses filter: ud::template_part::{instance} - * - boolean $load. if true, rendered HTML will be returned, in other case, only found template's path. - * @load boolean [optional]. If true and a template is found, the template will be loaded via load_template() and returned as a string - * @author peshkov@UD - * @version 1.1 - */ - static public function get_template_part( $name, $path = array(), $opts = array() ) { - $name = (array)$name; - $template = ""; - - /** - * Set default instance. - * Template can depend on instance. For example: facebook, PDF, etc. - */ - $instance = apply_filters( "ud::current_instance", "default" ); - - $opts = wp_parse_args( $opts, array( - 'instance' => $instance, - 'load' => false, - ) ); - - //** Allows to add/change templates storage directory. */ - $path = apply_filters( "ud::template_part::path", $path, $name, $opts ); - - foreach ( $name as $n ) { - $n = "{$n}.php"; - $template = locate_template( $n, false ); - if ( empty( $template ) && !empty( $path ) ) { - foreach ( (array)$path as $p ) { - if ( file_exists( $p . "/" . $n ) ) { - $template = $p . "/" . $n; - break( 2 ); - } - } - } - if ( !empty( $template ) ) break; - } - - $template = apply_filters( "ud::template_part::{$opts['instance']}", $template, array( 'name' => $name, 'path' => $path, 'opts' => $opts ) ); - - //** If match and load was requested, get template and return */ - if( !empty( $template ) && $opts[ 'load' ] == true ) { - ob_start(); - load_template( $template, false ); - return ob_get_clean(); - } - - return !empty( $template ) ? $template : false; - - } - - /** - * The goal of function is going through specific filters and return (or print) classes. - * This function should not be called directly. - * Every ud plugin/theme should have own short function ( wrapper ) for calling it. E.g., see: wpp_css(). - * So, use it in template as:
        ">
        - * - * Arguments: - * - instance [string] - UD plugin|theme's slug. E.g.: wpp, denali, wpi, etc - * - element [string] - specific element in template which will use the current classes. - * Element should be called as {template}::{specific_name_of_element}. Where {template} is name of template, - * where current classes will be used. This standart is optional. You can set any element's name if you want. - * - classes [array] - set of classes which will be used for element. - * - return [boolean] - If false, the function prints all classes like 'class1 class2 class3' - * - * @param array $args - * - * @return string - * @author peshkov@UD - * @version 0.1 - */ - static public function get_css_classes( $args = array() ) { - - //** Set arguments */ - $args = wp_parse_args( (array) $args, array( - 'classes' => array(), - 'instance' => '', - 'element' => '', - 'return' => false, - ) ); - - extract( $args ); - - //** Cast (set correct types) to avoid issues */ - if( !is_array( $classes ) ) { - $classes = trim( $classes ); - $classes = str_replace( ',', ' ', $classes ); - $classes = explode( ' ', $classes ); - } - - foreach( $classes as &$c ) { - $c = trim( $c ); - } - - $instance = (string) $instance; - $element = (string) $element; - - //** Now go through the filters */ - $classes = apply_filters( "$instance::css::$element", $classes, $args ); - - if( !$return ) { - echo implode( " ", (array) $classes ); - } - - return implode( " ", (array) $classes ); - - } - - /** - * Return simple array of column tables in a table - * - * @version 0.6 - */ - static public function get_column_names( $table ) { - - global $wpdb; - - $table_info = $wpdb->get_results( "SHOW COLUMNS FROM $table" ); - - if( empty( $table_info ) ) { - return array(); - } - - foreach( (array) $table_info as $row ) { - $columns[ ] = $row->Field; - } - - return $columns; - - } - - /** - * Port of jQuery.extend() function. - * - * @since 1.0.3 - */ - static public function extend() { - - $arrays = func_get_args(); - $base = array_shift( $arrays ); - if( !is_array( $base ) ) $base = empty( $base ) ? array() : array( $base ); - foreach( (array) $arrays as $append ) { - if( !is_array( $append ) ) $append = array( $append ); - foreach( (array) $append as $key => $value ) { - if( !array_key_exists( $key, $base ) and !is_numeric( $key ) ) { - $base[ $key ] = $append[ $key ]; - continue; - } - if( ( isset( $value ) && @is_array( $value ) ) || ( isset( $base[ $key ] ) && @is_array( $base[ $key ] ) ) ) { - - // extend if exists, otherwise create. - if( isset( $base[ $key ] ) ) { - $base[ $key ] = self::extend( $base[ $key ], $append[ $key ] ); - } else { - $base[ $key ] = $append[ $key ]; - } - - } else if( is_numeric( $key ) ) { - if( !in_array( $value, $base ) ) $base[ ] = $value; - } else { - $base[ $key ] = $value; - } - } - } - - return $base; - } - - /** - * Returns a URL to a post object based on passed variable. - * - * If its a number, then assumes its the id, If it resembles a slug, then get the first slug match. - * - * @since 1.0.0 - * - * @param bool|string $title A page title, although ID integer can be passed as well - * - * @return string The page's URL if found, otherwise the general blog URL - */ - static public function post_link( $title = false ) { - - global $wpdb; - - if( !$title ) return get_bloginfo( 'url' ); - - if( is_numeric( $title ) ) return get_permalink( $title ); - - if( $id = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_name = %s AND post_status='publish'", $title ) ) ) return get_permalink( $id ); - - if( $id = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE LOWER(post_title) = %s AND post_status='publish'", strtolower( $title ) ) ) ) return get_permalink( $id ); - - } - - /** - * Used to get the current plugin's log created via UD class - * - * If no log exists, it creates one, and then returns it in chronological order. - * - * Example to view log: - * - * print_r( self::get_log() ); - * - * - * $param string Event description - * - * @depreciated peshkov@UD - * @uses get_option() - * @uses update_option() - * @return array Using the get_option function returns the contents of the log. - * - * @param bool $args - * - * @return array Using the get_option function returns the contents of the log. - */ - static public function _get_log( $args = false ) { - - $args = wp_parse_args( $args, array( - 'limit' => 20, - 'prefix' => 'ud' - ) ); - - extract( $args ); - - $this_log = get_option( $prefix . '_log' ); - - if( empty( $this_log ) ) { - $this_log = self::log( false, array( 'prefix' => $prefix ) ); - } - - $entries = (array) get_option( $prefix . '_log' ); - - $entries = array_reverse( $entries ); - - $entries = array_slice( $entries, 0, $args[ 'args' ] ? $args[ 'args' ] : $args[ 'limit' ] ); - - return $entries; - - } - - /** - * Delete UD log for this plugin. - * - * @uses update_option() - */ - static public function delete_log( $args = array() ) { - - $args = wp_parse_args( $args, array( - 'prefix' => 'ud' - ) ); - - extract( $args ); - - $log = "{$prefix}_log"; - - delete_option( $log ); - } - - /** - * Creates Admin Menu page for UD Log - * - * @todo Need to make sure this will work if multiple plugins utilize the UD classes - * @see function show_log_page - * @since 1.0.0 - * @uses add_action() Calls 'admin_menu' hook with an anonymous ( lambda-style ) function which uses add_menu_page to create a UI Log page - */ - static public function add_log_page() { - if( did_action( 'admin_menu' ) ) { - _doing_it_wrong( __FUNCTION__, sprintf( __( 'You cannot call UD\Utility::add_log_page() after the %1$s hook.' ), 'init' ), '3.4' ); - - return false; - } - add_action( 'admin_menu', function() { - add_menu_page( __( 'Log', UD_API_Transdomain ), __( 'Log', UD_API_Transdomain ), current_user_can( 'manage_options' ), 'ud_log', array( 'UD_API', 'show_log_page' ) ); - }); - } - - /** - * Displays the UD UI log page. - * - * @todo Add button or link to delete log - * @todo Add nonce to clear_log functions - * @todo Should be refactored to implement adding LOG tabs for different instances (wpp, wpi, wp-crm). peshkov@UD - * - * @since 1.0.0.0 - */ - static public function show_log_page() { - - if( $_REQUEST[ 'ud_action' ] == 'clear_log' ) { - self::delete_log(); - } - - $output = array(); - - $output[ ] = ''; - - $output[ ] = '
        '; - $output[ ] = '

        ' . __( 'Log Page for', self::$text_domain ) . ' ud_log '; - $output[ ] = '' . __( 'Clear Log', self::$text_domain ) . '

        '; - - $output[ ] = ''; - $output[ ] = ''; - $output[ ] = ''; - $output[ ] = ''; - $output[ ] = ''; - $output[ ] = ''; - $output[ ] = ''; - - $output[ ] = ''; - - foreach( (array) self::_get_log() as $event ) { - $output[ ] = ''; - $output[ ] = ''; - $output[ ] = ''; - $output[ ] = ''; - $output[ ] = ''; - $output[ ] = ''; - $output[ ] = ''; - } - - $output[ ] = '
        ' . __( 'Timestamp', self::$text_domain ) . '' . __( 'Type', self::$text_domain ) . '' . __( 'Event', self::$text_domain ) . '' . __( 'User', self::$text_domain ) . '' . __( 'Related Object', self::$text_domain ) . '
        ' . self::nice_time( $event[ 'time' ] ) . '' . $event[ 'type' ] . '' . $event[ 'message' ] . '' . ( is_numeric( $event[ 'user' ] ) ? get_userdata( $event[ 'user' ] )->display_name : __( 'None' ) ) . '' . $event[ 'object' ] . '
        '; - - $output[ ] = '
        '; - - echo implode( '', (array) $output ); - - } - - /** - * Replace in $str all entries of keys of the given $values - * where each key will be rounded by $brackets['left'] and $brackets['right'] - * with the relevant values of the $values - * - * @param string|array $str - * @param array $values - * @param array $brackets - * - * @return string|array - * @author odokienko@UD - */ - static public function replace_data( $str = '', $values = array(), $brackets = array( 'left' => '[', 'right' => ']' ) ) { - $values = (array) $values; - $replacements = array_keys( $values ); - array_walk( $replacements, function(&$val) use ($brackets){ - $val = $brackets[ 'left' ] . $val . $brackets[ 'right' ]; - } ); - - return str_replace( $replacements, array_values( $values ), $str ); - } - - /** - * Wrapper function to send notification with WP-CRM or without one - * - * @param array|mixed $args ['message'] using in email notification - * - * @uses self::replace_data() - * @uses wp_crm_send_notification() - * @return boolean false if notification was not sent successfully - * @autor odokienko@UD - */ - static public function send_notification( $args = array() ) { - - $args = wp_parse_args( $args, array( - 'ignore_wp_crm' => false, - 'user' => false, - 'trigger_action' => false, - 'data' => array(), - 'message' => '', - 'subject' => '', - 'crm_log_message' => '' - ) ); - - if( is_numeric( $args[ 'user' ] ) ) { - $args[ 'user' ] = get_user_by( 'id', $args[ 'user' ] ); - } elseif( filter_var( $args[ 'user' ], FILTER_VALIDATE_EMAIL ) ) { - $args[ 'user' ] = get_user_by( 'email', $args[ 'user' ] ); - } elseif( is_string( $args[ 'user' ] ) ) { - $args[ 'user' ] = get_user_by( 'login', $args[ 'user' ] ); - } - - if( !is_object( $args[ 'user' ] ) || empty( $args[ 'user' ]->data->user_email ) ) { - return false; - } - - if( function_exists( 'wp_crm_send_notification' ) && - empty( $args[ 'ignore_wp_crm' ] ) - ) { - - if( !empty( $args[ 'crm_log_message' ] ) ) { - wp_crm_add_to_user_log( $args[ 'user' ]->ID, self::replace_data( $args[ 'crm_log_message' ], $args[ 'data' ] ) ); - } - - if ( !empty( $args[ 'trigger_action' ] ) && is_callable( 'WP_CRM_N', 'get_trigger_action_notification' ) ) { - $notifications = \WP_CRM_N::get_trigger_action_notification( $args[ 'trigger_action' ] ); - if ( !empty( $notifications ) ) { - return wp_crm_send_notification( $args[ 'trigger_action' ], $args[ 'data' ] ); - } - } - - } - - if( empty( $args[ 'message' ] ) ) { - return false; - } - - return wp_mail( $args[ 'user' ]->data->user_email, self::replace_data( $args[ 'subject' ], $args[ 'data' ] ), self::replace_data( $args[ 'message' ], $args[ 'data' ] ) ); - - } - - /** - * Turns a passed string into a URL slug - * - * @param bool|string $content - * @param bool|string $args Optional list of arguments to overwrite the defaults. - * - * @author potanin@UD - * @version 1.1.0 - * @since 1.0.0 - * @return string - */ - static public function create_slug( $content = null, $args = false ) { - - if( !$content ) { - return null; - } - - $args = wp_parse_args( $args, array( - 'separator' => '-' - ) ); - - $content = preg_replace( '~[^\\pL0-9_]+~u', $args[ 'separator' ], $content ); // substitutes anything but letters, numbers and '_' with separator - $content = trim( $content, $args[ 'separator' ] ); - $content = iconv( "utf-8", "us-ascii//TRANSLIT", $content ); // TRANSLIT does the whole job - $content = strtolower( $content ); - - // Removed the following logic because it was removing custom separators such as ":". - potanin@UD | October 17, 2013 - // return preg_replace( '~[^-a-z0-9_]+~', '', $content ); // keep only letters, numbers, '_' and separator - - return $content; - - } - - /** - * Convert a slug to a more readable string - * - * @since 1.3 - * - * @param $string - * - * @return string - */ - static public function de_slug( $string ) { - return ucwords( str_replace( "_", " ", $string ) ); - } - - /** - * Returns current url - * - * @param mixed $args GET args which should be added to url - * @param mixed $except_args GET args which will be removed from URL if they exist - * - * @return string - * @author peshkov@UD - */ - static public function current_url( $args = array(), $except_args = array() ) { - $url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER[ 'HTTP_HOST' ] . $_SERVER[ 'REQUEST_URI' ]; - - $args = wp_parse_args( $args ); - $except_args = wp_parse_args( $except_args ); - - if( !empty( $args ) ) { - foreach( (array) $args as $k => $v ) { - if( is_string( $v ) ) $url = add_query_arg( $k, $v, $url ); - } - } - - if( !empty( $except_args ) ) { - foreach( (array) $except_args as $arg ) { - if( is_string( $arg ) ) $url = remove_query_arg( $arg, $url ); - } - } - - return $url; - } - - /** - * Prepares data for SQL query. - * - * i.e. It should be used when $pwdb->prepare cannot be used. - * For example: - * we have situation when SQL query could not be prepared by default $wpdb->prepare: - * $titles = array( "John's appartment", " '; DELETE FROM $wpdb->posts;# " ); - * $wpdb->query( "SELECT ID FROM $wpdb->posts WHERE post_title IN ( '" . implode ("','", UD_Utility::prepare_to_sql( $titles ) ) . "' ) " ); - * - * @global type $wpdb - * - * @param mixed $args data which should be prepared for SQL query - * - * @return mixed prepared data - * @author peshkov@UD - */ - static public function prepare_to_sql( $args ) { - global $wpdb; - - $prepared = $args; - if( is_array( $prepared ) ) { - foreach( $prepared as $k => $v ) { - if( is_string( $v ) ) { - $prepared[ $k ] = $wpdb->_real_escape( $v ); - } else if( is_array( $v ) ) { - $prepared[ $k ] = self::prepare_to_sql( $v ); - } - } - } else if( is_string( $prepared ) ) { - $prepared = $wpdb->_real_escape( $prepared ); - } - - return $prepared; - } - - /** - * Returns date and/or time using the WordPress date or time format, as configured. - * - * @param bool|string $time Date or time to use for calculation. - * @param bool|string $args List of arguments to overwrite the defaults. - * - * @uses wp_parse_args() - * @uses get_option() - * @return string|bool Returns formatted date or time, or false if no time passed. - * @updated 3.0 - */ - static public function nice_time( $time = false, $args = false ) { - - $args = wp_parse_args( $args, array( - 'format' => 'date_and_time' - ) ); - - if( !$time ) { - return false; - } - - if( $args[ 'format' ] == 'date' ) { - return date( get_option( 'date_format' ), $time ); - } - - if( $args[ 'format' ] == 'time' ) { - return date( get_option( 'time_format' ), $time ); - } - - if( $args[ 'format' ] == 'date_and_time' ) { - return date( get_option( 'date_format' ), $time ) . ' ' . date( get_option( 'time_format' ), $time ); - } - - return false; - - } - - /** - * This function is for the encryption of data - * - * @source http://stackoverflow.com/questions/1289061/best-way-to-use-php-to-encrypt-and-decrypt - * @source http://php.net/manual/en/function.base64-encode.php - * @author williams@ud - * - * @param mixed $pt Object or plain text string - * @param bool|string $salt The salt to use - * - * @return mixed - */ - static public function encrypt( $pt, $salt = false ) { - - if( !$salt ) $salt = AUTH_SALT; - $encrypted = base64_encode( mcrypt_encrypt( MCRYPT_RIJNDAEL_256, md5( $salt ), $pt, MCRYPT_MODE_CBC, md5( md5( $salt ) ) ) ); - $encrypted = str_replace( array( '+', '/', '=' ), array( '-', '_', '' ), $encrypted ); - - return $encrypted; - - } - - /** - * This function decrypts data - * - * @source http://stackoverflow.com/questions/1289061/best-way-to-use-php-to-encrypt-and-decrypt - * @source http://php.net/manual/en/function.base64-encode.php - * @author williams@ud - * - * @param mixed $ct Ciphertext - * @param bool|string $salt The salt to use - * - * @return string - */ - static public function decrypt( $ct, $salt = false ) { - - if( !$salt ) $salt = AUTH_SALT; - $data = str_replace( array( '-', '_' ), array( '+', '/' ), $ct ); - $mod4 = strlen( $data ) % 4; - if( $mod4 ) { - $data .= substr( '====', $mod4 ); - } - $decrypted = rtrim( mcrypt_decrypt( MCRYPT_RIJNDAEL_256, md5( $salt ), base64_decode( $data ), MCRYPT_MODE_CBC, md5( md5( $salt ) ) ), "\0" ); - - return ( $decrypted ); - - } - - /** - * Returns array of full pathes of files or directories which we try to find. - * - * @param mixed $needle Directory(ies) or file(s) which we want to find - * @param string $path The path where we try to find it - * @param boolean $_is_dir We're finding dir or file. Default is file. - * - * @return array - * @author peshkov@UD - */ - static public function find_file_in_system( $needle, $path, $_is_dir = false ) { - $return = array(); - $needle = (array) $needle; - $dir = @opendir( $path ); - - if( $dir ) { - while( ( $file = readdir( $dir ) ) !== false ) { - if( $file[ 0 ] == '.' ) { - continue; - } - $fullpath = trailingslashit( $path ) . $file; - if( is_dir( $fullpath ) ) { - if( $_is_dir && in_array( $file, $needle ) ) { - $return[ ] = $fullpath; - } - $return = array_merge( $return, self::find_file_in_system( $needle, $fullpath, $_is_dir ) ); - } else { - if( !$_is_dir && in_array( $file, $needle ) ) { - $return[ ] = $fullpath; - } - } - } - } - - return $return; - } - - /** - * Gets complicated html entity e.g. Table and ou|ol - * and removes whitespace characters include new line. - * we should to do this before use nl2br - * - * @author odokienko@UD - */ - static public function cleanup_extra_whitespace( $content ) { - $content = preg_replace_callback( '~<(?:table|ul|ol )[^>]*>.*?<\/( ?:table|ul|ol )>~ims', function($matches){ - return preg_replace('~>[\s]+<((?:t[rdh]|li|\/tr|/table|/ul ))~ims', '><$1', $matches[0]); - }, $content ); - - return $content; - } - - /** - * Parses passed directory for widget files - * includes and registers widget if they exist - * - * @param string $path - * @param boolean $cache - * - * @return null - * @author peshkov@UD - */ - static public function maybe_load_widgets( $path, $cache = true ) { - if ( !is_dir( $path ) ) { - return null; - } - - $_widgets = wp_cache_get( 'widgets', 'usabilitydynamics' ); - if( !is_array( $_widgets ) ) { - $_widgets = array(); - } - - if( $cache && !empty( $_widgets[ $path ] ) && is_array( $_widgets[ $path ] ) ) { - foreach( $_widgets[ $path ] as $_widget ) { - include_once( $path . "/" . $_widget[ 'file' ] ); - register_widget( $_widget[ 'headers' ][ 'class' ] ); - } - return null; - } - - $_widgets[ $path ] = array(); - - if ( $dir = @opendir( $path ) ) { - $headers = array( - 'name' => 'Name', - 'id' => 'ID', - 'type' => 'Type', - 'group' => 'Group', - 'class' => 'Class', - 'version' => 'Version', - 'description' => 'Description', - ); - while ( false !== ( $file = readdir( $dir ) ) ) { - $data = @get_file_data( $path . "/" . $file, $headers, 'widget' ); - if( $data[ 'type' ] == 'widget' && !empty( $data[ 'class' ] ) ) { - include_once( $path . "/" . $file ); - if( class_exists( $data[ 'class' ] ) ) { - //var_dump( $data[ 'class' ] ); - array_push( $_widgets[ $path ], array( - 'file' => $file, - 'headers' => $data, - ) ); - register_widget( $data[ 'class' ] ); - } - } - } - } - - wp_cache_set( 'widgets', $_widgets, 'usabilitydynamics' ); - - } - - /** - * Includes all PHP files from specific folder - * - * @param string $dir Directory's path - * @author peshkov@UD - * @version 0.2 - */ - static public function load_files ( $dir = '' ) { - if ( !empty( $dir ) && is_dir( $dir ) ) { - if ( $dh = opendir( $dir ) ) { - while (($file = readdir($dh)) !== false) { - $path = trailingslashit( $dir ) . $file; - if( !in_array( $file, array( '.', '..' ) ) && is_file( $path ) && 'php' == pathinfo( $path, PATHINFO_EXTENSION ) ) { - include_once( $path ); - } - } - closedir( $dh ); - } - } - } - - /** - * Localization Functionality. - * - * Replaces array's l10n data. - * Helpful for localization of data which is stored in JSON files ( see /schemas ) - * - * Usage: - * - * add_filter( 'ud::schema::localization', function($locals){ - * return array_merge( array( 'value_for_translating' => __( 'Blah Blah' ) ), $locals ); - * }); - * - * $result = self::l10n_localize (array( - * 'key' => 'l10n.value_for_translating' - * ) ); - * - * - * @param array $data - * @param array $l10n translated values - * @return array - * @author peshkov@UD - */ - static public function l10n_localize( $data, $l10n = array() ) { - - if ( !is_array( $data ) && !is_object( $data ) ) { - return $data; - } - - //** The Localization's list. */ - $l10n = apply_filters( 'ud::schema::localization', $l10n ); - - //** Replace l10n entries */ - foreach( $data as $k => $v ) { - if ( is_array( $v ) ) { - $data[ $k ] = self::l10n_localize( $v, $l10n ); - } elseif ( is_string( $v ) ) { - if ( strpos( $v, 'l10n' ) !== false ) { - preg_match_all( '/l10n\.([^\s]*)/', $v, $matches ); - if ( !empty( $matches[ 1 ] ) ) { - foreach ( $matches[ 1 ] as $i => $m ) { - if ( array_key_exists( $m, $l10n ) ) { - $data[ $k ] = str_replace( $matches[ 0 ][ $i ], $l10n[ $m ], $data[ $k ] ); - } - } - } - } - } - } - - return $data; - } - - /** - * Wrapper for json_encode function. - * Emulates JSON_UNESCAPED_UNICODE. - * - * @param type $arr - * @return JSON - * @author peshkov@UD - */ - static public function json_encode( $arr ) { - // convmap since 0x80 char codes so it takes all multibyte codes (above ASCII 127). So such characters are being "hidden" from normal json_encoding - array_walk_recursive( $arr, function(&$item, $key){ - if (is_string($item)) - $item = mb_encode_numericentity($item, array (0x80, 0xffff, 0, 0xffff), "UTF-8"); - }); - return mb_decode_numericentity( json_encode( $arr ), array( 0x80, 0xffff, 0, 0xffff ), 'UTF-8' ); - } - - /** - * Merges any number of arrays / parameters recursively, - * - * Replacing entries with string keys with values from latter arrays. - * If the entry or the next value to be assigned is an array, then it - * automagically treats both arguments as an array. - * Numeric entries are appended, not replaced, but only if they are - * unique - * - * @source http://us3.php.net/array_merge_recursive - * @version 0.4 - */ - static public function array_merge_recursive_distinct() { - $arrays = func_get_args(); - $base = array_shift( $arrays ); - if ( !is_array( $base ) ) $base = empty( $base ) ? array() : array( $base ); - foreach ( (array)$arrays as $append ) { - if ( !is_array( $append ) ) $append = empty( $append ) ? array() : array( $append ); - foreach ( (array)$append as $key => $value ) { - if ( !array_key_exists( $key, $base ) and !is_numeric( $key ) ) { - $base[ $key ] = $append[ $key ]; - continue; - } - if ( @is_array( $value ) && isset( $base[ $key ] ) && isset( $append[ $key ] ) && is_array( $base[ $key ] ) && is_array( $append[ $key ] ) ) { - $base[ $key ] = self::array_merge_recursive_distinct( $base[ $key ], $append[ $key ] ); - } else if ( is_numeric( $key ) ) { - if ( !in_array( $value, $base ) ) $base[ ] = $value; - } else { - $base[ $key ] = $value; - } - } - } - return $base; - } - - } - - } - -} diff --git a/vendor/udx/lib-utility/package.json b/vendor/udx/lib-utility/package.json deleted file mode 100644 index 56023a358..000000000 --- a/vendor/udx/lib-utility/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "lib-utility", - "version": "0.4.0", - "description": "Utility Library.", - "private": true, - "repository": { - "type": "git", - "url": "https://github.com/udx/lib-utility" - }, - "main": "scripts/udx.utility.js", - "engines": { - "node": ">= 0.10.0" - }, - "devDependencies": { - "grunt-contrib-symlink": "~0.2.0", - "grunt-contrib-yuidoc": "~0.5.0", - "grunt-contrib-uglify": "~0.2.4", - "grunt-contrib-watch": "~0.5.3", - "grunt-markdown": "~0.4.0", - "grunt-requirejs": "~0.4.0", - "grunt-contrib-concat": "~0.3.0", - "grunt-contrib-clean": "~0.5.0", - "grunt-shell": "~0.6.0", - "grunt-contrib-less": "~0.8.3", - "grunt-mocha-cli": "~1.5.0", - "grunt-mocha-cov": "~0.1.1", - "grunt-phpunit": "~0.3.3", - "findup-sync": "~0.1.3" - } -} diff --git a/vendor/udx/lib-utility/readme.md b/vendor/udx/lib-utility/readme.md deleted file mode 100644 index 6243a56fb..000000000 --- a/vendor/udx/lib-utility/readme.md +++ /dev/null @@ -1,59 +0,0 @@ -## Classes - - - Utility: General utility methods. - - Job: Job and processing handling. - - Loader: PSR class loader. - -## Utility Methods - - - extend() - - defaults() - - pluralize() - - singularize() - - ordinalize() - - hashify_file_name() - - can_get_image() - - ... - -## Changelog - -0.2.4 - - Added Utility::hashify_file_name() method; - - Added seperator options to Utility:;create_slug() to support things such as "::" - -## Usage - -```PHP -// Extend an Array or Object with another for easily setting of defaults. This is similar to extend() but in reverse. -$settings = UsabilityDynamics\Utility::defaults( $configurationObject, $defaultsObject ); - -// Find composer.json file and return as Object. -$composer = UsabilityDynamics\Utility::findUp( 'composer.json', __DIR__ ); -echo "Versio is {$composer->version}." -``` - - -## License - -(The MIT License) - -Copyright (c) 2013 Usability Dynamics, Inc. <info@usabilitydynamics.com> - -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/vendor/udx/lib-utility/scripts/analysis.client.js b/vendor/udx/lib-utility/scripts/analysis.client.js deleted file mode 100644 index 14961ed7a..000000000 --- a/vendor/udx/lib-utility/scripts/analysis.client.js +++ /dev/null @@ -1 +0,0 @@ -define("analysis.client",["jquery.elasticsearch","analysis.visualizer"],function(){function a(){return h||b()}function b(a,b,c){return i={host:a,index:b,type:c},h=new jQuery.es.Client({hosts:a})}function c(b,c){console.debug("getMapping",typeof c);var d={index:i.index||"deafult",type:i.type||"profile"};return a().indices.getMapping(d).then(function(a){"function"==typeof c&&c.call(null,a["jezf-truq-qgox-hfxp"].mappings.profile||{},d)})}function d(b){console.debug("getResults",typeof handleResponse);var c={index:i.index||"deafult",type:i.type||"profile",from:0,size:0,body:b};return a().suggest(c).then(function(a){console.debug("getSuggestion","parseResponse",typeof a),"function"==typeof handleResponse&&handleResponse.call(null,null,a,"suggest",c)})}function e(b,c){console.debug("getMeta",typeof c);var d={index:i.index||"deafult",type:i.type||"profile"};return a().indices.getMapping(d).then(function(a){"function"==typeof c&&c.call(null,a["jezf-truq-qgox-hfxp"].mappings[i.type]._meta||{},"meta",d)})}function f(b,c,d){console.debug("getFacets",typeof d);var e={index:i.index||"deafult",type:i.type||"profile",from:0,size:0,body:{query:{filtered:{query:b}},facets:c}};return a().search(e).then(function(a){"function"==typeof d&&d.call(null,null,a.facets,"facets",e)}).then(function(a){console.debug("handleError",arguments),"function"==typeof d&&d.call(a,null,{},"facets",e)})}function g(b,c){console.debug("getResults",typeof c);var d={index:i.index||"deafult",type:i.type||"profile",from:0,size:0,body:b};return a().search(d).then(function(a){console.debug("getResults","parseResponse",typeof a),"function"==typeof c&&c.call(null,null,a,"search",d)})}console.debug("analysis.client","loaded");var h,i={};return{client:a,createClient:b,getSuggestion:d,getMeta:e,getMapping:c,getFacets:f,getResults:g}}); \ No newline at end of file diff --git a/vendor/udx/lib-utility/scripts/analysis.visualizer.js b/vendor/udx/lib-utility/scripts/analysis.visualizer.js deleted file mode 100644 index 45945aebf..000000000 --- a/vendor/udx/lib-utility/scripts/analysis.visualizer.js +++ /dev/null @@ -1 +0,0 @@ -define("analysis.visualizer",["http://www.google.com/jsapi/"],function(){function a(){console.debug("analysis.visualizer","googleVisualizationReady")}function b(a){var b={raleigh:"Raleigh",port:"New Port","new":"Wilmington",west:"West River",lake:"Lake",south:"South Raleigh",north:"North Raleigh",est:"Eastern",east:"East Brook",wilfred:"Wilfred",zena:"Durham",en_us:"English",twitter:"Twitter",facebook:"Facebook",male:"Male",female:"Female"};return b[a]||a}function c(a,b){console.debug("Pie");var c=google.visualization.arrayToDataTable(b),d=jQuery('
        ');return jQuery(".query-result").append(d),new google.visualization.PieChart(d.get(0)).draw(c,{title:a}),g[a]={title:a,element:d},f}function d(a,b){console.debug("Map");var c=google.visualization.arrayToDataTable(b.raw),d=jQuery('
        ');return jQuery(".query-result").append(d),new google.visualization.GeoChart(d.get(0)).draw(c,{region:"US",displayMode:"regions",resolution:"provinces",enableRegionInteractivity:!0}),g[a]={title:a,element:d},f}function e(a,c){console.debug("Table",c);var d=new google.visualization.DataTable,e=c.total,h=c.terms||[];d.addColumn("string","Metric"),d.addColumn("number","Percentage"),d.addColumn("number","Count"),h.forEach(function(a){d.addRows([[b(a.term),{v:Math.round(a.count/e*100),f:Math.round(a.count/e*100)+"%"},{v:a.count}]])});var i=jQuery('
        ');return jQuery(".query-result").append(i),new google.visualization.Table(i.get(0)).draw(d,{showRowNumber:!1,pageSize:5}),g[a]={title:a,element:i},f}console.debug("analysis.visualizer"),google.load("visualization","1",{packages:["geochart","corechart","table"],callback:a});var f=this,g={};return{Map:d,Table:e,Pie:c,_cached:g}}); \ No newline at end of file diff --git a/vendor/udx/lib-utility/scripts/jquery.ud.buttons.js b/vendor/udx/lib-utility/scripts/jquery.ud.buttons.js deleted file mode 100644 index 9b14c452d..000000000 --- a/vendor/udx/lib-utility/scripts/jquery.ud.buttons.js +++ /dev/null @@ -1 +0,0 @@ -!function(a){a.fn.smart_dom_button=function(b){var c=a.extend({debug:!1,action_attribute:"action_attribute",response_container:"response_container",ajax_action:"action",label_attributes:{process:"processing_label",revert_label:"revert_label",verify_action:"verify_action"}},b);return log=function(a,b){c.debug&&window.console&&console.debug&&("error"==b?console.error(a):console.log(a))},get_label=function(b){var c=a(b).get(0).tagName,d="";switch(c){case"SPAN":d=a(b).text();break;case"INPUT":d=a(b).val()}return d},set_label=function(b,c){switch(c.type){case"SPAN":a(c.button).text(b);break;case"INPUT":a(c.button).val(b)}return b},do_execute=function(b){var d={button:b,type:a(b).get(0).tagName,original_label:a(b).attr("original_label")?a(b).attr("original_label"):get_label(b)};c.wrapper&&a(d.button).closest(c.wrapper).length?(d.wrapper=a(d.button).closest(c.wrapper),d.use_wrapper=!0):(d.wrapper=d.button,d.use_wrapper=!1),d.the_action=a(d.wrapper).attr(c.action_attribute)?a(d.wrapper).attr(c.action_attribute):!1,c.label_attributes.processing&&a(d.wrapper).attr(c.label_attributes.processing)&&(d.processing_label=a(d.wrapper).attr(c.label_attributes.processing)?a(d.wrapper).attr(c.label_attributes.processing):!1),c.label_attributes.verify_action&&a(d.wrapper).attr(c.label_attributes.verify_action)&&(d.verify_action=a(d.wrapper).attr(c.label_attributes.verify_action)?a(d.wrapper).attr(c.label_attributes.verify_action):!1),c.label_attributes.revert_label&&a(d.wrapper).attr(c.label_attributes.revert_label)&&(d.revert_label=a(d.wrapper).attr(c.label_attributes.revert_label)?a(d.wrapper).attr(c.label_attributes.revert_label):!1,a(d.wrapper).attr("original_label")||(d.original_label=get_label(d.button),a(d.wrapper).attr("original_label",d.original_label))),d.the_action&&(!d.verify_action||confirm(d.verify_action))&&(d.use_wrapper&&(a(c.response_container,d.wrapper).length||a(d.wrapper).append(''),d.response_container=a(".response_container",d.wrapper),a(d.response_container).removeClass(),a(d.response_container).addClass("response_container"),d.processing_label&&a(d.response_container).html(d.processing_label)),"ui"==d.the_action?(d.revert_label&&(get_label(d.button)==d.revert_label?set_label(d.original_label,d):set_label(d.revert_label,d)),a(d.wrapper).attr("toggle")&&a(a(d.wrapper).attr("toggle")).toggle(),a(d.wrapper).attr("show")&&a(a(d.wrapper).attr("show")).show(),a(d.wrapper).attr("hide")&&a(a(d.wrapper).attr("hide")).hide()):a.post(ajaxurl,{_wpnonce:flawless_admin.actions_nonce,action:c.ajax_action,the_action:d.the_action},function(b){b&&b.success&&(a(d.response_container).show(),b.css_class&&a(d.response_container).addClass(b.css_class),b.remove_element&&a(b.remove_element).length&&a(b.remove_element).remove(),a(d.response_container).html(b.message),setTimeout(function(){a(d.response_container).fadeOut("slow",function(){a(d.response_container).remove()})},1e4))},"json"))},a(this).click(function(){log("Button triggered."),do_execute(this)}),this}}(jQuery); \ No newline at end of file diff --git a/vendor/udx/lib-utility/scripts/jquery.ud.date-selector.js b/vendor/udx/lib-utility/scripts/jquery.ud.date-selector.js deleted file mode 100644 index d3c7aa5a1..000000000 --- a/vendor/udx/lib-utility/scripts/jquery.ud.date-selector.js +++ /dev/null @@ -1 +0,0 @@ -!function(a){"use strict";a.prototype.date_selector=function(b){var d={element:this,cache:{}};d.options=a.extend(!0,{flat:!1,starts:1,prev:"◀",next:"▶",lastSel:!1,mode:"single",view:"days",calendars:1,format:"Y-m-d",position:"bottom",eventName:"click",onRender:function(){return{}},onChange:function(){return!0},onShow:function(){return!0},onBeforeShow:function(){return!0},locale:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun"],daysMin:["Su","Mo","Tu","We","Th","Fr","Sa","Su"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],weekMin:"wk"},views:{years:"date_selector_view_years",moths:"date_selector_view_months",days:"date_selector_view_days"},template:{wrapper:'
        ',head:["",'',"","",'','','',"",'',"","","","","","","","","","","
        <%=prev%><%=next%>
        <%=week%><%=day1%><%=day2%><%=day3%><%=day4%><%=day5%><%=day6%><%=day7%>
        "],space:'
        ',days:['',"",'<%=weeks[0].week%>','<%=weeks[0].days[0].text%>','<%=weeks[0].days[1].text%>','<%=weeks[0].days[2].text%>','<%=weeks[0].days[3].text%>','<%=weeks[0].days[4].text%>','<%=weeks[0].days[5].text%>','<%=weeks[0].days[6].text%>',"","",'<%=weeks[1].week%>','<%=weeks[1].days[0].text%>','<%=weeks[1].days[1].text%>','<%=weeks[1].days[2].text%>','<%=weeks[1].days[3].text%>','<%=weeks[1].days[4].text%>','<%=weeks[1].days[5].text%>','<%=weeks[1].days[6].text%>',"","",'<%=weeks[2].week%>','<%=weeks[2].days[0].text%>','<%=weeks[2].days[1].text%>','<%=weeks[2].days[2].text%>','<%=weeks[2].days[3].text%>','<%=weeks[2].days[4].text%>','<%=weeks[2].days[5].text%>','<%=weeks[2].days[6].text%>',"","",'<%=weeks[3].week%>','<%=weeks[3].days[0].text%>','<%=weeks[3].days[1].text%>','<%=weeks[3].days[2].text%>','<%=weeks[3].days[3].text%>','<%=weeks[3].days[4].text%>','<%=weeks[3].days[5].text%>','<%=weeks[3].days[6].text%>',"","",'<%=weeks[4].week%>','<%=weeks[4].days[0].text%>','<%=weeks[4].days[1].text%>','<%=weeks[4].days[2].text%>','<%=weeks[4].days[3].text%>','<%=weeks[4].days[4].text%>','<%=weeks[4].days[5].text%>','<%=weeks[4].days[6].text%>',"","",'<%=weeks[5].week%>','<%=weeks[5].days[0].text%>','<%=weeks[5].days[1].text%>','<%=weeks[5].days[2].text%>','<%=weeks[5].days[3].text%>','<%=weeks[5].days[4].text%>','<%=weeks[5].days[5].text%>','<%=weeks[5].days[6].text%>',"",""],months:['',"",'<%=data[0]%>','<%=data[1]%>','<%=data[2]%>','<%=data[3]%>',"","",'<%=data[4]%>','<%=data[5]%>','<%=data[6]%>','<%=data[7]%>',"","",'<%=data[8]%>','<%=data[9]%>','<%=data[10]%>','<%=data[11]%>',"",""]}},b),d.log="function"==typeof d.log?d.log:function(){},d.initialize="function"==typeof d.initialize?d.initialize:function(){return d.log("s.initialize()","function"),d.extendDate(d.options.locale),d.options.calendars=Math.max(1,parseInt(d.options.calendars,10)||1),d.options.mode=/single|multiple|range/.test(d.options.mode)?d.options.mode:"single",d.element.each(function(b,c){var j,k,l="date_selector_"+parseInt(1e3*Math.random());if(a(d.element).data("date_selector_initialized"))return void d.log("s.initialize() - DOM element already initialized, skipping.","function");if(d.options.date||(d.options.date=new Date),d.options.date.constructor===String&&(d.options.date=g(d.options.date,d.options.format),d.options.date.setHours(0,0,0,0)),"single"!=d.options.mode)if(d.options.date.constructor!=Array)d.options.date=[d.options.date.valueOf()],"range"===d.options.mode&&d.options.date.push(new Date(d.options.date[0]).setHours(23,59,59,0).valueOf());else{for(var n=0;n0&&(o+=d.options.template.space),o+=e(d.options.template.head.join(""),{week:d.options.locale.weekMin,prev:d.options.prev,next:d.options.next,day1:d.options.locale.daysMin[k++%7],day2:d.options.locale.daysMin[k++%7],day3:d.options.locale.daysMin[k++%7],day4:d.options.locale.daysMin[k++%7],day5:d.options.locale.daysMin[k++%7],day6:d.options.locale.daysMin[k++%7],day7:d.options.locale.daysMin[k++%7]});j.find("tr:first").append(o).find("table").addClass(d.options.views[d.options.view]),f(j.get(0)),d.options.flat?(j.appendTo(this).show().css("position","relative"),h(j.get(0))):(j.appendTo(document.body),a(this).bind(d.options.eventName,m)),a(d.element).data("date_selector_initialized",!0)})};var e=function(a,b){d.log("tmpl()","function");var c=/\W/.test(a)?new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g," ").split("<%").join(" ").replace(/((^|%>)[^\t]*)'/g,"$1\r").replace(/\t=(.*?)%>/g,"',$1,'").split(" ").join("');").split("%>").join("p.push('").split("\r").join("\\'")+"');}return p.join('');"):d.cache[a]=d.cache[a]||e(document.getElementById(a).innerHTML);return b?c(b):c},f=function(b){d.log("fill()","function"),b=a(b);var c,f,g,h,i,j,k,l,m,n=Math.floor(d.options.calendars/2),o=0;b.find("td>table tbody").remove();for(var p=0;pq;q++)f.data.push(g+q);l=e(d.options.template.months.join(""),f),c.setDate(1),f={weeks:[],test:10},h=c.getMonth();var g=(c.getDay()-d.options.starts)%7;for(c.addDays(-(g+(0>g?7:0))),i=-1,o=0;42>o;){j=parseInt(o/7,10),k=o%7,f.weeks[j]||(i=c.getWeekNumber(),f.weeks[j]={week:i,days:[]}),f.weeks[j].days[k]={text:c.getDate(),classname:[]},h!=c.getMonth()&&f.weeks[j].days[k].classname.push("date_selectorNotInMonth"),0===c.getDay()&&f.weeks[j].days[k].classname.push("date_selectorSunday"),6===c.getDay()&&f.weeks[j].days[k].classname.push("date_selectorSaturday");var r=d.options.onRender(c),s=c.valueOf();(r.selected||d.options.date===s||a.inArray(s,d.options.date)>-1||"range"===d.options.mode&&s>=d.options.date[0]&&s<=d.options.date[1])&&f.weeks[j].days[k].classname.push("date_selector_selected"),r.disabled&&f.weeks[j].days[k].classname.push("date_selector_disabled"),r.className&&f.weeks[j].days[k].classname.push(r.className),f.weeks[j].days[k].classname=f.weeks[j].days[k].classname.join(" "),o++,c.addDays(1)}l=e(d.options.template.days.join(""),f)+l,f={data:d.options.locale.monthsShort,className:"date_selector_months"},l=e(d.options.template.months.join(""),f)+l,m.append(l)}},g=function(a,b){if(d.log("parseDate()","function"),a){if(a.constructor===Date)return new Date(a);for(var c,e,f,g,h,i=a.split(/\W+/),j=b.split(/\W+/),k=new Date,l=0;l100?0:29>f?2e3:1900;break;case"H":case"I":case"k":case"l":g=parseInt(i[l],10);break;case"P":case"p":/pm/i.test(i[l])&&12>g?g+=12:/am/i.test(i[l])&&g>=12&&(g-=12);break;case"M":h=parseInt(i[l],10)}return new Date(void 0===f?k.getFullYear():f,void 0===e?k.getMonth():e,void 0===c?k.getDate():c,void 0===g?k.getHours():g,void 0===h?k.getMinutes():h,0)}};d.formatDate="function"==typeof d.formatDate?d.formatDate:function(a,b){g&&g.log("s.formatDate()","function");var c=a.getMonth(),d=a.getDate(),e=a.getFullYear(),f=(a.getWeekNumber(),a.getDay()),g={},h=a.getHours(),i=h>=12,j=i?h-12:h,k=a.getDayOfYear();0===j&&(j=12);for(var l,m=a.getMinutes(),n=a.getSeconds(),o=b.split(""),p=0;pd?"0"+d:d;break;case"e":l=d;break;case"H":l=10>h?"0"+h:h;break;case"I":l=10>j?"0"+j:j;break;case"j":l=100>k?10>k?"00"+k:"0"+k:k;break;case"k":l=h;break;case"l":l=j;break;case"m":l=9>c?"0"+(1+c):1+c;break;case"M":l=10>m?"0"+m:m;break;case"p":case"P":l=i?"PM":"AM";break;case"s":l=Math.floor(a.getTime()/1e3);break;case"S":l=10>n?"0"+n:n;break;case"u":l=f+1;break;case"w":l=f;break;case"y":l=(""+e).substr(2,2);break;case"Y":l=e}o[p]=l}return o.join("")},d.extendDate="function"==typeof d.extendDate?d.extendDate:function(a){Date.prototype.tempDate||(Date.prototype.tempDate=null,Date.prototype.months=a.months,Date.prototype.monthsShort=a.monthsShort,Date.prototype.days=a.days,Date.prototype.daysShort=a.daysShort,Date.prototype.getMonthName=function(a){return this[a?"months":"monthsShort"][this.getMonth()]},Date.prototype.getDayName=function(a){return this[a?"days":"daysShort"][this.getDay()]},Date.prototype.addDays=function(a){this.setDate(this.getDate()+a),this.tempDate=this.getDate()},Date.prototype.addMonths=function(a){null===this.tempDate&&(this.tempDate=this.getDate()),this.setDate(1),this.setMonth(this.getMonth()+a),this.setDate(Math.min(this.tempDate,this.getMaxDays()))},Date.prototype.addYears=function(a){null===this.tempDate&&(this.tempDate=this.getDate()),this.setDate(1),this.setFullYear(this.getFullYear()+a),this.setDate(Math.min(this.tempDate,this.getMaxDays()))},Date.prototype.getMaxDays=function(){var a,b=new Date(Date.parse(this)),c=28;for(a=b.getMonth(),c=28;b.getMonth()===a;)c++,b.setDate(c);return c-1},Date.prototype.getFirstDay=function(){var a=new Date(Date.parse(this));return a.setDate(1),a.getDay()},Date.prototype.getWeekNumber=function(){var a=new Date(this);a.setDate(a.getDate()-(a.getDay()+6)%7+3);var b=a.valueOf();return a.setMonth(0),a.setDate(4),Math.round((b-a.valueOf())/6048e5)+1},Date.prototype.getDayOfYear=function(){var a=new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0),b=new Date(this.getFullYear(),0,0,0,0,0),c=a-b;return Math.floor(c/24*60*60*1e3)})};var h=function(b){d.log("layout()","function");var c=a(b).data("date_selector"),e=a("#"+c.id);if(!d.options.extraHeight){var f=a(b).find("div");d.options.extraHeight=f.get(0).offsetHeight+f.get(1).offsetHeight,d.options.extraWidth=f.get(2).offsetWidth+f.get(3).offsetWidth}var g=e.find("table:first").get(0),h=g.offsetWidth,i=g.offsetHeight;e.css({width:h+d.options.extraWidth+"px",height:i+d.options.extraHeight+"px"}).find("div.date_selector_container").css({width:h+"px",height:i+"px"})},i=function(b){d.log("click()","function"),a(b.target).is("span")&&(b.target=b.target.parentNode);var c=a(b.target);if(c.is("a")){if(b.stopPropagation(),b.preventDefault(),b.target.blur(),c.hasClass("date_selector_disabled"))return!1;var e=d.options,g=c.parent(),h=g.parent().parent().parent(),i=a("table",this).index(h.get(0))-1,k=new Date(e.current),l=!1,m=!1;if(g.is("th")){if(g.hasClass("date_selectorWeek")&&"range"===d.options.mode&&!g.next().hasClass("date_selector_disabled")){var n=parseInt(g.next().text(),10);k.addMonths(i-Math.floor(d.options.calendars/2)),g.next().hasClass("date_selectorNotInMonth")&&k.addMonths(n>15?-1:1),k.setDate(n),d.options.date[0]=k.setHours(0,0,0,0).valueOf(),k.setHours(23,59,59,0),k.addDays(6),d.options.date[1]=k.valueOf(),m=!0,l=!0,d.options.lastSel=!1}else if(g.hasClass("date_selector_month"))switch(k.addMonths(i-Math.floor(d.options.calendars/2)),h.get(0).className){case"date_selector_view_days":h.get(0).className="date_selector_view_months",c.find("span").text(k.getFullYear());break;case"date_selector_view_months":h.get(0).className="date_selector_view_years",c.find("span").text(k.getFullYear()-6+" - "+(k.getFullYear()+5));break;case"date_selector_view_years":h.get(0).className="date_selector_view_days",c.find("span").text(d.formatDate(k,"B, Y"))}else if(g.parent().parent().is("thead")){switch(h.get(0).className){case"date_selector_view_days":d.options.current.addMonths(g.hasClass("date_selectorGoPrev")?-1:1);break;case"date_selector_view_months":d.options.current.addYears(g.hasClass("date_selectorGoPrev")?-1:1);break;case"date_selector_view_years":d.options.current.addYears(g.hasClass("date_selectorGoPrev")?-12:12)}m=!0}}else if(g.is("td")&&!g.hasClass("date_selector_disabled")){switch(h.get(0).className){case"date_selector_view_months":d.options.current.setMonth(h.find("tbody.date_selector_months td").index(g)),d.options.current.setFullYear(parseInt(h.find("thead th.date_selector_month span").text(),10)),d.options.current.addMonths(Math.floor(d.options.calendars/2)-i),h.get(0).className="date_selector_view_days";break;case"date_selector_view_years":d.options.current.setFullYear(parseInt(c.text(),10)),h.get(0).className="date_selector_view_months";break;default:var n=parseInt(c.text(),10);switch(k.addMonths(i-Math.floor(d.options.calendars/2)),g.hasClass("date_selectorNotInMonth")&&k.addMonths(n>15?-1:1),k.setDate(n),d.options.mode){case"multiple":n=k.setHours(0,0,0,0).valueOf(),a.inArray(n,d.options.date)>-1?a.each(d.options.date,function(a,b){return b===n?(d.options.date.splice(a,1),!1):void 0}):d.options.date.push(n);break;case"range":d.options.lastSel||(d.options.date[0]=k.setHours(0,0,0,0).valueOf()),n=k.setHours(23,59,59,0).valueOf(),nj.t+j.h&&(l=i.top-g.offsetHeight),lj.l+j.w&&(m=i.left-g.offsetWidth),m0?j(a("#"+a(this).data("date_selector_id")).data("date_selector"))[formated?0:1]:void 0},this.Clear=d.clear="function"==typeof d.clear?d.clear:function(){return d.log("clear()","function"),this.each(function(){if(a(this).data("date_selector_id")){{a("#"+a(this).data("date_selector_id"))}d.options=d.element.data("date_selector"),"single"!=d.options.mode&&(d.options.date=[],f(d.element.get(0)))}})},this.fixLayout=d.fixLayout="function"==typeof d.fixLayout?d.fixLayout:function(){return d.log("fixLayout()","function"),this.each(function(){if(a(this).data("date_selector_id")){{a("#"+a(this).data("date_selector_id"))}d.options=d.element.data("date_selector"),d.options.flat&&h(d.element.get(0))}})},d.initialize(),this}}(jQuery); \ No newline at end of file diff --git a/vendor/udx/lib-utility/scripts/jquery.ud.dynamic-filter.js b/vendor/udx/lib-utility/scripts/jquery.ud.dynamic-filter.js deleted file mode 100644 index 12ea808e2..000000000 --- a/vendor/udx/lib-utility/scripts/jquery.ud.dynamic-filter.js +++ /dev/null @@ -1,2 +0,0 @@ -!function(a){"use strict";a.prototype.dynamic_filter=function(b){this.s=b=a.extend(!0,{ajax:{args:{},async:!0,cache:!0,format:"json"},active_timers:{status:{}},attributes:{},attribute_defaults:{label:"",concatenation_character:", ",display:!0,default_filter_label:"",related_attributes:[],sortable:!1,filter:!1,filter_always_show:!1,filter_collapsable:4,filter_multi_select:!1,filter_show_count:!1,filter_show_label:!0,filter_note:"",filter_placeholder:"",filter_show_disabled_values:!1,filter_range:{},filter_ux:[],filter_value_order:"native",filter_values:[]},callbacks:{result_format:function(a){return a}},data:{filterable_attributes:{},current_filters:{},sortable_attributes:{},dom_results:{},rendered_query:[]},filter_types:{checkbox:{filter_show_count:!0,filter_multi_select:!0},input:{filter_always_show:!0,filter_ux:[{autocomplete:{}}]},dropdown:{default_filter_label:"Show All",filter_show_count:!0,filter_always_show:!0},range:{filter_always_show:!0}},helpers:{},instance:{},settings:{auto_request:!0,chesty_puller:!1,debug:!1,dom_limit:200,filter_id:a(this).attr("dynamic_filter")?a(this).attr("dynamic_filter"):"df_"+location.host+location.pathname,load_ahead_multiple:2,sort_by:"",sort_direction:"",set_url_hashes:!0,per_page:25,request_range:{},use_instances:!0,timers:{notice:{dim:5e3,hide:2500},filter_intent:1600,initial_request:0},messages:{no_results:"No results found.",show_more:"Show More",show_less:"Show Less",loading:"Loading...",server_fail:"Could not retrieve results due to a server error, please notify the website administrator.",total_results:"There are {1} total results.",load_more:"Showing {1} of {2} results. Show {3} more."},unique_tag:!1},classes:{wrappers:{ui_debug:"df_ui_debug",element:"df_top_wrapper",results_wrapper:"df_results_wrapper",sorter:"df_sorter",results:"df_results",filter:"df_filter",load_more:"df_load_more",status_wrapper:"df_status_wrapper"},inputs:{input:"df_input",checkbox:"df_checkbox",start_range:"df_start_range",end_range:"df_end_range",range_slider:"df_range_slider"},labels:{range_slider:"df_range_slider_label",attribute:"df_attribute_label",checkbox:"df_checkbox"},status:{success:"df_alert_success",error:"df_alert_error"},results:{row:"df_result_row",result_data:"df_result_data",list_item:"df_list_item"},element:{ajax_loading:"df_ajax_loading",filter_pending:"df_filter_pending",server_fail:"df_server_fail",have_results:"df_have_results"},filter:{inputs_list_wrapper:"df_filter_inputs_list_wrapper",inputs_list:"df_filter_inputs_list",value_wrapper:"df_filter_value_wrapper",value_label:"df_filter_value_label",value_title:"df_filter_title",value_count:"df_filter_value_count",trigger:"df_filter_trigger",filter_label:"df_filter_label",filter_note:"df_filter_note",show_more:"df_filter_toggle_list df_show_more",show_less:"df_filter_toggle_list df_show_less",selected:"df_filter_selected",extended_option:"df_extended_option",currently_extended:"df_currently_extended"},sorter:{button:"df_sortable_button",button_active:"df_sortable_active"},close:"df_close",separator:"df_separator",selected_page:"df_current",disabled_item:"df_disabled_item"},css:{results:{hidden_row:" display: none; ",visible_row:" display: block; "}},ux:{element:this,results_wrapper:a("
        "),results:a("
          "),result_item:a("
        • "),sorter:a("
          "),sorter_button:a("
          "),filter:a("
          "),filter_label:a("
          "),load_more:a("
          "),status:a("
          ")},status:{},supported:{isotope:"function"==typeof a.prototype.isotope?!0:!1,jquery_ui:"object"==typeof a.ui?!0:!1,jquery_widget:"function"==typeof a.widget?!0:!1,jquery_position:"object"==typeof a.ui.position?!0:!1,autocomplete:"object"==typeof a.ui&&"function"==typeof a.widget&&"object"==typeof a.ui.position&&"function"==typeof a.prototype.autocomplete?!0:!1,date_selector:"function"==typeof a.prototype.date_selector?!0:!1,slider:"function"==typeof a.prototype.slider?!0:!1,window_history:"object"==typeof history&&"function"==typeof history.pushState?!0:!1}},b);var c=(this.get_log=function(d,e){d="undefind"!=typeof d?d:!1,e="undefind"!=typeof e?e:!1,"object"==typeof b.log_history&&a.each(b.log_history,function(a,b){d&&d!=b.type||c(b.notice,b.type,b.console_type,!0)})},this.log=function(a,c,d,e){if(c="undefined"!=typeof c?c:"log",d=d?d:"log",b.log_history.push({notice:a,type:c,console_type:d}),a="string"==typeof a||"number"==typeof a?"DF::"+a:a,!(e||b.settings.debug&&window.console))return a;if(!e&&"object"==typeof b.debug_detail&&!b.debug_detail[c])return a;if(window.console&&console.debug)switch(d){case"error":console.error(a);break;case"info":console.info(a);break;case"time":"undefined"!=typeof console.time&&console.time(a);break;case"timeEnd":"undefined"!=typeof console.timeEnd&&console.timeEnd(a);break;case"debug":"undefined"!=typeof console.debug?console.debug(a):console.log(a);break;case"dir":"undefined"!=typeof console.dir?console.dir(a):console.log(a);break;case"warn":"undefined"!=typeof console.warn?console.warn(a):console.log(a);break;case"clear":"undefined"!=typeof console.clear&&console.clear();break;case"log":console.log(a)}return a?a:void 0}),d=this.status=function(d,e){e=a.extend(!0,{element:b.ux.status,type:"default",message:d,hide:b.settings.timers.notice.hide},e),c("status( "+d+" ), type: "+e.type,"status","log"),a(b.ux.status).show().addClass(b.classes.status_wrapper),""===d&&(a(b.ux.status).html(""),a(b.ux.status).hide()),a(b.ux.status).data("original_classes")||a(b.ux.status).data("original_classes",a(b.ux.status).attr("class")),a(b.ux.status).attr("class",a(b.ux.status).data("original_classes")),clearTimeout(b.active_timers.status.hide),"string"==typeof b.classes.status[e.type]&&a(b.ux.status).addClass(b.classes.status[e.type]),b.ux.status.html(d),"undefined"!=typeof e.click_trigger?a(b.ux.status).one("click",function(){a(document).trigger(e.click_trigger,{})}):"function"==typeof a.prototype.alert&&(a(b.ux.status).prepend(a('×')),a(b.ux.status).alert()),e.hide&&(b.active_timers.status.hide=setTimeout(function(){a(b.ux.status).fadeTo(3e3,0,function(){a(b.ux.status).hide()})},e.hide)),"error"===e.type&&a(document).trigger("dynamic_filter::error_status",e)},e=this.prepare_system=function(){b.debug_detail=a.extend(!0,{ajax_detail:!1,attribute_detail:!0,detail:!0,dom_detail:!1,event_handlers:!0,filter_ux:!0,filter_detail:!0,helpers:!1,instance_detail:!0,log:!0,procedurals:!0,status:!1,supported:!0,timers:!0,ui_debug:!1},"object"==typeof b.settings.debug?b.settings.debug:{}),b.log_history=[],c("prepare_system","procedurals"),a.each(b.supported,function(a,b){b?c("Support for ("+a+") verified.","supported","info"):!1}),a(b.ux.element).children().length&&(b.ux.placeholder_results=a(b.ux.element).children()),b.settings.chesty_puller&&"function"==typeof a.prototype.animate&&q()},f=this.analyze_attributes=function(){c("analyze_attributes","procedurals"),a(document).trigger("dynamic_filter::analyze_attributes::initialize"),"undefined"==typeof b.ajax.args&&(b.ajax.args={}),a.each(b.attribute_defaults,function(a,c){b.attribute_defaults[a]="true"===c?!0:"false"===c?!1:c}),b.ajax.args.attributes=b.ajax.args.attributes?b.ajax.args.attributes:{},b.ajax.args.filter_query=b.ajax.args.filter_query?b.ajax.args.filter_query:{},f.add_ux_support=function(a,d,e){c("analyze_attributes.add_ux_support("+a+")","procedurals"),b.attributes[a].verified_ux=b.attributes[a].verified_ux?b.attributes[a].verified_ux:{},b.attributes[a].verified_ux[d]=e?e:{}},f.analyze_single=function(d,e){if(c("analyze_attributes.analyze("+d+")","procedurals"),e=e?e:b.attributes[d],a.each(e,function(a,b){e[a]="true"===b?!0:"false"===b?!1:b}),b.attributes[d]=a.extend({},b.attribute_defaults,b.attributes[d].filter?b.filter_types[b.attributes[d].filter]:{},e),b.attributes[d].verified_ux={},b.ajax.args.attributes[d]=b.ajax.args.attributes[d]?b.ajax.args.attributes[d]:{},a.each(b.attributes[d],function(a,c){b.ajax.args.attributes[d][a]="function"!=typeof c?c:"callback"}),b.attributes[d].sortable&&(b.data.sortable_attributes[d]=b.attributes[d]),b.attributes[d].filter&&(b.data.filterable_attributes[d]={filter:b.attributes[d].filter},b.ajax.args.filter_query[d]=b.ajax.args.filter_query[d]?b.ajax.args.filter_query[d]:[],"undefined"!=typeof e.filter_ux)){if("string"==typeof e.filter_ux){var g=new Object;g[e.filter_ux]={},e.filter_ux=[g]}a.each(e.filter_ux?e.filter_ux:[],function(c,e){a.each(e,function(a,c){b.supported[a]&&f.add_ux_support(d,a,c),"boolean"==typeof b.supported[a]&&b.supported[a]===!1&&b.helpers.attempt_ud_ux_fetch(a,d,c)})})}},a.each(b.attributes,function(a,b){f.analyze_single(a,b)}),a(document).trigger("dynamic_filter::analyze_attributes::complete")},g=this.render_ui=function(){c("render_ui","procedurals"),a.each(b.ux,function(d,e){return e&&"object"!=typeof e&&(b.ux[d]=a(e)),a(b.ux[d]).length?(a(b.ux[d]).addClass("df_element"),a(b.ux.element).addClass(b.debug_detail.ui_debug?b.classes.wrappers.ui_debug:""),void a(b.ux[d]).addClass(b.classes.wrappers[d])):void c("render_ui - s.ux."+d+" was passed as a selector. Corresponding DOM element could not be found.","misconfiguration","error")}),a(b.ux.results_wrapper).not(":visible").length&&a(b.ux.element).prepend(b.ux.results_wrapper),a(b.ux.sorter).not(":visible").length&&a(b.ux.element).prepend(b.ux.sorter),a(b.ux.results).not(":visible").length&&a(b.ux.results_wrapper).append(b.ux.results),b.ux.filter&&!a(b.ux.filter,"body").is(":visible")&&(a(b.ux.element).prepend(b.ux.filter),a(b.ux.filter).addClass(b.classes.filter)),b.ux.status&&!a(b.ux.status).is(":visible")&&(a(b.ux.element).before(b.ux.status),a(b.ux.status).hide()),b.ux.load_more&&!a(b.ux.load_more).is(":visible")&&(a(b.ux.results_wrapper).append(b.ux.load_more),a(b.ux.load_more).click(function(){b.status.loading||(a(b.ux.load_more).unbind("s.ux.load_more"),a(document).trigger("dynamic_filter::load_more"))}),a(b.ux.load_more).hide()),b.supported.isotope&&a(b.ux.results).isotope({itemSelector:"."+b.classes.results.row})},h=this.render_sorter_ui=function(){""!==b.settings.sort_by&&"object"==typeof b.attributes[b.settings.sort_by]&&(b.attributes[b.settings.sort_by].sortable=!0),a.each(b.attributes?b.attributes:{},function(a){b.attributes[a].sortable&&(b.data.sortable_attributes[a]=b.attributes[a])}),a.each(b.data.sortable_attributes?b.data.sortable_attributes:{},function(c,d){a('div[attribute_key="'+c+'"]',b.ux.sorter).length||(b.ux.sorter.append(b.ux.sorter[c]=a(b.ux.sorter_button).clone(!1).addClass(b.classes.sorter.button).attr("attribute_key",c).attr("sort_direction","ASC").text(d.label)),a(b.ux.sorter[c]).click(function(){b.settings.sort_by=this.getAttribute("attribute_key"),b.settings.sort_direction=this.getAttribute("sort_direction"),a("div",b.ux.sorter).removeClass(b.classes.sorter.button_active),a(this).addClass(b.classes.sorter.button_active),a(document).trigger("dynamic_filter::execute_filters")}))})},i=this.render_filter_ui=function(d){c("render_filter_ui","procedurals"),a(document).trigger("dynamic_filter::render_filter_ui::initiate"),"object"!=typeof b.data.filters&&(c("render_filter_ui - s.data.filters is not an object. Creating initial DOM References for filters.","dom_detail"),b.data.filters={}),a.each(b.data.filterable_attributes,function(a,b){k(a,b,d)}),a(document).trigger("dynamic_filter::render_filter_ui::complete")},j=this.update_filters=function(d){c("update_filters","procedurals"),a(document).trigger("dynamic_filter::update_filters::initialize"),a.each(b.data.filterable_attributes,function(a,c){"undefined"!=typeof b.attributes[a]&&k(a,c,d)}),a(document).trigger("dynamic_filter::update_filters::complete")},k=this.render_single_filter=function(d,e){c("render_filter_ui( "+d+", "+typeof e+" ) ","procedurals");var f=b.attributes[d],g=b.data.filters[d],h={},i={},j=function(a,c){"enable"!==c&&c?a.prop("checked",!1).closest("li").removeClass(b.classes.filter.selected):a.prop("checked",!0).closest("li").addClass(b.classes.filter.selected)};switch("undefined"==typeof g&&(i.initial_run=!0,g={inputs_list_wrapper:a('
          '),filter_label:a(b.ux.filter_label).clone(!0).attr("class",b.classes.filter.filter_label).text(b.attributes[d].label),inputs_list:a('
            '),show_more:a('
            '+b.settings.messages.show_more+"
            ").hide(),show_less:a('
            '+b.settings.messages.show_less+"
            ").hide(),filter_note:a('
            ').hide(),items:{},triggers:[]},b.attributes[d].filter_show_label||g.filter_label.hide(),b.ux.filter.append(g.inputs_list_wrapper),g.inputs_list_wrapper.append(g.filter_label),g.inputs_list_wrapper.append(g.inputs_list),g.inputs_list_wrapper.append(g.filter_note),g.inputs_list_wrapper.append(g.show_more),g.inputs_list_wrapper.append(g.show_less),""!==f.filter_note&&g.filter_note.show(),""===f.label&&g.filter_label.hide(),b.data.filters[d]=g,g.show_more.click(function(){a("."+b.classes.filter.extended_option,g.inputs_list_wrapper).show(),g.inputs_list_wrapper.toggleClass(b.classes.filter.currently_extended),g.show_more.toggle(),g.show_less.toggle()}),g.show_less.click(function(){a("."+b.classes.filter.extended_option,g.inputs_list_wrapper).hide(),g.inputs_list_wrapper.toggleClass(b.classes.filter.currently_extended),g.show_more.toggle(),g.show_less.toggle()})),c({"Attribute Key":d,"Attribute Settings":f,"Filter Type":f.filter,"Filter Detail":g,"Verified UX":a.map(f.verified_ux?f.verified_ux:{},function(a,b){return b}),"Filter Items":g.items},"filter_detail","dir"),f.filter){case"input":i.initial_run&&(g.items.single={wrapper:a('
          • '),label:a(''),trigger:a('')},a(g.inputs_list).append(g.items.single.wrapper),g.items.single.wrapper.append(g.items.single.label),g.items.single.label.append(g.items.single.trigger),a(g.items.single.trigger).unbind("keyup").keyup(function(){b.ajax.args.filter_query[d]=g.items.single.trigger.val(),a(document).trigger("dynamic_filter::execute_filters")}),""!=b.ajax.args.filter_query[d]&&g.items.single.trigger.val(b.ajax.args.filter_query[d]),g.items.single.execute_filter=function(){b.ajax.args.filter_query[d]=g.items.single.trigger.val(),a(document).trigger("dynamic_filter::execute_filters")}),f.verified_ux.autocomplete&&(c("render_filter_ui() - Adding AutoComplete UX to ("+d+").","filter_ux","info"),a(g.items.single.trigger).unbind("keyup"),a(g.items.single.trigger).autocomplete({appendTo:g.items.single.wrapper,source:a.map(f.filter_values?f.filter_values:[],function(a){return"object"==typeof a?a.value:!1}),select:function(){g.items.single.execute_filter()},change:function(){g.items.single.execute_filter()}}));break;case"dropdown":i.initial_run&&(g.items.single={wrapper:a('
          • '),label:a(''),trigger:a(''),empty_placeholder:a('")},a(g.inputs_list).append(g.items.single.wrapper),g.items.single.wrapper.append(g.items.single.label),g.items.single.label.append(g.items.single.trigger),g.items.single.trigger.append(g.items.single.empty_placeholder),a(g.items.single.trigger).keyup(function(){b.ajax.args.filter_query[d]=g.items.single.trigger.val(),a(document).trigger("dynamic_filter::execute_filters")}),a(g.items.single.trigger).unbind("change").change(function(){g.items.single.trigger.value=a(":selected",this).val(),b.ajax.args.filter_query[d]=-1===a.inArray(g.items.single.trigger.value,b.ajax.args.filter_query[d])?[g.items.single.trigger.value]:[],a(document).trigger("dynamic_filter::execute_filters")})),a("> option",g.items.single.trigger).each(function(){a(this).attr("filter_key")&&(h[a(this).attr("filter_key")]=a(this))}),a.each(f.filter_values?f.filter_values:[],function(b,c){"object"==typeof c&&(delete h[c.filter_key],c.element=a('option[filter_key="'+c.filter_key+'"]',g.items.single.trigger),c.element.length?f.filter_show_count&&c.element.text(c.element.text().replace(/\(\d+\)$/,"("+c.value_count+")")):(c.element=a('"),f.filter_show_count&&c.value_count&&c.element.append(" ("+c.value_count+")")),t(g.items.single.trigger,c.element,b+1))}),""!=b.ajax.args.filter_query[d]&&""===g.items.single.trigger.val()&&g.items.single.trigger.val(b.ajax.args.filter_query[d]);break;case"checkbox":i.initial_run,a(" > ."+b.classes.filter.value_wrapper,g.inputs_list).each(function(){a(this).attr("filter_key")&&(h[a(this).attr("filter_key")]=a(this))}),""!=f.default_filter_label&&(f.filter_values[0]={filter_key:"show_all",value:f.default_filter_label,css_class:b.classes.filter.default_filter}),a.each(f.filter_values?f.filter_values:[],function(c,e){if("object"==typeof e){c=parseInt(c);var i=g.items[e.filter_key]=g.items[e.filter_key]?g.items[e.filter_key]:{};delete h[e.filter_key],e.css_class=e.css_class?e.css_class:b.classes.filter.value_wrapper,i.wrapper=a('li[filter_key="'+e.filter_key+'"]',g.inputs_list),i.wrapper.length||(i.wrapper=a('
          • '),i.label_wrapper=a(''),i.trigger=a(''),i.label=a(''+e.value+" "),i.count=a(''),i.label_wrapper.append(i.trigger),i.label_wrapper.append(i.label),i.label_wrapper.append(i.count),i.wrapper.append(i.label_wrapper)),"show_all"!==e.filter_key&&g.triggers.push(i.trigger),"number"==typeof f.filter_collapsable&&c>f.filter_collapsable?(i.wrapper.addClass(b.classes.filter.extended_option),g.inputs_list_wrapper.hasClass(b.classes.filter.currently_extended)||(i.wrapper.addClass(b.classes.filter.extended_option).hide(),g.show_more.show(),g.show_less.hide())):i.wrapper.removeClass(b.classes.filter.extended_option),i.wrapper.removeClass(b.classes.disabled_item),i.trigger.prop("disabled",!1),("undefined"!=typeof e.value_count||"object"==typeof e.value_count&&""===e.value_count.val())&&i.count.text(" ("+e.value_count+") "),f.filter_show_count||a(i.count).hide(),t(g.inputs_list,i.wrapper,c+1),a(i.trigger).unbind("change").change(function(){return"show_all"!==a(this).val()||a(this).prop("checked")?("show_all"!=a(this).val()&&a(this).prop("checked")&&(j(a(this),"enable"),j(g.items.show_all.trigger,"disable"),-1===a.inArray(i.trigger.val(),b.ajax.args.filter_query[d])?b.ajax.args.filter_query[d].push(i.trigger.val()):b.ajax.args.filter_query[d]=s(i.trigger.val(),b.ajax.args.filter_query[d]),a(document).trigger("dynamic_filter::execute_filters")),void("show_all"===a(this).val()&&a(this).prop("checked")&&(j(a(this),"enable"),a(g.triggers).each(function(){j(a(this),"disable")}),b.ajax.args.filter_query[d]=[],a(document).trigger("dynamic_filter::execute_filters")))):(j(g.items.show_all.trigger,"enable"),!1)}),-1!==a.inArray(e.filter_key,b.ajax.args.filter_query[d])&&j(i.trigger,"enable")}}),a.isEmptyObject(b.ajax.args.filter_query[d])&&"object"==typeof g.items.show_all&&j(g.items.show_all.trigger,"enable");break;case"range":i.initial_run&&(g.items.single={wrapper:a('
          • '),label:a(''),min:a(''),max:a('')},a(g.inputs_list).append(g.items.single.min),a(g.inputs_list).append(g.items.single.max),a(g.items.single.min).unbind("keyup").keyup(function(){b.ajax.args.filter_query[d]={min:g.items.single.min.val(),max:g.items.single.max.val()},a(document).trigger("dynamic_filter::execute_filters")}),a(g.items.single.max).unbind("keyup").keyup(function(){b.ajax.args.filter_query[d]={min:g.items.single.min.val(),max:g.items.single.max.val()},a(document).trigger("dynamic_filter::execute_filters")})),f.verified_ux.date_selector&&(c("render_filter_ui() - Updating DateSelector UX to ("+d+").","filter_ux","info"),"undefined"==typeof g.items.single.range_selector&&(a(g.items.single.min).remove(),a(g.items.single.max).remove(),a(g.inputs_list).append(g.items.single.date_selector_field=a('
            ')),a(g.inputs_list).append(g.items.single.range_selector=a('
            ')),g.items.single.range_selector.date_selector({flat:!0,calendars:2,position:"left",format:"ymd",mode:"range",onChange:function(c){g.items.single.date_selector_field.val("object"==typeof c?c.join(" - "):""),b.ajax.args.filter_query[d]={min:c[0],max:c[1]},a(document).trigger("dynamic_filter::execute_filters")}}),a(document).bind("dynamic_filter::get_data",function(){}),g.items.single.date_selector_field.focus(function(){})),"object"==typeof b.ajax.args.filter_query[d]&&g.items.single.range_selector.setDate([b.ajax.args.filter_query[d].min,b.ajax.args.filter_query[d].max]))}a.each(h,function(c){f.filter_show_disabled_values?"object"==typeof g.items[c]&&g.items[c].count&&(g.items[c].wrapper.addClass(b.classes.disabled_item),g.items[c].trigger.prop("disabled",!0),g.items[c].count.text("")):a(this).remove()}),!f.filter_always_show&&a.isEmptyObject(f.filter_values)?(c("render_filter_ui - No Filter Values for "+d+" - hiding input.","filter_detail","info"),g.inputs_list_wrapper.hide()):g.inputs_list_wrapper.show()},l=this.get_data=function(e,f){a(document).trigger("dynamic_filter::get_data::initialize",[f]),b.status.loading=!0,f=a.extend(!0,{silent_fetch:!1,append_results:!1},f),b.data.get_count="number"==typeof b.data.get_count?b.data.get_count+1:1,b.settings.request_range.start||(b.settings.request_range.start=0),b.settings.request_range.end||(b.settings.request_range.end=b.settings.dom_limit);var g=a.extend(!0,b.ajax.args,b.settings,{filterable_attributes:b.data.filterable_attributes});f.silent_fetch||a(document).trigger("dynamic_filter::doing_ajax",{settings:b,args:f,ajax_request:g}),c(g.filter_query,"ajax_detail","dir"),a.ajax({dataType:b.ajax.format,type:"POST",cache:b.ajax.cache,async:b.ajax.async,url:b.ajax.url,data:g,success:function(e){c("get_data - Have AJAX response.","ajax_detail","debug"),delete b.status.loading;var g=b.callbacks.result_format(e);return g&&"object"==typeof g&&(e=g),c(e,"ajax_detail","dir"),"object"!=typeof e.all_results?(c("get_data() - AJAX response missing all_results array.","log","error"),!1):(a.each(b.attributes,function(a){b.attributes[a].filter_values=[]}),a.each(e.current_filters?e.current_filters:{},function(c,d){b.attributes[c]&&("undefined"!=typeof d.min&&"undefined"!=typeof d.max&&(b.attributes[c].filter_values=d),a.each(d,function(a,d){"undefined"!=typeof d.filter_key&&null!==d.filter_key&&(("undefined"==typeof d.value||""==d.value||null===d.value)&&(d.value=d.filter_key),d.value.length&&(b.attributes[c].filter_values[parseInt(a)+1]=d))}))}),void(a.isEmptyObject(e)?"object"==typeof b.data.rendered_query[0]?d(b.settings.messages.no_results,{type:"error",hide:!1,click_trigger:"dynamic_filter::undo_last_query"}):(d(b.settings.messages.no_results,{type:"error",hide:!1,click_trigger:b.settings.debug?"dynamic_filter::get_data":""}),a(document).trigger("dynamic_filter::get_data::fail",f)):a(document).trigger("dynamic_filter::get_data::complete",a.extend(f,e))))},error:function(){d(b.settings.messages.server_fail,{type:"error",hide:!1,click_trigger:b.settings.debug?"dynamic_filter::get_data":""}),a(document).trigger("dynamic_filter::get_data::fail",f)}})},m=this.append_dom=function(d,e){c("append_dom()","procedurals"),a(document).trigger("dynamic_filter::append_dom::initialize",e),b.data.all_results=b.data.all_results?b.data.all_results:[],e.append_results||(b.data.all_results=[]),b.ux.placeholder_results&&e.initial_request&&b.ux.placeholder_results.length&&(c("Removing Placeholder Results.","dom_detail","info"),a(b.ux.placeholder_results).remove()),m.process_attributes=function(d){d.dom.row.append(d.dom.attribute_wrapper),a.each(d.attribute_data,function(e,f){if(b.attributes[e]){if(b.attributes[e].filter&&d.dom.row.attr(e,f),!b.attributes[e].display)return void c("append_dom.process_attributes - Returned attribute ("+e+") is defined, but not for display - skipping.","attribute_detail","info");a.isArray(f)&&(c("append_dom.process_attributes - Value returned as an array for "+e,"attribute_detail","info"),f=f.join(concatenation_character)),"function"==typeof b.attributes[e].render_callback&&(c("append_dom.process_attributes - Callback function found for "+e+".","attribute_detail","info"),f=b.attributes[e].render_callback(f,{data:d.attribute_data,dfro:d})),d.dom.attribute_wrapper.append(d.dom.attributes[e]=a('
          • '+(null!==f?f:"")+"
          • ")),c({"Log Event":"Appended dfro.dom.attributes["+e+"] attribute.","Attribute Key":e,"Attribute Value":f,"Attribute Value Type":typeof f,"Attribute DOM":d.dom.attributes[e]},"attribute_detail","dir")}})};var f=a.extend({},b.data.dom_results);return a.each(e.all_results,function(d,g){if("number"!=typeof d)return c('append_dom() - Unexpected Data Error! "index" is ('+typeof d+"), not a numeric value as expected.","log","error"),!0;e.append_results&&(d=b.data.total_in_dom+d);var h="df_"+(b.settings.unique_tag?b.settings.unique_tag:"row")+"_"+("string"==typeof b.settings.unique_tag&&"undefined"!=typeof g[b.settings.unique_tag]?g[b.settings.unique_tag]:b.helpers.random_string());if(delete f[h],"object"==typeof b.data.dom_results[h])return c("append_dom() - Result #"+h+" already in DOM - moving to position "+d,"dom_detail","info"),t(b.ux.results,b.data.dom_results[h].dom.row,d),b.data.all_results[d]=b.data.dom_results[h],!0;var i=b.data.dom_results[h]=b.data.all_results[d]=a.extend({},{attribute_data:g,unique_id:"string"==typeof b.settings.unique_tag?g[b.settings.unique_tag]:!1,dom:{row:b.ux.result_item.clone(!1),attribute_wrapper:a('
              '),attributes:{}},dom_id:h,result_count:d});a(document).trigger("dynamic_filter::render_data::row_element",i),i.dom.row.attr("id",h).attr("class",b.classes.results.row).attr("df_result_count",d).attr("style",b.css.results.hidden_row),c({"Log Event":"append_dom() - #"+i.dom_id+" - DOM created.","DOM ID":"#"+i.dom_id,"Result Count":i.result_count,DOM:i.dom,"Attribute Data":i.attribute_data},"attribute_detail","dir"),m.process_attributes(i),t(b.ux.results,i.dom.row,i.result_count)?c("append_dom() - Inserted #"+i.dom_id+" at position "+i.result_count+".","dom_detail","info"):c("append_dom() - Unable to insert #"+i.dom_id+" at position "+i.result_count+".","dom_detail","error")}),e.append_results||a.each(f?f:{},function(a,d){c("append_dom() - Removing #"+a+", no longer in result set.","dom_detail","info"),d.dom.row.remove(),delete b.data.dom_results[a]}),b.data.all_results.length>0?a(b.ux.element).addClass(b.classes.element.have_results):a(b.ux.element).removeClass(b.classes.element.have_results),a(document).trigger("dynamic_filter::append_dom::complete",e),b.data.total_results=e.total_results?e.total_results:b.data.all_results.length,b.data.total_in_dom=parseInt(b.data.all_results.length),b.data.more_available_on_server=b.data.total_results-b.data.total_in_dom,e},n=this.render_data=function(d,e){return c("render_data()","procedurals"),a(document).trigger("dynamic_filter::render_data::initialize",e),b.settings.visible_range||(b.settings.visible_range={start:0,end:b.settings.per_page?b.settings.per_page:25}),b.data.now_visible=parseInt(b.settings.visible_range.end)-parseInt(b.settings.visible_range.start),b.data.more_available_in_dom=parseInt(b.data.total_in_dom)-parseInt(b.data.now_visible),b.data.next_batch=b.data.total_results-b.settings.visible_range.end0)&&(c("load_more - fetching more results.","detail"),b.settings.request_range={start:b.data.total_in_dom,end:b.data.total_in_dom+b.settings.per_page*b.settings.load_ahead_multiple},a(document).trigger("dynamic_filter::get_data",{silent_fetch:!0,append_results:!0}))},q=this.chesty_puller=function(){b.settings.chesty_puller=a.extend(!0,{top_padding:45,offset:a(b.ux.filter).offset()},b.settings.chesty_puller),q.move_chesty=function(){var c=b.settings.chesty_puller;a(b.ux.filter).stop().animate(a(window).scrollTop()>c.offset.top?{marginTop:a(window).scrollTop()-c.offset.top+c.top_padding}:{marginTop:0})},a(window).scroll(move_chesty)},r=function(a,b){if(c("sprintf()","helpers"),"array"!=typeof b);else;var d=a;for(var e in b){var f=parseInt(e)+1;d=d.replace("{"+f+"}",b[e])}return d},s=this.remove_from_array=function(b,d){return c("remove_from_array()","helpers"),a.grep(d,function(a){return a!==b})},t=this.insert_at=function(b,d,e){c("insert_at()","procedurals"),b=a(b);var e=(b.children().size(),parseInt(e));return b.append(0!==e&&b.children().eq(e-1).length?d:d),!0};b.instance.load="function"==typeof b.instance.load?b.instance.load:function(){c("s.instance.load()","procedurals"),b.supported.cookies&&(b.instance.rendered_query=jaaulde.utils.cookies.get(b.settings.filter_id+"_rendered_query"),b.instance.per_page=jaaulde.utils.cookies.get(b.settings.filter_id+"_per_page"),b.instance.sort_by=jaaulde.utils.cookies.get(b.settings.filter_id+"_sort_by"),b.instance.sort_direction=jaaulde.utils.cookies.get(b.settings.filter_id+"_sort_direction")),b.instance.rendered_query=b.instance.rendered_query?b.instance.rendered_query:{},a.each(b.helpers.url_to_object(),function(c,d){-1!==a.inArray(c,["sort_by","sort_direction","per_page"])?b.instance[c]=d[0]:b.instance.rendered_query[c]=d -}),b.ajax.args.filter_query=a.extend(!0,b.ajax.args.filter_query,b.instance.rendered_query),b.settings.sort_by=b.instance.sort_by?b.instance.sort_by:b.settings.sort_by,b.settings.sort_direction=b.instance.sort_direction?b.instance.sort_direction:b.settings.sort_direction,b.settings.per_page=parseInt(b.instance.per_page?b.instance.per_page:b.settings.per_page),b.instance.result_range&&(b.settings.request_range={start:b.instance.result_range.split("-")[0],end:b.instance.result_range.split("-")[1]},c("s.instance.clear() - Setting Result Range: ("+b.settings.request_range.start+" - "+b.settings.request_range.end+").","instance_detail"))},b.instance.set="function"==typeof b.instance.set?b.instance.set:function(){c("s.instance.set()","procedurals"),b.instance.data={cookies:{rendered_query:b.data.rendered_query?b.data.rendered_query[0]:"",sort_direction:b.settings.sort_direction,per_page:b.settings.per_page,sort_by:b.settings.sort_by},hash:{sort_direction:b.settings.sort_direction,per_page:b.settings.per_page,sort_by:b.settings.sort_by},window_history:{rendered_query:b.data.rendered_query?b.data.rendered_query[0]:""}},a.each(b.data.rendered_query&&b.data.rendered_query?b.data.rendered_query[0]:[],function(a,c){b.instance.data.hash[a]=c}),b.supported.cookies&&a.each(b.instance.data.cookies,function(c,d){a.cookies.set(b.settings.filter_id+"_"+c,d)}),window.location.hash=b.settings.set_url_hashes?b.helpers.object_to_url(b.instance.data.hash):"",b.supported.window_history},b.instance.clear="function"==typeof b.instance.clear?b.instance.clear:function(){return b.supported.cookies&&(delete b.instance.cookie_data,jaaulde.utils.cookies.del(b.settings.filter_id+"_rendered_query"),jaaulde.utils.cookies.del(b.settings.filter_id+"_result_range"),jaaulde.utils.cookies.del(b.settings.filter_id+"_sort_by"),jaaulde.utils.cookies.del(b.settings.filter_id+"_sort_direction")),c("s.instance.clear() - All Instance data cleared out. ","instance_detail")},b.helpers.attempt_ud_ux_fetch="function"==typeof b.helpers.attempt_ud_ux_fetch?b.helpers.attempt_ud_ux_fetch:function(d,e,g){switch(b.helpers.attempt_ud_ux_fetch.attempted=b.helpers.attempt_ud_ux_fetch.attempted?b.helpers.attempt_ud_ux_fetch.attempted:{},d){case"date_selector":var h=" http://cdn.usabilitydynamics.com/jquery.ud.date_selector.js"}return b.helpers.attempt_ud_ux_fetch.attempted[d]||!h?!1:(b.helpers.attempt_ud_ux_fetch.fail=function(a,b){c("Library ("+a+") could not be loaded for: ("+b+"), but we did try.","filter_ux","info")},b.helpers.attempt_ud_ux_fetch.success=function(a,b){c("Library ("+a+") loaded automatically from UD. Applying to: ("+b+"). You are welcome.","filter_ux","info"),f.add_ux_support(b,a,g)},b.helpers.attempt_ud_ux_fetch.attempted[d]=!0,void a.getScript("http://cdn.usabilitydynamics.com/jquery.ud.date_selector.js",function(){"function"==typeof a.prototype.date_selector?b.helpers.attempt_ud_ux_fetch.success(e,d):b.helpers.attempt_ud_ux_fetch.fail(e,d)}).fail(function(){b.helpers.attempt_ud_ux_fetch.fail(e,d)}))},b.helpers.object_to_url="function"==typeof b.helpers.object_to_url?b.helpers.object_to_url:function(b){if(c("s.helpers.object_to_url()","helpers"),"object"!=typeof b)return"string"==typeof b?b:"";var d=a.map(b,function(b,c){return"string"==typeof b&&""!==b?b=b:"function"==typeof b.join?b=b.join(","):"object"==typeof b&&(b=a.map(b,function(a){return a}).join("-")),b?c+"="+b:void 0});return d.length?encodeURI(d.join("&")):""},b.helpers.url_to_object="function"==typeof b.helpers.url_to_object?b.helpers.url_to_object:function(b){c("s.helpers.url_to_object()","helpers");var d=b?b:decodeURI(window.location.hash.replace("#","")),e={};return a.each(d.split("&"),function(a,b){b&&(a=b.split("=")[0],b=b.split("=")[1],-1!==b.indexOf("-")?b={min:b.split("-")[0],max:b.split("-")[1]}:"string"==typeof b&&(b=[b]),e[a]=b)}),e},b.helpers.random_string="function"==typeof b.helpers.random_string?b.helpers.random_string:function(a,b){c("random_string()","helpers"),a="string"==typeof a?a:"",b="string"==typeof b?b:"abcdefghijklmnopqrstuvwxyz";for(var d=0;10>d;d++)a+=b.charAt(Math.floor(Math.random()*b.length));return a},b.helpers.purge="function"==typeof b.helpers.purge?b.helpers.purge:function(a){var c,d,e,f=a.attributes;if(f)for(c=f.length-1;c>=0;c-=1)e=f[c].name,"function"==typeof a[e]&&(a[e]=null);if(f=a.childNodes)for(d=f.length,c=0;d>c;c+=1)b.helpers.purge(a.childNodes[c])};var u=this.enable=function(){a(document).bind("dynamic_filter::doing_ajax",function(){c("doing_ajax","event_handlers"),a(b.ux.element).removeClass(b.classes.element.filter_pending),a(b.ux.element).removeClass(b.classes.element.server_fail),a(b.ux.element).addClass(b.classes.element.ajax_loading)}),a(document).bind("dynamic_filter::ajax_complete",function(){c("ajax_complete","event_handlers"),a(b.ux.element).removeClass(b.classes.element.ajax_loading)}),a(document).bind("dynamic_filter::get_data",function(a,b){c("get_data","event_handlers"),l(a,b)}),a(document).bind("dynamic_filter::instance::set",function(){b.settings.use_instances?b.instance.set():!1}),a(document).bind("dynamic_filter::get_data::complete",function(b,d){c("get_data::complete","event_handlers"),a(document).trigger("dynamic_filter::ajax_complete",d),m(b,d),d.silent_fetch||(n(b,d),j(b,d))}),a(document).bind("dynamic_filter::get_data::fail",function(){a(document).trigger("dynamic_filter::ajax_complete"),a(b.ux.element).addClass(b.classes.element.server_fail)}),a(document).bind("dynamic_filter::undo_last_query",function(){c("undo_last_query","event_handlers"),a(b.ux.element).removeClass(b.classes.element.server_fail),a(b.ux.element).removeClass(b.classes.element.ajax_loading),d("")}),a(document).bind("dynamic_filter::render_data",function(){c("render_data","event_handlers"),n()}),a(document).bind("dynamic_filter::render_data::complete",function(){c("render_data::complete","event_handlers")}),a(document).bind("dynamic_filter::execute_filters",function(){c("execute_filters","event_handlers"),o()}),a(document).bind("dynamic_filter::update_filters::complete",function(){c("update_filters::complete","event_handlers")}),a(document).bind("dynamic_filter::load_more",function(){c("load_more","event_handlers"),p()}),a(document).bind("dynamic_filter::onpopstate",function(){c("dynamic_filter::onpopstate","log","info")}),e(),f(),b.settings.use_instances?b.instance.load():!1,g(),i(),h(),b.settings.auto_request&&(b.settings.timers.initial_request&&c("Doing Initial Request with a "+b.settings.timers.initial_request+"ms pause.","log","info"),setTimeout(function(){a(document).trigger("dynamic_filter::get_data",{initial_request:!0})},b.settings.timers.initial_request))};return window.onpopstate=function(b){a(document).trigger("dynamic_filter::onpopstate",b)},u(),this}}(jQuery); \ No newline at end of file diff --git a/vendor/udx/lib-utility/scripts/jquery.ud.elastic_filter.js b/vendor/udx/lib-utility/scripts/jquery.ud.elastic_filter.js deleted file mode 100644 index 8e38959bb..000000000 --- a/vendor/udx/lib-utility/scripts/jquery.ud.elastic_filter.js +++ /dev/null @@ -1 +0,0 @@ -!new function(a){var b=window.ef_app=jQuery.extend(!0,this,{settings:{account_id:void 0,access_key:void 0,per_page:10,debug:!1,visual_debug:!1,url:"https://cloud.usabilitydynamics.com",index:""},documents:[],facets:[],sort_options:[],defaults:null,state:"loading",query:{full_text:null,field:[],terms:[],range:[],fuzzy:[],from:0},size:0,sort:null,bindings_initialized:[],total:null,message:"",elastic_ready:!1,session_id:null,global:window.__elastic_filter={},ready:function(){},_required:{io:"//ud-cdn.com/js/ud.socket/1.0.0/ud.socket.js","ko.mapping":"//ud-cdn.com/js/knockout.mapping/2.3.2/knockout.mapping.js",async:"//ud-cdn.com/js/async/1.0/async.js","ud.ko":"//ud-cdn.com/js/knockout.ud/1.0/knockout.ud.js","ud.select":"//ud-cdn.com/js/ud.select/3.2/ud.select.js","jq-lazyload":"//ud-cdn.com/js/jquery.lazyload/1.8.2/jquery.lazyload.js"},_log:{subscriptions:{},search:[],debug:[],profilers:{}}},a);b._document=function(a){return a},b._facet=function(a,c){var d=[];for(var e in a.terms)d.push({text:a.terms[e].term,id:a.terms[e].term});return a._label=c,a.options=ko.observableArray(d),a.value=ko.observable(),a.select_multiple=ko.observableArray(),a.select_multiple.subscribe(function(a){if(b.view_model.query.terms.remove(ko.utils.arrayFirst(b.view_model.query.terms(),function(a){return"undefined"!=typeof a[c]})),a.length){var d={};d[c]=a,b.view_model.query.terms.push(d)}b.view_model.size(parseInt(b.view_model.settings.per_page())),b.search_request()}),a.css_class=ko.computed(function(){var b="undefined"!=typeof a.options()?a.options().length:0,d=1==b?"eff_single_option":b?"eff_options_"+b:"eff_no_options";return d+" ef_facet_"+c.replace(" ","_")}),a},b.profile=function(a,c,d){if(b._log.profilers[a]&&c){var e=["Profiler",a,c,((new Date).getTime()-b._log.profilers[a])/1e3];return d&&e.push(d),b.log.apply(this,e)}return b._log.profilers[a]=(new Date).getTime(),this},b.log=function(){return"undefined"==typeof console?arguments?arguments:null:arguments[0]instanceof Error?(console.error("ElasticFilter Fatal Error:",arguments[0].message),arguments):(console.log(arguments),arguments?arguments:null)},b.debug=function(){return b._log.debug.push({time:(new Date).getTime(),data:arguments}),ko.utils.unwrapObservable(b.settings.debug)||arguments[0]instanceof Error?b.log.apply(this,arguments):arguments},b.init=function(){return c.back_support(),b.debug("init"),async.auto({binding_handlers:[function(a){return b.debug("init","auto","binding_handlers"),"object"!=typeof ko?a(new Error("Missing Knockout.")):"object"!=typeof io?a(b.debug(new Error("Missing Socket.io."))):(ko.bindingHandlers["elastic-filter"]={init:function(a,c){b.log("binding_handlers","elastic-filter","init"),ko.mapping.fromJS({settings:jQuery.extend(!0,{},b.settings,ko.utils.unwrapObservable(c()))},b.view_model),b.bindings_initialized.push("elastic-filter")}},ko.bindingHandlers["fulltext-search"]={init:function(a,c,d){return b.debug("binding_handlers","fulltext-search","init"),"undefined"==typeof jQuery().select2?new Error("Select2 library is required for Fulltext Search feature"):(jQuery(a).select2(c()),"undefined"!=typeof d().elastic_settings&&ko.mapping.fromJS({settings:d().elastic_settings},b.view_model),ko.utils.domNodeDisposal.addDisposeCallback(a,function(){jQuery(a).select2("destroy")}),void b.bindings_initialized.push("fulltext-search"))}},a(null,[ko.bindingHandlers]))}],observable:["binding_handlers",function(a){return b.debug("init","auto","observable"),b.view_model=ko.mapping.fromJS(b,{ignore:c.get_methods(b).concat("_log","_required","model_functions","facet_functions","document_functions","utils","success","global")}),ko.applyBindings(b.view_model),jQuery.extend(!0,b.view_model,b.facet_functions,b.document_functions),a(null,b)}],socket:["observable",function(a){return b.debug("init","auto","socket"),b.bindings_initialized.length?"undefined"==typeof b.view_model.settings.account_id||"undefined"==typeof b.view_model.settings.access_key?a(new Error("Empty credentials.")):void ud.socket.connect(ko.utils.unwrapObservable(b.view_model.settings.url),{resource:"websocket.api/1.5","account-id":ko.utils.unwrapObservable(b.view_model.settings.account_id),"access-key":ko.utils.unwrapObservable(b.view_model.settings.access_key)},function(c,d){return b.socket=d,c?a(c):(b.socket.once("reconnect",function(){b.debug(new Error("Reconnecting, re-initializing ElasticFilter.").arguments),b.init()}),b.view_model.session_id(b.socket.sessionid),a(null,b.socket))}):void 0}],settings:["socket",function(a){b.debug("init","auto","settings"),b.socket.request("get","api/v1/settings",function(c,d){return b.log("settings",d),c||!d?a(b.log(c||new Error("Request for index settings returned no results."))):(ko.mapping.fromJS({settings:d.settings},b.view_model),b.ready(),a(null,b.settings))})}],ready:["settings",function(a,c){b.debug("init","auto","ready",c),b.view_model.sort(ko.mapping.toJS(b.view_model.settings.defaults.sort)),b.view_model.size(parseInt(b.view_model.settings.per_page())),-1!==b.bindings_initialized.indexOf("elastic-filter")&&b.search_request(),b.view_model.elastic_ready(!0),a(null,b.view_model.elastic_ready())}]},b.initialized),this},b.search_request=function(a){b.profile("search_request");var d={index:b.view_model.settings.index(),query:jQuery.extend(!0,{match_all:{}},ko.mapping.toJS(b.view_model.query)),facets:ko.mapping.toJS(b.view_model.settings.facets),size:b.view_model.size(),sort:b.view_model.sort()};d=c.clean_object(d),b.computed_query=function(){return d},b.log("search_request_data","Data Before Send",d),b.view_model.state("loading"),b.socket.request("post","api/v1/search",d,function(c,d){b.last_response=function(){return d},b.profile("search_request","Have Cloud Response.",d),b.profile("search_request","Request Mapping Start.");var e=[];jQuery.each("undefined"!=typeof d.documents?d.documents:[],function(){e.push(arguments[1])}),b.view_model.documents(ko.utils.arrayMap(e,function(a){return new b._document(a)}));for(var f in"undefined"!=typeof d.meta.facets?d.meta.facets:{}){var g=!1;ko.utils.arrayForEach(b.view_model.facets(),function(a){f==a._label&&(g=!0)}),g||b.view_model.facets.push(new b._facet(d.meta.facets[f],f))}return b.view_model.total("undefined"!=typeof d.meta.total?d.meta.total:0),b.view_model.state("ready"),b.profile("search_request","Request Mapping Complete."),"function"==typeof a?a(c,d):d})},b.custom_search=function(a){b.profile("custom_search_start");var c={index:b.view_model.settings.index(),query:{query_string:{query:b.view_model.query.full_text()}},size:b.view_model.size(),sort:b.view_model.sort()};return b.socket.request("post","api/v1/search",c,a),b.profile("custom_search_end"),!0},b.get_json=function(){return JSON.parse(ko.mapping.toJSON(b.view_model))},b.initialized=function(a,c){return b.debug("initialized",arguments),b.initialization=b.log(a?"Initializaiton Failed.":"Initializaiton Done.",c?c:a),"function"==typeof b.ready&&b.ready(b,a,c),b.initialization},b.facet_functions={facet_after_render:function(){},facet_before_remove:function(a){ko.removeNode(a)},facet_after_add:function(){},facet_template:function(a){var c=[];switch(a&&a._type){case"terms":c.push("template-facet-terms")}return c.push("template-default-facet"),b.model_functions._get_template(c)},submit_facets:function(){b.debug("facet_functions","submit_facets"),b.view_model.size(parseInt(b.view_model.settings.per_page())),b.search_request()}},b.document_functions={document_after_render:function(){},document_before_remove:function(a){ko.removeNode(a)},document_after_add:function(){},document_template:function(){return b.model_functions._get_template(["template-default-document"])},sort_by:function(a,c){b.debug("document_functions","sort"),jQuery(c.target).trigger("sort",[a]);var d=jQuery(c.target).data("field"),e=ko.utils.arrayFirst(a.sort_options,function(a){return"undefined"!=typeof a[d]});if(b.view_model.sort()){var f="undefined"!=typeof b.view_model.sort()[d]?b.view_model.sort()[d]:!1;f&&(e[d].order="desc"==b.view_model.sort()[d].order?"asc":"desc")}b.view_model.sort(e),b.view_model.size(parseInt(b.view_model.settings.per_page())),b.search_request()},is_active_sort:function(a){return b.view_model.sort()&&"undefined"!=typeof b.view_model.sort()[a]?"active":"disabled"},have_more:function(){return b.debug("document_functions","have_more()"),b.have_more=ko.computed({owner:this,read:function(){return b.view_model.total()>b.view_model.documents().length?!0:!1}}),b.have_more()},load_more:function(){b.debug("document_functions","load_more()"),b.view_model.size(parseInt(b.view_model.size())+parseInt(b.view_model.settings.per_page())),b.search_request()}},b.model_functions={_get_template:function(a){for(i in a?a:[])if(document.getElementById(a[i]))return a[i];return a[0]},_remove_item:function(a,b){var c=this[a];ko.utils.arrayFirst(c,function(a){a&&parseInt(a.id)===parseInt(b)&&(c.remove(document),ko.utils.arrayRemoveItem(a))})}};var c=b.utilis={back_support:function(){Object.keys=Object.keys||function(){var a=Object.prototype.hasOwnProperty,b=!{toString:null}.propertyIsEnumerable("toString"),c=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],d=c.length;return function(e){if("object"!=typeof e&&"function"!=typeof e||null===e)throw new TypeError("Object.keys called on a non-object");var f=[];for(var g in e)a.call(e,g)&&f.push(g);if(b)for(var h=0;d>h;h++)a.call(e,c[h])&&f.push(c[h]);return f}}()},get_methods:function(a){var b=jQuery.map(a,function(a,b){return"function"==typeof a?b:void 0});return b},json_editor:function(){ud.load.js({JSONEditor:"http://ud-cdn.com/js/ud.json.editor.js"},function(){ud.load.css("http://ud-cdn.com/js/assets/ud.json.editor.css"),b.json_editor=new JSONEditor(jQuery(".elastic_json_editor").get(0),{indentation:2,search:!1,history:!1})})},contains:function(a,b){for(var c=0;c0&&i.lengthd.selection_limit&&a(c).removeAttr("checked"),b.helpers.update_inline_help(e.control_group,e);break;case"password":case"matching_passwords":var l;if(a.each(e.related_fields,function(b,c){l=a(c).val()}),""===g&&""===l){h.detail_log.push("Passwords are empty: "+g+" - "+l),e.status_code="error";break}if(g===l){h.detail_log.push("Passwords match: "+g+" - "+l),e.status_code="success",e.password_strength=Math.round(l.length/13*100),e.messages.success=a('
              Password Strength:
              '),b.helpers.update_inline_help(e.control_group,e);break}if(g!=l){h.detail_log.push("Passwords do not match: "+g+" - "+l),e.status_code="error";break}break;case"email":e.status_code=""==g?"blank":b.helpers.validate_email(g)?"success":"error";break;case"url":e.status_code=""==g?"blank":b.helpers.validate_url(g)?"success":"error";break;case"domain":e.status_code=""==g?"blank":b.helpers.validate_url(g,{use_http:!1})?"success":"error";break;case"address":if(""==g){e.status_code="blank";break}if("object"!=typeof google||"object"!=typeof google.maps)break;e.remote_request=!0,e.geocoder=e.geocoder?e.geocoder:new google.maps.Geocoder,e.clean_value=g.replace(/(\r\n|\n|\r)/gm," "),e.geocoder.geocode({address:e.clean_value},function(c){"object"==typeof c&&(a.each(c,function(a,b){"ROOFTOP"==b.geometry.location_type?(e.messages.success="Validated: "+b.formatted_address,e.status_code="success"):e.status_code="ZERO_RESULTS"==b.status?"error":"warning"}),b.helpers.update_inline_help(e.control_group,e),j(g,h,e))});break;case"ajax":if(!e.validation_ajax)break;e.remote_request=!0;var m=a.extend({},{action:e.validation_ajax,field_name:e.name,field_value:g,field_type:e.type},b.settings.ajax_url);a.ajax({url:b.settings.ajax_url,data:m,success:function(a){e.status_code="false"==a.success?"error":"success",e.messages[e.status_code]=a.message,k(e.control_group,e),h.detail_log.push(e.name+" - Custom Ajax Validation. Result: "+e.status_code),j(g,h,e)},dataType:"json"});break;case"pattern":var n=new RegExp(e.attributes.pattern,"g");""==g?e.status_code="blank":n.test(g)?e.status_code="success":(e.status_code="error",e.messages[e.status_code]="Please, match the requested format"+("undefined"!=typeof e.title?":"+e.title:""));break;case"not_empty":default:e.status_code=""==g?"blank":"success",e.status_code=""==g?"blank":"success"}e.remote_request||j(g,h,e)},j=this.finalize_field_validation=function(c,d,e){"blank"==e.status_code&&b.settings.error_on_blank&&(e.status_code="error"),d.detail_log.push("new status_code: "+e.status_code),a(e.input_element).attr("validation_status_code",e.status_code),a(e.control_group).attr("validation_status_code",e.status_code),e.form.form_helper_fields[e.name].status_code=e.status_code,e.validation_required&&("success"!=e.status_code&&d.detail_log.push("Field validation fail."),l(e.form).validation_fail?(a(e.form).addClass("validation_fail"),a(e.form).data("do_not_process",!0),d.detail_log.push("Form validation fail.")):(a(e.form).removeClass("validation_fail"),a(e.form).removeData("do_not_process"),d.detail_log.push("Form passed validation."))),f(d.detail_log,"dir"),(!e.initial_run||b.settings.validate_on_enable)&&k(e.control_group,e)},k=this.update_control_group_ui=function(c,d){f("update_control_group_ui()"),d.do_not_markup||(a.each(b.classes.status,function(b,d){a(c).removeClass(d)}),d.helpers&&(a("> ."+b.classes.helper_item,d.helpers).removeClass(b.classes.active_helper).addClass(b.classes.disabled_helper),a("."+d.status_code,d.helpers).removeClass(b.classes.disabled_helper).addClass(b.classes.active_helper)),a(c).addClass(b.classes.status[d.status_code]))},l=this.form_status=function(b){if(f("form_status()"),"object"!=typeof b.form_helper_fields)return f("form_status() - form.form_helper_fields is not an object, leaving."),{};var c={validation_fail:!1,failed_fields:[]};return a.each(b.form_helper_fields,function(a,b){"success"!=b.status_code&&(f("form_status() - Input Field failed validation: "+a),c.failed_fields.push(a))}),c.failed_fields.length?(f("form_status() - Form failed validation. Invalid fields: "+c.failed_fields.length),b.validation_fail=c.validation_fail=!0,b.failed_fields=c.failed_fields):f("form_status() - Form is valid. "),c};return"function"!=typeof b.helpers.update_inline_help&&(b.helpers.update_inline_help=function(c,d){f("helpers.update_inline_help()"),d.helpers||(d.helpers=a(b.class_selector.help_block,c)),d.helpers.length||a(d.type+":last",c).after(d.helpers=a('')),a.each(d.messages,function(c,e){var f=b.classes.status[c],g=a("span."+f,d.helpers);g.length||a(d.helpers).append(g=a("")),g.addClass(b.classes.helper_item),g.addClass(f),b.settings.auto_hide_helpers&&g.addClass(b.classes.disabled_helper),a(g).html(e)})}),"function"!=typeof b.helpers.css_class_query&&(b.helpers.css_class_query=function(b){var c=[];if("object"==typeof b||"array"==typeof b){var d=!1;if(a.each(b,function(b,e){return c.push(e),a.isNumeric(b)?void 0:void(d=!0)}),d)return b}else"string"==typeof b&&(c=b.split(" "));return("."+c.join(".")).replace(/\.\./g,".")}),"function"!=typeof b.helpers.remove_from_array&&(b.helpers.remove_from_array=function(b,c){return a.grep(c,function(a){return a!==b})}),"function"!=typeof b.helpers.validate_url&&(b.helpers.validate_url=function(b,c){return f("helpers.validate_url("+b+")"),c=a.extend({use_http:!0},c),c.use_http?/^(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/i.test(b):/^[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/i.test(b)}),"function"!=typeof b.helpers.validate_email&&(b.helpers.validate_email=function(a){f("helpers.validate_email("+a+")");var b=/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;return b.test(a)}),b.settings.auto_enable&&g(),this}}(jQuery); \ No newline at end of file diff --git a/vendor/udx/lib-utility/scripts/jquery.ud.smart-buttons.js b/vendor/udx/lib-utility/scripts/jquery.ud.smart-buttons.js deleted file mode 100644 index 10ad4d181..000000000 --- a/vendor/udx/lib-utility/scripts/jquery.ud.smart-buttons.js +++ /dev/null @@ -1 +0,0 @@ -!function(a){a.fn.smart_dom_button=function(b){var c=a.extend({debug:!1,action_attribute:"action_attribute",response_container:"response_container",ajax_action:"action",label_attributes:{process:"processing_label",revert_label:"revert_label",verify_action:"verify_action"}},b);return log=function(a,b){c.debug&&window.console&&console.debug&&("error"==b?console.error(a):console.log(a))},get_label=function(b){var c=a(b).get(0).tagName,d="";switch(c){case"SPAN":d=a(b).text();break;case"INPUT":d=a(b).val()}return d},set_label=function(b,c){switch(c.type){case"SPAN":a(c.button).text(b);break;case"INPUT":a(c.button).val(b)}return b},do_execute=function(b){var d={button:b,type:a(b).get(0).tagName,original_label:a(b).attr("original_label")?a(b).attr("original_label"):get_label(b)};c.wrapper&&a(d.button).closest(c.wrapper).length?(d.wrapper=a(d.button).closest(c.wrapper),d.use_wrapper=!0):(d.wrapper=d.button,d.use_wrapper=!1),d.the_action=a(d.wrapper).attr(c.action_attribute)?a(d.wrapper).attr(c.action_attribute):!1,c.label_attributes.processing&&a(d.wrapper).attr(c.label_attributes.processing)&&(d.processing_label=a(d.wrapper).attr(c.label_attributes.processing)?a(d.wrapper).attr(c.label_attributes.processing):!1),c.label_attributes.verify_action&&a(d.wrapper).attr(c.label_attributes.verify_action)&&(d.verify_action=a(d.wrapper).attr(c.label_attributes.verify_action)?a(d.wrapper).attr(c.label_attributes.verify_action):!1),c.label_attributes.revert_label&&a(d.wrapper).attr(c.label_attributes.revert_label)&&(d.revert_label=a(d.wrapper).attr(c.label_attributes.revert_label)?a(d.wrapper).attr(c.label_attributes.revert_label):!1,a(d.wrapper).attr("original_label")||(d.original_label=get_label(d.button),a(d.wrapper).attr("original_label",d.original_label))),d.the_action&&(!d.verify_action||confirm(d.verify_action))&&(d.use_wrapper&&(a(c.response_container,d.wrapper).length||a(d.wrapper).append(''),d.response_container=a(".response_container",d.wrapper),a(d.response_container).removeClass(),a(d.response_container).addClass("response_container"),d.processing_label&&a(d.response_container).html(d.processing_label)),"ui"==d.the_action?(d.revert_label&&(get_label(d.button)==d.revert_label?set_label(d.original_label,d):set_label(d.revert_label,d)),a(d.wrapper).attr("toggle")&&a(a(d.wrapper).attr("toggle")).toggle(),a(d.wrapper).attr("show")&&a(a(d.wrapper).attr("show")).show(),a(d.wrapper).attr("hide")&&a(a(d.wrapper).attr("hide")).hide()):a.post(ajaxurl,{action:c.ajax_action,the_action:d.the_action},function(b){if(b&&b.success){a(d.response_container).show(),b.css_class&&a(d.response_container).addClass(b.css_class),b.remove_element&&a(b.remove_element).length&&a(b.remove_element).remove(),a(d.response_container).html(b.message);var c;a(d.response_container).mouseover(function(){c=setTimeout(function(){a(d.response_container).fadeOut("slow",function(){a(d.response_container).remove()})},1e4)}).mouseout(function(){clearTimeout(c)})}},"json"))},a(this).click(function(){log("Button triggered."),do_execute(this)}),this}}(jQuery); \ No newline at end of file diff --git a/vendor/udx/lib-utility/scripts/jquery.ud.social.js b/vendor/udx/lib-utility/scripts/jquery.ud.social.js deleted file mode 100644 index ac85c3d17..000000000 --- a/vendor/udx/lib-utility/scripts/jquery.ud.social.js +++ /dev/null @@ -1 +0,0 @@ -!function(a){"use strict";a.fn.social=function(b){b=a.extend({element:this,networks:{linkedin:{profile_fields:{id:"network_id",firstName:"first_name",lastName:"last_name",pictureUrl:"user_image",headline:"headline",industry:"industry",summary:"summary",specialties:"specialties",location:"location",associations:"associations",certifications:"certifications",educations:"educations",skills:"skills",patents:"patents",honors:"honors",proposalComments:"proposal_comments","three-current-positions":"current_positions","recommendations-received":"recommendations","main-address":"primary_address","member-url-resources":"url_resources","phone-numbers":"phone_number","public-profile-url":"profile_url","im-accounts":"im_accounts"}}},user_data:{},debug:!0},b);{var c=this.log=function(a,c){b.debug&&window.console&&console.debug&&("error"===c?console.error(a):console.log(a))},d=this.handle_linkedin=function(){c("handle_linkedin()"),b.networks.linkedin.active=!0,"undefined"!=typeof IN.Event&&(a(".linkedin_asset").show(),IN.Event.on(IN,"auth",function(){c("IN.Event::auth ");var d=[];a.each(b.networks.linkedin.profile_fields,function(a){d.push(a)}),IN.API.Profile("me").fields(d).result(function(d){c("IN.API.Profile()"),a.each(d.values[0],function(a,c){var d=b.networks.linkedin.profile_fields[a];if("undefined"!=typeof d&&""!=c){switch(a){case"location":c=c.name}b.user_data[d]=c}}),b.user_data.display_name=b.user_data.first_name+" "+b.user_data.last_name,b.user_data&&a(".linked_in_login").html('

              '+("string"==typeof b.user_data.user_image?'':"")+'Hello, '+b.user_data.first_name+"! "+("string"==typeof b.user_data.headline?''+b.user_data.headline+"":"")+("string"==typeof b.user_data.industry?''+b.user_data.industry+"":"")+"

              "),a(document).trigger("social::user_data_update",b.user_data)}),a(document).bind("social::user_logout",function(){"object"==typeof IN&&"undefined"!=typeof IN.User&&IN.User.logout()})}))};this.user_logout=function(){a(document).trigger("social::user_logout")},this.enable=function(){c("social::enable()"),"object"==typeof IN&&d()}}return this.enable(),this}}(jQuery); \ No newline at end of file diff --git a/vendor/udx/lib-utility/scripts/jquery.ud.super-search.js b/vendor/udx/lib-utility/scripts/jquery.ud.super-search.js deleted file mode 100644 index ebc17ace9..000000000 --- a/vendor/udx/lib-utility/scripts/jquery.ud.super-search.js +++ /dev/null @@ -1 +0,0 @@ -!function(a){a.fn.super_search=function(b){var c,d,e=this,f={},g={},h={current:"",previous:""};this.attr("ss_element","search_input");var i=a.extend({action:"super_search",ajax_url:ajaxurl,input_classes:{no_results:"ss_no_results",processing:"ss_processing",error:"ss_error"},response_classes:{response_wrapper:"ss_response_container",show_scroll:"ss_show_scroll",item_class:""},append_to:a(e).parent(),search_trigger:!1,search_result_gap:200,limit:5,timers:{abandonment:1e3,search_entry:2e3},async:!1,debug:!0,success:!1,beforeSend:!1,ui:{}},b);"function"!=typeof i.log&&(i.log=function(a){i.debug&&console.log(a)}),a(i.append_to).length||i.log("The ("+i.append_to+") element does not exist.","warning"),i.search_trigger&&"object"==typeof i.search_trigger&&a(i.search_trigger).click(function(){h.current!=h.previous&&a.fn.super_search.do_search()}),this.keyup(function(){return h.current=e.val(),d&&!h.current?void clearTimeout(d):void(h.current!=h.previous&&(d&&clearTimeout(d),d=setTimeout(a.fn.super_search.do_search,i.timers.search_entry)))}),this.focus(function(){a.fn.super_search.ux_change()}),this.blur(function(){a.fn.super_search.ux_change()}),a.fn.super_search.do_search=function(){i.log("do_search()"),h.current=e.val();var b={action:i.action,limit:i.limit,query:h.current};cb_data={post_data:b,settings:i},a.each(i.input_classes,function(b,c){a(e).removeClass(c)}),a(e).addClass(i.input_classes.processing),a.ajax({url:i.ajax_url,async:i.async,data:b,beforeSend:function(a,b){i.log("do_search.beforeSend() - have callback, executing"),cb_data.settings=b,"function"==typeof i.beforeSend&&i.beforeSend.call(this,cb_data)},complete:function(b,c){i.log("do_search.complete( jqXHR, "+c+" )"),a(e).removeClass(i.input_classes.processing),i.log("Ajax response received.")},success:function(b,c,d){i.log("do_search.success()"),"function"==typeof i.success&&(i.log("do_search.success() - have callback, executing"),i.success.call(b,c,d))||(h.previous=h.current,a.fn.super_search.remove_rendered_results(),b.results?(i.last_results=b.results,a.fn.super_search.render_results(b.results)):a(e).addClass(i.input_classes.no_results),b.other&&i.log("Search Debug Data:".data.debug_response))},error:function(){i.log("do_search.error()"),a(e).addClass(i.input_classes.error)},dataType:"json"})},a.fn.super_search.remove_rendered_results=function(){i.log("remove_rendered_results()"),i.rendered_element&&i.rendered_element.length&&a(i.rendered_element).fadeOut(300,function(){}),a.fn.super_search.update_dom_triggers()},a.fn.super_search.update_dom_triggers=function(){i.log("update_dom_triggers()"),a(i.rendered_element).off("mouseenter"),a(i.rendered_element).off("mouseleave"),a(i.rendered_element).mouseenter(function(){g.results_over=!0,a.fn.super_search.ux_change()}).mouseleave(function(){g.results_over=!1,a.fn.super_search.ux_change()})},a.fn.super_search.ux_change=function(){i.log("ux_change()"),a(e).is(":focus")?(g.input_focus=!0,h.current==h.previous&&i.rendered_element&&i.rendered_element.show()):g.input_focus=!1,i.rendered_element&&!g.input_focus&&g.results_over===!1?c=setTimeout(a.fn.super_search.remove_rendered_results,i.timers.abandonment):c&&clearTimeout(c)},a.fn.super_search.render_results=function(b){i.log("render_results()");var c=b.length-1;html=[],html.push(i.ui.response_container='
                '),console.log(i.ui.response_container),a.each(b,function(a,b){var d=[];i.response_classes.item_class&&d.push(i.response_classes.item_class),b.item_class&&d.push(b.item_class),a==c&&d.push("last_item"),html.push('
              • '),b.url&&html.push(''),html.push(b.title),b.url&&html.push(""),html.push("
              • ")}),html.push("
              "),i.rendered_element=a(html.join("")),a(i.append_to).append(i.rendered_element),f.window_height=a(window).height(),f.rendered_element=a(i.rendered_element).height(),f.rendered_element+i.search_result_gap>f.window_height&&(a(i.rendered_element).css("max-height",f.window_height-i.search_result_gap+"px"),a(i.rendered_element).addClass(i.response_classes.show_scroll),f.rendered_element=a(i.rendered_element).height()),a.fn.super_search.update_dom_triggers()}}}(jQuery); \ No newline at end of file diff --git a/vendor/udx/lib-utility/scripts/jquery.ui.progressbar.js b/vendor/udx/lib-utility/scripts/jquery.ui.progressbar.js deleted file mode 100644 index e2ef8d8d1..000000000 --- a/vendor/udx/lib-utility/scripts/jquery.ui.progressbar.js +++ /dev/null @@ -1 +0,0 @@ -!function(a,b){a.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()}),this.valueDiv=a("
              ").appendTo(this.element),this.oldValue=this._value(),this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove(),a.Widget.prototype.destroy.apply(this,arguments)},value:function(a){return a===b?this._value():(this._setOption("value",a),this)},_setOption:function(b,c){"value"===b&&(this.options.value=c,this._refreshValue(),this._value()===this.options.max&&this._trigger("complete")),a.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;return"number"!=typeof a&&(a=0),Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100*this._value()/this.options.max},_refreshValue:function(){var a=this.value(),b=this._percentage();this.oldValue!==a&&(this.oldValue=a,this._trigger("change")),this.valueDiv.toggleClass("ui-corner-right",a===this.options.max).width(b.toFixed(0)+"%"),this.element.attr("aria-valuenow",a)}}),a.extend(a.ui.progressbar,{version:"1.8.10"})}(jQuery); \ No newline at end of file diff --git a/vendor/udx/lib-utility/scripts/src/analysis.client.js b/vendor/udx/lib-utility/scripts/src/analysis.client.js deleted file mode 100644 index 285d2b123..000000000 --- a/vendor/udx/lib-utility/scripts/src/analysis.client.js +++ /dev/null @@ -1,205 +0,0 @@ -/** - * ElasticSearch Analysis Client - * - * @todo Switch to vanilla version of elasticsearch to avoid dependency and resolve shim issue. - */ -define( 'analysis.client', [ 'jquery.elasticsearch', 'analysis.visualizer' ], function() { - console.debug( 'analysis.client', 'loaded' ); - - var options = {}; - var client; - - /** - * Get Current Client - * - * @returns {*|jQuery.es.Client} - */ - function getClient() { - return client || createClient(); - } - - /** - * Create Client Instance - * - * @returns {tinylr.Client} - */ - function createClient( host, index, type ) { - - options = { - host: host, - index: index, - type: type - }; - - return client = new jQuery.es.Client({ - hosts: host - }); - - } - - /** - * Parse Response - * - * @param error - * @param res - */ - function parseResponse( error, res ) { - console.debug( 'parseResponse', error, res ); - console.log( res.hits.hits ); - } - - /** - * Get Mapping - * - * @param query - * @param handleResponse - * @returns {*|Promise} - */ - function getMapping( query, handleResponse ) { - console.debug( 'getMapping', typeof handleResponse ); - - var request = { - index: options.index || 'deafult', - type: options.type || 'profile' - }; - - return getClient().indices.getMapping( request ).then( function parseResponse( res ) { - - if( 'function' === typeof handleResponse ) { - handleResponse.call( null, res[ 'jezf-truq-qgox-hfxp' ].mappings[ 'profile' ] || {}, request ) - } - - }); - - } - - function getSuggestion( query, handleResonse ) { - console.debug( 'getResults', typeof handleResponse ); - - var request = { - index: options.index || 'deafult', - type: options.type || 'profile', - from: 0, - size: 0, - body: query - }; - - return getClient().suggest( request ).then( function parseResponse( res ) { - console.debug( 'getSuggestion', 'parseResponse', typeof res ); - - if( 'function' === typeof handleResponse ) { - handleResponse.call( null, null, res, 'suggest', request ) - } - - }); - } - - /** - * Get Type Mapping - * - * @param query - * @param handleResponse - * @returns {*|Promise} - */ - function getMeta( query, handleResponse ) { - console.debug( 'getMeta', typeof handleResponse ); - - var request = { - index: options.index || 'deafult', - type: options.type || 'profile', - }; - - return getClient().indices.getMapping( request ).then( function parseResponse( res ) { - - if( 'function' === typeof handleResponse ) { - handleResponse.call( null, res[ 'jezf-truq-qgox-hfxp' ].mappings[ options.type ]._meta || {}, 'meta', request ) - } - - }); - - } - - /** - * Get Facets - * - * @param query - * @param facets - * @param handleResponse - * @returns {*|Promise} - */ - function getFacets( query, facets, handleResponse ) { - console.debug( 'getFacets', typeof handleResponse ); - - var request = { - index: options.index || 'deafult', - type: options.type || 'profile', - from: 0, - size: 0, - body: { - query: { - filtered: { - query: query - } - }, - facets: facets - } - }; - - return getClient().search( request ).then( function parseResponse( res ) { - - if( 'function' === typeof handleResponse ) { - handleResponse.call( null, null, res.facets, 'facets', request ) - } - - }).then( function handleError( error ) { - console.debug( 'handleError', arguments ); - - if( 'function' === typeof handleResponse ) { - handleResponse.call( error, null, {}, 'facets', request ) - } - - }); - - } - - /** - * Get Search - * - * @param query - * @param handleResponse - * @returns {*|Promise} - * @constructor - */ - function getResults( query, handleResponse ) { - console.debug( 'getResults', typeof handleResponse ); - - var request = { - index: options.index || 'deafult', - type: options.type || 'profile', - from: 0, - size: 0, - body: query - }; - - return getClient().search( request ).then( function parseResponse( res ) { - console.debug( 'getResults', 'parseResponse', typeof res ); - - if( 'function' === typeof handleResponse ) { - handleResponse.call( null, null, res, 'search', request ) - } - - }); - - } - - return { - client: getClient, - createClient: createClient, - getSuggestion: getSuggestion, - getMeta: getMeta, - getMapping: getMapping, - getFacets: getFacets, - getResults: getResults - }; - -}); \ No newline at end of file diff --git a/vendor/udx/lib-utility/scripts/src/analysis.visualizer.js b/vendor/udx/lib-utility/scripts/src/analysis.visualizer.js deleted file mode 100644 index ef5ad4387..000000000 --- a/vendor/udx/lib-utility/scripts/src/analysis.visualizer.js +++ /dev/null @@ -1,194 +0,0 @@ -/** - * - * - * @todo Consider adding udx.fleck for fixing strings for view. - * - * require( 'analysis.visualizer' )._cached - * - */ -define( 'analysis.visualizer', [ 'http://www.google.com/jsapi/' ], function() { - console.debug( 'analysis.visualizer' ); - - /** - * Google Visualization Library Loaded - */ - function googleVisualizationReady() { - console.debug( 'analysis.visualizer', 'googleVisualizationReady' ); - } - - google.load( 'visualization', '1', { - packages: [ 'geochart', 'corechart', 'table' ], - callback: googleVisualizationReady - }); - - var instance = this; - - var _cached = {}; - - /** - * Get Client Location from Google JS-API - * - * @returns {*} - */ - function clientLocation() { - console.debug( 'analysis.visualizer', 'clientLocation', google.loader.ClientLocation ); - return google.loader.ClientLocation; - } - - /** - * Convert Term to Label - * - * @param key - * @returns {*} - */ - function termLabel( key ) { - - var labels = { - raleigh: 'Raleigh', - port: 'New Port', - new: 'Wilmington', - west: 'West River', - lake: 'Lake', - south: 'South Raleigh', - north: 'North Raleigh', - est: 'Eastern', - east: 'East Brook', - wilfred: 'Wilfred', - zena: 'Durham', - en_us: 'English', - twitter: 'Twitter', - facebook: 'Facebook', - male: 'Male', - female: 'Female' - }; - - return labels[ key ] || key; - - } - - /** - * Render Piegraph - * - * @param title - * @param data - * @returns {*} - */ - function Pie( title, data ) { - console.debug( 'Pie' ); - - var parsedData = google.visualization.arrayToDataTable( data ); - - var element = jQuery( '
              ' ); - - jQuery( '.query-result' ).append( element ); - - new google.visualization.PieChart( element.get( 0 ) ).draw(parsedData, { - title: title - }); - - _cached[ title ] = { - title: title, - element: element - }; - - return instance; - - } - - /** - * Render Regional Map. - * - * @param title - * @param data - * @returns {*} - */ - function Map( title, data ) { - console.debug( 'Map' ); - - var parsedData = google.visualization.arrayToDataTable( data.raw ); - - var element = jQuery( '
              ' ); - jQuery( '.query-result' ).append( element ); - - new google.visualization.GeoChart( element.get( 0 ) ).draw( parsedData, { - region: 'US', - displayMode: 'regions', - resolution: 'provinces', - enableRegionInteractivity: true - }); - - _cached[ title ] = { - title: title, - element: element - }; - - return instance; - - } - - /** - * Render Table. - * - * @param title - * @param data - * @returns {*} - * @constructor - */ - function Table( title, data ) { - console.debug( 'Table', data ); - - var parsedData = new google.visualization.DataTable(); - - if( 'object' !== typeof data ) { - // data = {}; - } - - var total = data.total; - var terms = data.terms || []; - - parsedData.addColumn( 'string', 'Metric' ); - parsedData.addColumn( 'number', 'Percentage' ); - parsedData.addColumn( 'number', 'Count' ); - - terms.forEach( function( item ) { - - parsedData.addRows([ [ - termLabel( item.term ), - { - v: Math.round( ( item.count / total ) * 100 ), - f: ( Math.round( ( item.count / total ) * 100 ) ) + '%' - }, - { - v: item.count - } - ] ]); - - }); - - - var element = jQuery( '
              ' ); - jQuery( '.query-result' ).append( element ); - - new google.visualization.Table( element.get( 0 ) ).draw( parsedData, { - showRowNumber: false, - pageSize: 5 - }); - - _cached[ title ] = { - title: title, - element: element - }; - - return instance; - - } - - return { - Map: Map, - Table: Table, - Pie: Pie, - _cached: _cached - } - -}); - diff --git a/vendor/udx/lib-utility/scripts/src/jquery.ud.buttons.js b/vendor/udx/lib-utility/scripts/src/jquery.ud.buttons.js deleted file mode 100644 index bc5dbccbe..000000000 --- a/vendor/udx/lib-utility/scripts/src/jquery.ud.buttons.js +++ /dev/null @@ -1,260 +0,0 @@ -/* ========================================================= - * jquery-smart-dom-buttons.js v1.0 - * http://usabilitydynamics.com - * ========================================================= - * Copyright 2011 Usability Dynamics, Inc. - * - * Version 0.0.5 - * - * Copyright (c) 2011 Usability Dynamics, Inc. (usabilitydynamics.com) - * ========================================================= */ - -(function( jQuery ){ - - /** - * Handle AJAX Actions and UI actions - * - * {missing detailed description} - * - * @author potanin@UD - * @version 0.2.2 - */ - jQuery.fn.smart_dom_button = function( settings ) { - - /* Set Settings */ - var s = jQuery.extend({ - debug: false, - action_attribute: 'action_attribute', - response_container: 'response_container', - ajax_action: 'action', - label_attributes: { - process: 'processing_label', - revert_label: 'revert_label', - verify_action: 'verify_action' - } - }, settings); - - /* Internal logging function */ - log = function(something, type) { - - if(!s.debug) { - return; - } - - if(window.console && console.debug) { - - if (type == 'error') { - console.error(something); - } else { - console.log(something); - } - - } - - }; - - - /** - * Gets label for the type of element - * - */ - get_label = function( this_button ) { - - var type = jQuery(this_button).get(0).tagName; - var label = ''; - - switch (type) { - - case 'SPAN': - label = jQuery(this_button).text(); - break; - - case 'INPUT': - label = jQuery(this_button).val(); - break; - - } - - return label; - - } - - - /** - * Sets the label for the type - * - */ - set_label = function( label, a ) { - - switch (a.type) { - - case 'SPAN': - jQuery(a.button).text(label); - break; - - case 'INPUT': - jQuery(a.button).val(label); - break; - - } - - return label; - - } - - - /** - * Execute an action for the button - * - * @todo Improve ajax response handling, to include hiding response element on error. - * - */ - do_execute = function( this_button ) { - - /* Array of all settings specific to the current button */ - var a = { - button: this_button, - type: jQuery(this_button).get(0).tagName, - original_label: jQuery(this_button).attr('original_label') ? jQuery(this_button).attr('original_label') : get_label(this_button) - }; - - /* Get wrapper if used and exists */ - if(s.wrapper && jQuery(a.button).closest(s.wrapper).length) { - a.wrapper = jQuery(a.button).closest(s.wrapper); - a.use_wrapper = true; - } else { - a.wrapper = a.button; - a.use_wrapper = false; - } - - /* Determine action */ - a.the_action = jQuery(a.wrapper).attr(s.action_attribute) ? jQuery(a.wrapper).attr(s.action_attribute) : false; - - /* Get labels */ - if(s.label_attributes.processing && jQuery(a.wrapper).attr(s.label_attributes.processing)) { - a.processing_label = jQuery(a.wrapper).attr(s.label_attributes.processing) ? jQuery(a.wrapper).attr(s.label_attributes.processing) : false; - } - - if(s.label_attributes.verify_action && jQuery(a.wrapper).attr(s.label_attributes.verify_action)) { - a.verify_action = jQuery(a.wrapper).attr(s.label_attributes.verify_action) ? jQuery(a.wrapper).attr(s.label_attributes.verify_action) : false; - } - - /* Set original label only if a revert label exists */ - if(s.label_attributes.revert_label && jQuery(a.wrapper).attr(s.label_attributes.revert_label)) { - a.revert_label = jQuery(a.wrapper).attr(s.label_attributes.revert_label) ? jQuery(a.wrapper).attr(s.label_attributes.revert_label) : false; - - /* Set original label if not already set */ - if(!jQuery(a.wrapper).attr('original_label')) { - a.original_label = get_label(a.button); - jQuery(a.wrapper).attr('original_label', a.original_label); - } - - } - - /* If no action found, we leave */ - if(!a.the_action) { - return; - } - - if(a.verify_action) { - if(!confirm(a.verify_action)) { - return; - } - } - - /* Create a response container if we are using a wrapper */ - if(a.use_wrapper) { - - if(!jQuery(s.response_container, a.wrapper).length) { - jQuery(a.wrapper).append(''); - } - - a.response_container = jQuery('.response_container', a.wrapper); - - /* Unset all classes */ - jQuery(a.response_container).removeClass(); - jQuery(a.response_container).addClass('response_container'); - - if(a.processing_label) { - jQuery(a.response_container).html(a.processing_label); - } - - } - - /* Check if this is a UI action first, otherwise use AJAX */ - if(a.the_action == 'ui') { - - /* If a revert label exists, we toggle them */ - if(a.revert_label) { - - if(get_label(a.button) == a.revert_label) { - set_label(a.original_label, a); - - } else { - set_label(a.revert_label, a); - - } - - } - - if(jQuery(a.wrapper).attr('toggle')) { - jQuery(jQuery(a.wrapper).attr('toggle')).toggle(); - } - - if(jQuery(a.wrapper).attr('show')) { - jQuery(jQuery(a.wrapper).attr('show')).show(); - } - - if(jQuery(a.wrapper).attr('hide')) { - jQuery(jQuery(a.wrapper).attr('hide')).hide(); - } - - } else { - - jQuery.post(ajaxurl, { - _wpnonce: flawless_admin.actions_nonce, - action: s.ajax_action, - the_action: a.the_action - }, function (result) { - - if(result && result.success) { - jQuery(a.response_container).show(); - - if(result.css_class) { - jQuery(a.response_container).addClass(result.css_class); - } - - if(result.remove_element && jQuery(result.remove_element).length) { - jQuery(result.remove_element).remove(); - } - - jQuery(a.response_container).html(result.message); - - setTimeout(function() { - - jQuery(a.response_container).fadeOut('slow', function() { - jQuery(a.response_container).remove(); - }); - - }, 10000); - - } - - }, 'json'); - - - } - - } - - - jQuery( this ).click(function() { - log("Button triggered."); - do_execute( this ); - }); - - - return this; - - }; -}) ( jQuery ); \ No newline at end of file diff --git a/vendor/udx/lib-utility/scripts/src/jquery.ud.date-selector.js b/vendor/udx/lib-utility/scripts/src/jquery.ud.date-selector.js deleted file mode 100644 index 49bd2cca3..000000000 --- a/vendor/udx/lib-utility/scripts/src/jquery.ud.date-selector.js +++ /dev/null @@ -1,1175 +0,0 @@ -/** ========================================================= - * jquery.ud.date_selector.js v0.1.1 - * http://usabilitydynamics.com - * ========================================================= - * - * Commercial use requires one-time license fee - * http://usabilitydynamics.com/licenses - * - * Copyright 2012 Usability Dynamics, Inc. (usabilitydynamics.com) - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Alexandru Marasteanu BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * TO DO: - * - Convert all data to be stored in JS object, not in DOM. - * - Add validation and better converion for date formats to setDate(); - * - * - * - * ========================================================= */ - -/*jslint devel: true, undef: true, browser: true, continue: true, unparam: true, debug: true, eqeq: true, vars: true, white: true, newcap: true, plusplus: true, maxerr: 50, indent: 2 */ -/*global window */ -/*global console */ -/*global clearTimeout */ -/*global setTimeout */ -/*global jQuery */ - - -(function (jQuery) { - "use strict"; - - jQuery.prototype.date_selector = function ( default_options ) { - - var s = { - element: this, - cache: {} - }; - - /** Merge Custom Settings with Defaults */ - s.options = jQuery.extend( true, { - flat: false, - starts: 1, - prev: '◀', - next: '▶', - lastSel: false, - mode: 'single', - view: 'days', - calendars: 1, - format: 'Y-m-d', - position: 'bottom', - eventName: 'click', - onRender: function () { - return {}; - }, - onChange: function () { - return true; - }, - onShow: function () { - return true; - }, - onBeforeShow: function () { - return true; - }, - locale: { - days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], - daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], - daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"], - months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], - monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], - weekMin: 'wk' - }, - views: { - years: 'date_selector_view_years', - moths: 'date_selector_view_months', - days: 'date_selector_view_days' - }, - template: { - wrapper: '
              ', - head: [ - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '
              <%=prev%><%=next%>
              <%=week%><%=day1%><%=day2%><%=day3%><%=day4%><%=day5%><%=day6%><%=day7%>
              '], - space: '
              ', - days: ['', '', '<%=weeks[0].week%>', '<%=weeks[0].days[0].text%>', '<%=weeks[0].days[1].text%>', '<%=weeks[0].days[2].text%>', '<%=weeks[0].days[3].text%>', '<%=weeks[0].days[4].text%>', '<%=weeks[0].days[5].text%>', '<%=weeks[0].days[6].text%>', '', '', '<%=weeks[1].week%>', '<%=weeks[1].days[0].text%>', '<%=weeks[1].days[1].text%>', '<%=weeks[1].days[2].text%>', '<%=weeks[1].days[3].text%>', '<%=weeks[1].days[4].text%>', '<%=weeks[1].days[5].text%>', '<%=weeks[1].days[6].text%>', '', '', '<%=weeks[2].week%>', '<%=weeks[2].days[0].text%>', '<%=weeks[2].days[1].text%>', '<%=weeks[2].days[2].text%>', '<%=weeks[2].days[3].text%>', '<%=weeks[2].days[4].text%>', '<%=weeks[2].days[5].text%>', '<%=weeks[2].days[6].text%>', '', '', '<%=weeks[3].week%>', '<%=weeks[3].days[0].text%>', '<%=weeks[3].days[1].text%>', '<%=weeks[3].days[2].text%>', '<%=weeks[3].days[3].text%>', '<%=weeks[3].days[4].text%>', '<%=weeks[3].days[5].text%>', '<%=weeks[3].days[6].text%>', '', '', '<%=weeks[4].week%>', '<%=weeks[4].days[0].text%>', '<%=weeks[4].days[1].text%>', '<%=weeks[4].days[2].text%>', '<%=weeks[4].days[3].text%>', '<%=weeks[4].days[4].text%>', '<%=weeks[4].days[5].text%>', '<%=weeks[4].days[6].text%>', '', '', '<%=weeks[5].week%>', '<%=weeks[5].days[0].text%>', '<%=weeks[5].days[1].text%>', '<%=weeks[5].days[2].text%>', '<%=weeks[5].days[3].text%>', '<%=weeks[5].days[4].text%>', '<%=weeks[5].days[5].text%>', '<%=weeks[5].days[6].text%>', '', ''], - months: ['', '', '<%=data[0]%>', '<%=data[1]%>', '<%=data[2]%>', '<%=data[3]%>', '', '', '<%=data[4]%>', '<%=data[5]%>', '<%=data[6]%>', '<%=data[7]%>', '', '', '<%=data[8]%>', '<%=data[9]%>', '<%=data[10]%>', '<%=data[11]%>', '', ''] - } - }, default_options ); - - - /** - * Logging Function. - * - * @since 0.1 - * @author potanin@UD - */ - s.log = typeof s.log === 'function' ? s.log : function (notice, type, console_type, override_debug) { - //console.log('DP:: ' + notice); - }; - - - /** - * Primary Initializer. - * - * @since 0.1 - * @author potanin@UD - */ - s.initialize = typeof s.initialize === 'function' ? s.initialize : function () { - s.log('s.initialize()', 'function'); - - s.extendDate( s.options.locale ); - s.options.calendars = Math.max(1, parseInt(s.options.calendars, 10) || 1); - s.options.mode = /single|multiple|range/.test(s.options.mode) ? s.options.mode : 'single'; - - /* Cycle through each container and identify related calendar elements */ - return s.element.each( function ( index, this_wrapper ) { - var id = 'date_selector_' + parseInt(Math.random() * 1000), this_calendar, count; - - /* If this element alreay has options saved to data, we do nothing */ - if( jQuery( s.element ).data('date_selector_initialized') ) { - s.log('s.initialize() - DOM element already initialized, skipping.', 'function'); - return; - } - - if( !s.options.date ) { - s.options.date = new Date(); - } - - if ( s.options.date.constructor === String ) { - s.options.date = parseDate(s.options.date, s.options.format); - s.options.date.setHours(0, 0, 0, 0); - } - - if (s.options.mode != 'single') { - if ( s.options.date.constructor != Array ) { - s.options.date = [s.options.date.valueOf()]; - if (s.options.mode === 'range') { - s.options.date.push(((new Date(s.options.date[0])).setHours(23, 59, 59, 0)).valueOf()); - } - } else { - for (var i = 0; i < s.options.date.length; i++) { - s.options.date[i] = (parseDate(s.options.date[i], s.options.format).setHours(0, 0, 0, 0)).valueOf(); - } - if (s.options.mode === 'range') { - s.options.date[1] = ((new Date(s.options.date[1])).setHours(23, 59, 59, 0)).valueOf(); - } - } - } else { - s.options.date = s.options.date.valueOf(); - } - - if (!s.options.current) { - s.options.current = new Date(); - } else { - s.options.current = parseDate(s.options.current, s.options.format); - } - - s.options.current.setDate(1); - s.options.current.setHours(0, 0, 0, 0); - - s.options.id = id; - - jQuery( this_wrapper ).data('date_selector_id', s.options.id); - - /* Attach to mousedown so propagadtion can be stopped early enough when the calendar is being interacted with */ - this_calendar = jQuery( s.options.template.wrapper ).attr( 'id' , id ).bind( 'mousedown', click ).data('date_selector', s.options); - - if (s.options.className) { - this_calendar.addClass(s.options.className); - } - - var html = ''; - for (var i = 0; i < s.options.calendars; i++) { - count = s.options.starts; - - if (i > 0) { - html += s.options.template.space; - } - - html += tmpl(s.options.template.head.join(''), { - week: s.options.locale.weekMin, - prev: s.options.prev, - next: s.options.next, - day1: s.options.locale.daysMin[(count++) % 7], - day2: s.options.locale.daysMin[(count++) % 7], - day3: s.options.locale.daysMin[(count++) % 7], - day4: s.options.locale.daysMin[(count++) % 7], - day5: s.options.locale.daysMin[(count++) % 7], - day6: s.options.locale.daysMin[(count++) % 7], - day7: s.options.locale.daysMin[(count++) % 7] - }); - - }; - - this_calendar.find('tr:first').append( html ).find( 'table' ).addClass( s.options.views[s.options.view] ); - - fill( this_calendar.get(0) ); - - if ( s.options.flat ) { - this_calendar.appendTo( this ).show().css('position', 'relative'); - layout(this_calendar.get(0)); - - } else { - this_calendar.appendTo(document.body); - jQuery(this).bind(s.options.eventName, show); - - } - - jQuery( s.element ).data('date_selector_initialized', true ); - - }); - - }; - - - /** - * {}. - * - * @since 0.1 - * @author potanin@UD - */ - var tmpl = function (str, data) { - s.log('tmpl()', 'function'); - - // Figure out if we're getting a template, or if we need to load the template - and be sure to cache the result. - var fn = !/\W/.test(str) ? s.cache[str] = s.cache[str] || tmpl(document.getElementById(str).innerHTML) : - - // Generate a reusable function that will serve as a template generator (and which will be cached). - new Function("obj", "var p=[],print=function(){p.push.apply(p,arguments);};" + "with(obj){p.push('" + str.replace(/[\r\t\n]/g, " ").split("<%").join("\t").replace(/((^|%>)[^\t]*)'/g, "$1\r").replace(/\t=(.*?)%>/g, "',$1,'").split("\t").join("');").split("%>").join("p.push('").split("\r").join("\\'") + "');}return p.join('');"); - - // Provide some basic currying to the user - return data ? fn(data) : fn; - }; - - - /** - * {}. - * - * @since 0.1 - * @author potanin@UD - */ - var fill = function ( this_calendar ) { - s.log('fill()', 'function'); - - this_calendar = jQuery( this_calendar ); - - var currentCal = Math.floor( s.options.calendars / 2 ), - date, data, dow, month, count = 0, - week, days, indic, indic2, html, tblCal; - - this_calendar.find('td>table tbody').remove(); - - for (var i = 0; i < s.options.calendars; i++) { - date = new Date(s.options.current); - date.addMonths(-currentCal + i); - - tblCal = this_calendar.find('table').eq( i + 1) ; - - if( typeof tblCal === 'object' && typeof tblCal[0] != 'undefined' ) { - - switch ( tblCal[0].className ) { - case 'date_selector_view_days': - dow = s.formatDate(date, 'B, Y'); - break; - - case 'date_selector_view_months': - dow = date.getFullYear(); - break; - - case 'date_selector_view_years': - dow = (date.getFullYear() - 6) + ' - ' + (date.getFullYear() + 5); - break; - - }; - - } - - tblCal.find('thead tr:first th:eq(1) span').text(dow); - dow = date.getFullYear() - 6; - data = { - data: [], - className: 'date_selector_years' - } - - for (var j = 0; j < 12; j++) { - data.data.push(dow + j); - }; - - html = tmpl(s.options.template.months.join(''), data); - date.setDate(1); - data = { - weeks: [], - test: 10 - }; - - month = date.getMonth(); - var dow = (date.getDay() - s.options.starts) % 7; - date.addDays(-(dow + (dow < 0 ? 7 : 0))); - week = -1; - count = 0; - while (count < 42) { - indic = parseInt(count / 7, 10); - indic2 = count % 7; - if (!data.weeks[indic]) { - week = date.getWeekNumber(); - data.weeks[indic] = { - week: week, - days: [] - }; - } - data.weeks[indic].days[indic2] = { - text: date.getDate(), - classname: [] - }; - if (month != date.getMonth()) { - data.weeks[indic].days[indic2].classname.push('date_selectorNotInMonth'); - } - if (date.getDay() === 0) { - data.weeks[indic].days[indic2].classname.push('date_selectorSunday'); - } - if (date.getDay() === 6) { - data.weeks[indic].days[indic2].classname.push('date_selectorSaturday'); - } - var fromUser = s.options.onRender(date); - var val = date.valueOf(); - if (fromUser.selected || s.options.date === val || jQuery.inArray(val, s.options.date) > -1 || (s.options.mode === 'range' && val >= s.options.date[0] && val <= s.options.date[1])) { - data.weeks[indic].days[indic2].classname.push('date_selector_selected'); - } - if (fromUser.disabled) { - data.weeks[indic].days[indic2].classname.push('date_selector_disabled'); - } - if (fromUser.className) { - data.weeks[indic].days[indic2].classname.push(fromUser.className); - } - data.weeks[indic].days[indic2].classname = data.weeks[indic].days[indic2].classname.join(' '); - count++; - date.addDays(1); - } - - html = tmpl(s.options.template.days.join(''), data) + html; - - data = { - data: s.options.locale.monthsShort, - className: 'date_selector_months' - }; - - html = tmpl(s.options.template.months.join(''), data) + html; - tblCal.append(html); - - } - }; - - - /** - * {}. - * - * @since 0.1 - * @author potanin@UD - */ - var parseDate = function ( date, format ) { - s.log('parseDate()', 'function'); - - if( !date ) { - return; - } - - if ( date.constructor === Date ) { - return new Date(date); - } - var parts = date.split(/\W+/); - var against = format.split(/\W+/), - d, m, y, h, min, now = new Date(); - for (var i = 0; i < parts.length; i++) { - switch (against[i]) { - case 'd': - case 'e': - d = parseInt(parts[i], 10); - break; - case 'm': - m = parseInt(parts[i], 10) - 1; - break; - case 'Y': - case 'y': - y = parseInt(parts[i], 10); - y += y > 100 ? 0 : (y < 29 ? 2000 : 1900); - break; - case 'H': - case 'I': - case 'k': - case 'l': - h = parseInt(parts[i], 10); - break; - case 'P': - case 'p': - if (/pm/i.test(parts[i]) && h < 12) { - h += 12; - } else if (/am/i.test(parts[i]) && h >= 12) { - h -= 12; - } - break; - case 'M': - min = parseInt(parts[i], 10); - break; - } - } - return new Date( - y === undefined ? now.getFullYear() : y, m === undefined ? now.getMonth() : m, d === undefined ? now.getDate() : d, h === undefined ? now.getHours() : h, min === undefined ? now.getMinutes() : min, 0); - }; - - - /** - * {}. - * - * @since 0.1 - * @author potanin@UD - */ - s.formatDate = typeof s.formatDate === 'function' ? s.formatDate : function (date, format) { - - if( s ) { - s.log('s.formatDate()', 'function'); - } - - var m = date.getMonth(); - var d = date.getDate(); - var y = date.getFullYear(); - var wn = date.getWeekNumber(); - var w = date.getDay(); - var s = {}; - var hr = date.getHours(); - var pm = (hr >= 12); - var ir = (pm) ? (hr - 12) : hr; - var dy = date.getDayOfYear(); - if (ir === 0) { - ir = 12; - } - var min = date.getMinutes(); - var sec = date.getSeconds(); - var parts = format.split(''), - part; - for (var i = 0; i < parts.length; i++) { - part = parts[i]; - switch (parts[i]) { - case 'a': - part = date.getDayName(); - break; - case 'A': - part = date.getDayName(true); - break; - case 'b': - part = date.getMonthName(); - break; - case 'B': - part = date.getMonthName(true); - break; - case 'C': - part = 1 + Math.floor(y / 100); - break; - case 'd': - part = (d < 10) ? ("0" + d) : d; - break; - case 'e': - part = d; - break; - case 'H': - part = (hr < 10) ? ("0" + hr) : hr; - break; - case 'I': - part = (ir < 10) ? ("0" + ir) : ir; - break; - case 'j': - part = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; - break; - case 'k': - part = hr; - break; - case 'l': - part = ir; - break; - case 'm': - part = (m < 9) ? ("0" + (1 + m)) : (1 + m); - break; - case 'M': - part = (min < 10) ? ("0" + min) : min; - break; - case 'p': - case 'P': - part = pm ? "PM" : "AM"; - break; - case 's': - part = Math.floor(date.getTime() / 1000); - break; - case 'S': - part = (sec < 10) ? ("0" + sec) : sec; - break; - case 'u': - part = w + 1; - break; - case 'w': - part = w; - break; - case 'y': - part = ('' + y).substr(2, 2); - break; - case 'Y': - part = y; - break; - } - parts[i] = part; - } - return parts.join(''); - }; - - - - /** - * {}. - * - * @since 0.1 - * @author potanin@UD - */ - s.extendDate = typeof s.extendDate === 'function' ? s.extendDate : function ( locale ) { - - if (Date.prototype.tempDate) { - return; - } - - Date.prototype.tempDate = null; - Date.prototype.months = locale.months; - Date.prototype.monthsShort = locale.monthsShort; - Date.prototype.days = locale.days; - Date.prototype.daysShort = locale.daysShort; - - Date.prototype.getMonthName = function (fullName) { - return this[ fullName ? 'months' : 'monthsShort' ][ this.getMonth() ]; - }; - - Date.prototype.getDayName = function (fullName) { - return this[fullName ? 'days' : 'daysShort'][this.getDay()]; - }; - - Date.prototype.addDays = function (n) { - this.setDate(this.getDate() + n); - this.tempDate = this.getDate(); - }; - - Date.prototype.addMonths = function (n) { - if (this.tempDate === null) { - this.tempDate = this.getDate(); - } - this.setDate(1); - this.setMonth(this.getMonth() + n); - this.setDate(Math.min(this.tempDate, this.getMaxDays())); - }; - - Date.prototype.addYears = function (n) { - if (this.tempDate === null) { - this.tempDate = this.getDate(); - } - this.setDate(1); - this.setFullYear(this.getFullYear() + n); - this.setDate(Math.min(this.tempDate, this.getMaxDays())); - }; - - Date.prototype.getMaxDays = function () { - var tmpDate = new Date(Date.parse(this)), - d = 28, - m; - m = tmpDate.getMonth(); - d = 28; - while (tmpDate.getMonth() === m) { - d++; - tmpDate.setDate(d); - } - return d - 1; - }; - - Date.prototype.getFirstDay = function () { - var tmpDate = new Date(Date.parse(this)); - tmpDate.setDate(1); - return tmpDate.getDay(); - }; - - Date.prototype.getWeekNumber = function () { - var tempDate = new Date(this); - tempDate.setDate(tempDate.getDate() - (tempDate.getDay() + 6) % 7 + 3); - var dms = tempDate.valueOf(); - tempDate.setMonth(0); - tempDate.setDate(4); - return Math.round((dms - tempDate.valueOf()) / (604800000)) + 1; - }; - - Date.prototype.getDayOfYear = function () { - var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0); - var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0); - var time = now - then; - return Math.floor(time / 24 * 60 * 60 * 1000); - }; - - }; - - - /** - * Displays a single calendar. The calendar object (not the wrapper) is passed to function. - * - * Adds width and height to the Calendar element and to the primary container (.date_selector_container) - * - * @since 0.1 - * @author potanin@UD - */ - var layout = function ( el ) { - s.log('layout()', 'function'); - - var options = jQuery( el ).data('date_selector'); - var this_calendar = jQuery('#' + options.id); - - /* Gets all the divs within the Calendar element */ - if (!s.options.extraHeight) { - var divs = jQuery( el ).find( 'div' ); - s.options.extraHeight = divs.get(0).offsetHeight + divs.get(1).offsetHeight; - s.options.extraWidth = divs.get(2).offsetWidth + divs.get(3).offsetWidth; - } - - var first_table = this_calendar.find('table:first').get(0); - var width = first_table.offsetWidth; - var height = first_table.offsetHeight; - - this_calendar.css({ - width: width + s.options.extraWidth + 'px', - height: height + s.options.extraHeight + 'px' - }).find('div.date_selector_container').css({ - width: width + 'px', - height: height + 'px' - }); - - }; - - - /** - * Click Monitor for the entire Calendar object. - * - * @since 0.1 - * @author potanin@UD - */ - var click = function ( ev ) { - s.log('click()', 'function'); - - if (jQuery(ev.target).is('span')) { - ev.target = ev.target.parentNode; - } - - var clicked_element = jQuery(ev.target); - - /* If we didn't click a link, there is nothing we can do here */ - if( !clicked_element.is('a') ) { - return; - } - - ev.stopPropagation(); - - ev.preventDefault(); - - ev.target.blur(); - - if (clicked_element.hasClass('date_selector_disabled')) { - return false; - } - - var options = s.options; - var parentEl = clicked_element.parent(); - var tblEl = parentEl.parent().parent().parent(); /* the table element, e.g. .date_selector_view_days */ - var tblIndex = jQuery('table', this).index(tblEl.get(0)) - 1; - var tmp = new Date(options.current); - var changed = false; - var fillIt = false; - - if (parentEl.is('th')) { - - if (parentEl.hasClass('date_selectorWeek') && s.options.mode === 'range' && !parentEl.next().hasClass('date_selector_disabled')) { - var val = parseInt(parentEl.next().text(), 10); - tmp.addMonths(tblIndex - Math.floor(s.options.calendars / 2)); - - if (parentEl.next().hasClass('date_selectorNotInMonth')) { - tmp.addMonths(val > 15 ? -1 : 1); - } - - tmp.setDate(val); - s.options.date[0] = (tmp.setHours(0, 0, 0, 0)).valueOf(); - tmp.setHours(23, 59, 59, 0); - tmp.addDays(6); - s.options.date[1] = tmp.valueOf(); - fillIt = true; - changed = true; - s.options.lastSel = false; - - } else if (parentEl.hasClass('date_selector_month')) { - tmp.addMonths(tblIndex - Math.floor(s.options.calendars / 2)); - switch (tblEl.get(0).className) { - case 'date_selector_view_days': - tblEl.get(0).className = 'date_selector_view_months'; - clicked_element.find('span').text(tmp.getFullYear()); - break; - case 'date_selector_view_months': - tblEl.get(0).className = 'date_selector_view_years'; - clicked_element.find('span').text((tmp.getFullYear() - 6) + ' - ' + (tmp.getFullYear() + 5)); - break; - case 'date_selector_view_years': - tblEl.get(0).className = 'date_selector_view_days'; - clicked_element.find('span').text(s.formatDate(tmp, 'B, Y')); - break; - } - - } else if (parentEl.parent().parent().is('thead')) { - switch (tblEl.get(0).className) { - case 'date_selector_view_days': - s.options.current.addMonths(parentEl.hasClass('date_selectorGoPrev') ? -1 : 1); - break; - case 'date_selector_view_months': - s.options.current.addYears(parentEl.hasClass('date_selectorGoPrev') ? -1 : 1); - break; - case 'date_selector_view_years': - s.options.current.addYears(parentEl.hasClass('date_selectorGoPrev') ? -12 : 12); - break; - } - fillIt = true; - } - - } else if ( parentEl.is('td') && !parentEl.hasClass('date_selector_disabled')) { - - switch (tblEl.get(0).className) { - - case 'date_selector_view_months': - s.options.current.setMonth(tblEl.find('tbody.date_selector_months td').index(parentEl)); - s.options.current.setFullYear(parseInt(tblEl.find('thead th.date_selector_month span').text(), 10)); - s.options.current.addMonths(Math.floor(s.options.calendars / 2) - tblIndex); - tblEl.get(0).className = 'date_selector_view_days'; - break; - - case 'date_selector_view_years': - s.options.current.setFullYear(parseInt(clicked_element.text(), 10)); - tblEl.get(0).className = 'date_selector_view_months'; - break; - - default: - var val = parseInt(clicked_element.text(), 10); - tmp.addMonths(tblIndex - Math.floor(s.options.calendars / 2)); - - if (parentEl.hasClass('date_selectorNotInMonth')) { - tmp.addMonths(val > 15 ? -1 : 1); - } - - tmp.setDate(val); - switch (s.options.mode) { - - case 'multiple': - val = (tmp.setHours(0, 0, 0, 0)).valueOf(); - if (jQuery.inArray(val, s.options.date) > -1) { - jQuery.each(s.options.date, function (nr, dat) { - if (dat === val) { - s.options.date.splice(nr, 1); - return false; - } - }); - } else { - s.options.date.push(val); - } - break; - - case 'range': - if (!s.options.lastSel) { - s.options.date[0] = (tmp.setHours(0, 0, 0, 0)).valueOf(); - } - val = (tmp.setHours(23, 59, 59, 0)).valueOf(); - if (val < s.options.date[0]) { - s.options.date[1] = s.options.date[0] + 86399000; - s.options.date[0] = val - 86399000; - } else { - s.options.date[1] = val; - } - s.options.lastSel = !s.options.lastSel; - break; - - default: - s.options.date = tmp.valueOf(); - break; - - } - - break; - } - - fillIt = true; - changed = true; - - } - - if (fillIt) { - fill(this); - } - - if (changed) { - s.options.onChange.apply( this, prepareDate( options ) ); - } - - }; - - - /** - * {}. - * - * @since 0.1 - * @author potanin@UD - */ - var prepareDate = function ( options ) { - s.log('prepareDate()', 'function'); - - var tmp; - - if (s.options.mode === 'single') { - tmp = new Date( s.options.date ); - return [s.formatDate( tmp, s.options.format), tmp, s.options.el]; - - } else { - - tmp = [ [], [], s.options.el ]; - - jQuery.each( s.options.date , function( nr, val ) { - var date = new Date(val); - tmp[0].push(s.formatDate( date , s.options.format)); - tmp[1].push(date); - }); - - return tmp; - } - }; - - - /** - * {}. - * - * @since 0.1 - * @author potanin@UD - */ - var getViewport = function () { - s.log('getViewport()', 'function'); - - var m = document.compatMode === 'CSS1Compat'; - return { - l: window.pageXOffset || (m ? document.documentElement.scrollLeft : document.body.scrollLeft), - t: window.pageYOffset || (m ? document.documentElement.scrollTop : document.body.scrollTop), - w: window.innerWidth || (m ? document.documentElement.clientWidth : document.body.clientWidth), - h: window.innerHeight || (m ? document.documentElement.clientHeight : document.body.clientHeight) - }; - }; - - - /** - * {}. - * - * @since 0.1 - * @author potanin@UD - */ - var isChildOf = function (parentEl, el, container) { - s.log('isChildOf()', 'function'); - - if (parentEl === el) { - return true; - } - if (parentEl.contains) { - return parentEl.contains(el); - } - if (parentEl.compareDocumentPosition) { - return !!(parentEl.compareDocumentPosition(el) & 16); - } - var prEl = s.element.parentNode; - while (prEl && prEl != container) { - if (prEl === parentEl) return true; - prEl = prEl.parentNode; - } - return false; - } - - - /** - * {}. - * - * @since 0.1 - * @author potanin@UD - */ - var show = function ( ev ) { - s.log('show()', 'function'); - - /* Get the calendar container DOM element */ - var element = this; - - /* Get jQuery Object for calendar */ - var calendar_object = jQuery('#' + jQuery( this ).data('date_selector_id')); - - if (!calendar_object.is(':visible')) { - - /* Get DOM Element */ - var calendar_element = calendar_object.get(0); - - fill( calendar_element ); - - /* Applying to the wrapper? */ - s.options.onBeforeShow.apply(this, [ calendar_element ]); - - var pos = jQuery( element ).offset(); - var viewPort = getViewport(); - var top = pos.top; - var left = pos.left; - var oldDisplay = jQuery.curCSS( calendar_element , 'display' ); - - calendar_object.css({ - visibility: 'hidden', - display: 'block' - }); - - layout( calendar_element ); - - switch (s.options.position) { - case 'top': - top -= calendar_element.offsetHeight; - break; - case 'left': - left -= c.offsetWidth; - break; - case 'right': - left += element.offsetWidth; - break; - case 'bottom': - top += element.offsetHeight; - break; - } - - if (top + calendar_element.offsetHeight > viewPort.t + viewPort.h) { - top = pos.top - calendar_element.offsetHeight; - } - - if (top < viewPort.t) { - top = pos.top + this.offsetHeight + calendar_element.offsetHeight; - } - - if (left + calendar_element.offsetWidth > viewPort.l + viewPort.w) { - left = pos.left - calendar_element.offsetWidth; - } - - if (left < viewPort.l) { - left = pos.left + this.offsetWidth - } - - calendar_object.css({ - visibility: 'visible', - display: 'block', - top: top + 'px', - left: left + 'px' - }); - - if (s.options.onShow.apply(this, [ calendar_element ]) != false) { - calendar_object.show(); - } - - jQuery( document ).bind( 'mousedown' , { - element: element, - calendar_object: calendar_object, - trigger: this - }, hide ); - - } - return false; - }; - - - /** - * {}. - * - * @since 0.1 - * @author potanin@UD - */ - var hide = function ( ev, args ) { - s.log('hide()', 'function'); - - if ( ev.target != ev.data.trigger && !isChildOf( ev.data.calendar_object, ev.target, ev.data.element )) { - ev.data.calendar_object.hide(); - jQuery(document).unbind('mousedown', hide); - } - }; - - - - /** - * {} - * - * @author potanin@UD - */ - this.showPicker = s.showPicker = typeof s.showPicker === 'function' ? s.showPicker : function() { - s.log('showPicker()', 'function'); - - return this.each(function () { - if (jQuery(this).data('date_selector_id')) { - show.apply(this); - } - }); - }; - - - /** - * {} - * - * @author potanin@UD - */ - this.hidePicker = s.hidePicker = typeof s.hidePicker === 'function' ? s.hidePicker : function() { - s.log('hidePicker()', 'function'); - - return this.each(function () { - if (jQuery(this).data('date_selector_id')) { - jQuery('#' + jQuery(this).data('date_selector_id')).hide(); - } - }); - }; - - - /** - * {} - * - * - * @author potanin@UD - */ - this.setDate = s.setDate = typeof s.setDate === 'function' ? s.setDate : function( date, shiftTo ) { - s.log('setDate()', 'function'); - - return s.element.each( function () { - - if( !jQuery( this ).data('date_selector_id')) { - s.log('setDate() - Element not initialized.', 'function'); - return; - } - - var cal = jQuery('#' + jQuery(this).data('date_selector_id')); - - s.options.date = date; - - if( !s.options.date ) { - s.options.date = new Date(); - } - - if ( s.options.date.constructor === String ) { - s.options.date = parseDate(s.options.date, s.options.format); - s.options.date.setHours(0, 0, 0, 0); - } - - if (s.options.mode != 'single') { - if ( s.options.date.constructor != Array ) { - s.options.date = [s.options.date.valueOf()]; - if (s.options.mode === 'range') { - s.options.date.push(((new Date(s.options.date[0])).setHours(23, 59, 59, 0)).valueOf()); - } - } else { - - for (var i = 0; i < s.options.date.length; i++) { - if( typeof s.options.date[i] != 'undefined' ) { - s.options.date[i] = (parseDate( s.options.date[i] , s.options.format).setHours(0, 0, 0, 0)).valueOf(); - } - } - - if ( s.options.mode === 'range' ) { - s.options.date[1] = ((new Date(s.options.date[1])).setHours(23, 59, 59, 0)).valueOf(); - } - } - } else { - s.options.date = s.options.date.valueOf(); - } - - - if (shiftTo) { - s.options.current = new Date( s.options.mode != 'single' ? s.options.date[0] : s.options.date ); - } - - fill( s.element.get(0) ); - - }); - - }; - - - /** - * {} - * - * @author potanin@UD - */ - this.getDate = s.getDate = typeof s.getDate === 'function' ? s.getDate : function() { - s.log('getDate()', 'function'); - - if (this.size() > 0) { - return prepareDate(jQuery('#' + jQuery(this).data('date_selector_id')).data('date_selector'))[formated ? 0 : 1]; - } - }; - - - /** - * {} - * - * @author potanin@UD - */ - this.Clear = s.clear = typeof s.clear === 'function' ? s.clear : function() { - s.log('clear()', 'function'); - - return this.each(function () { - if (jQuery(this).data('date_selector_id')) { - var cal = jQuery('#' + jQuery(this).data('date_selector_id')); - s.options = s.element.data('date_selector'); - if (s.options.mode != 'single') { - s.options.date = []; - fill(s.element.get(0)); - } - } - }); - }; - - - /** - * {} - * - * @author potanin@UD - */ - this.fixLayout = s.fixLayout = typeof s.fixLayout === 'function' ? s.fixLayout : function() { - s.log('fixLayout()', 'function'); - - return this.each(function () { - if (jQuery(this).data('date_selector_id')) { - var cal = jQuery('#' + jQuery(this).data('date_selector_id')); - s.options = s.element.data('date_selector'); - if (s.options.flat) { - layout(s.element.get(0)); - } - } - }); - }; - - - s.initialize(); - - return this; - - } /* end jQuery.prototype.date_selector */ - -}(jQuery) /* p.s. No dog balls. */ ); - - diff --git a/vendor/udx/lib-utility/scripts/src/jquery.ud.dynamic-filter.js b/vendor/udx/lib-utility/scripts/src/jquery.ud.dynamic-filter.js deleted file mode 100644 index 48908f372..000000000 --- a/vendor/udx/lib-utility/scripts/src/jquery.ud.dynamic-filter.js +++ /dev/null @@ -1,2351 +0,0 @@ -/** ========================================================= - * jquery.ud.dynamic_filter.js v1.1.4-a2 - * http://usabilitydynamics.com - * ========================================================= - * - * Commercial use requires one-time license fee - * http://usabilitydynamics.com/licenses - * - * Copyright © 2012 Usability Dynamics, Inc. (usabilitydynamics.com) - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Alexandru Marasteanu BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * =TODO= - * - Show More / Show Less are visible when only one option remains, need to decide how to handle - should the filter inputs be visible at all with one option? - * - * - * ========================================================= */ - -/*jslint devel: true, undef: true, browser: true, continue: true, unparam: true, debug: true, eqeq: true, vars: true, white: true, newcap: true, plusplus: true, maxerr: 50, indent: 2 */ -/*global window */ -/*global console */ -/*global clearTimeout */ -/*global setTimeout */ -/*global jQuery */ - -( function ( jQuery ) { - "use strict"; - - jQuery.prototype.dynamic_filter = function ( s ) { - - /** Merge Custom Settings with Defaults */ - this.s = s = jQuery.extend( true, { - ajax: { - args: {}, - async: true, - cache: true, - format: 'json' - }, - active_timers: { - status: {} - }, - attributes: {}, - attribute_defaults: { - label: '', - concatenation_character: ', ', - display: true, - default_filter_label: '', - related_attributes: [], - sortable: false, - filter: false, - filter_always_show: false, - filter_collapsable: 4, /* zero based */ - filter_multi_select: false, - filter_show_count: false, - filter_show_label: true, - filter_note: '', - filter_placeholder: '', - filter_show_disabled_values: false, - filter_range: {}, - filter_ux: [], - filter_value_order: 'native', /* Or 'value_count', or 'label' */ - filter_values: [] - }, - callbacks: { - result_format: function ( result ) { return result; } - }, - data: { - filterable_attributes: {}, - current_filters: {}, - sortable_attributes: {}, - dom_results: {}, - rendered_query: [] - }, - filter_types: { - checkbox: { - filter_show_count: true, - filter_multi_select: true - }, - input: { - filter_always_show: true, - filter_ux: [ { 'autocomplete': {} } ] - }, - dropdown: { - default_filter_label: 'Show All', - filter_show_count: true, - filter_always_show: true - }, - range: { - filter_always_show: true - } - }, - helpers: {}, - instance: {}, - settings: { - auto_request: true, - chesty_puller: false, - debug: false, - dom_limit: 200, - filter_id: jQuery( this ).attr( 'dynamic_filter' ) ? jQuery( this ).attr( 'dynamic_filter' ) : 'df_' + location.host + location.pathname, - load_ahead_multiple: 2, - sort_by: '', - sort_direction: '', - set_url_hashes: true, - per_page: 25, - request_range: {}, - use_instances: true, - timers: { - notice: { - dim: 5000, - hide: 2500 - }, - filter_intent: 1600, - initial_request: 0 - }, - messages: { - no_results: 'No results found.', - show_more: 'Show More', - show_less: 'Show Less', - loading: 'Loading...', - server_fail: 'Could not retrieve results due to a server error, please notify the website administrator.', - total_results: 'There are {1} total results.', - load_more: 'Showing {1} of {2} results. Show {3} more.' - }, - unique_tag: false - }, - classes: { - wrappers: { - ui_debug: 'df_ui_debug', - element: 'df_top_wrapper', - results_wrapper: 'df_results_wrapper', - sorter: 'df_sorter', - results: 'df_results', - filter: 'df_filter', - load_more: 'df_load_more', - status_wrapper: 'df_status_wrapper' - }, - inputs: { - input: 'df_input', - checkbox: 'df_checkbox', - start_range: 'df_start_range', - end_range: 'df_end_range', - range_slider: 'df_range_slider' - }, - labels: { - range_slider: 'df_range_slider_label', - attribute: 'df_attribute_label', - checkbox: 'df_checkbox' - }, - status: { - success: 'df_alert_success', - error: 'df_alert_error' - }, - results: { - row: 'df_result_row', - result_data: 'df_result_data', - list_item: 'df_list_item' - }, - element: { - ajax_loading: 'df_ajax_loading', - filter_pending: 'df_filter_pending', - server_fail: 'df_server_fail', - have_results: 'df_have_results' - }, - filter: { - inputs_list_wrapper: 'df_filter_inputs_list_wrapper', - inputs_list: 'df_filter_inputs_list', - value_wrapper: 'df_filter_value_wrapper', - value_label: 'df_filter_value_label', - value_title: 'df_filter_title', - value_count: 'df_filter_value_count', - trigger: 'df_filter_trigger', - filter_label: 'df_filter_label', - filter_note: 'df_filter_note', - show_more: 'df_filter_toggle_list df_show_more', - show_less: 'df_filter_toggle_list df_show_less', - selected: 'df_filter_selected', - extended_option: 'df_extended_option', - currently_extended: 'df_currently_extended' - }, - sorter: { - button: 'df_sortable_button', - button_active: 'df_sortable_active' - }, - close: 'df_close', - separator: 'df_separator', - selected_page: 'df_current', - disabled_item: 'df_disabled_item' - }, - css: { - results: { - hidden_row: ' display: none; ', - visible_row: ' display: block; ' - } - }, - ux: { - element: this, - results_wrapper: jQuery( '
              ' ), - results: jQuery( '
                ' ), - result_item: jQuery( '
              • ' ), - sorter: jQuery( '
                ' ), - sorter_button: jQuery( '
                ' ), - filter: jQuery( '
                ' ), - filter_label: jQuery( '
                ' ), - load_more: jQuery( '
                ' ), - status: jQuery( '
                ' ) - }, - status: {}, - supported: { - isotope: typeof jQuery.prototype.isotope === 'function' ? true : false, - jquery_ui: typeof jQuery.ui === 'object' ? true : false, - jquery_widget: typeof jQuery.widget === 'function' ? true : false, - jquery_position: typeof jQuery.ui.position === 'object' ? true : false, - autocomplete: typeof jQuery.ui === 'object' && typeof jQuery.widget === 'function' && typeof jQuery.ui.position === 'object' && typeof jQuery.prototype.autocomplete === 'function' ? true : false, - date_selector: typeof jQuery.prototype.date_selector === 'function' ? true : false, - slider: typeof jQuery.prototype.slider === 'function' ? true : false, - //cookies: typeof jaaulde === 'object' && jaaulde.utils.cookies.test() ? true : false, - window_history: typeof history === 'object' && typeof history.pushState === 'function' ? true : false - } - }, s ); - - - /** - * Return Log - * - * @since 0.1 - * @author potanin@UD - */ - var get_log = this.get_log = function ( type, console_type ) { - - type = typeof type != 'undefind' ? type : false; - console_type = typeof console_type != 'undefind' ? console_type : false; - - if( typeof s.log_history === 'object' ) { - jQuery.each( s.log_history, function( index, entry_data ) { - - if( type && type != entry_data.type ) { - return; - } - - log( entry_data.notice, entry_data.type, entry_data.console_type, true ); - }); - - } - - } - - - /** - * Internal logging function - * - * @since 0.1 - * @author potanin@UD - */ - var log = this.log = function ( notice, type, console_type, override_debug ) { - - /** Defaults */ - type = typeof type !== 'undefined' ? type : 'log'; - console_type = console_type ? console_type : 'log'; - - /** Save entry to log */ - s.log_history.push( { notice: notice, type: type, console_type: console_type } ); - - /** Add Prefix */ - notice = ( typeof notice === 'string' || typeof notice === 'number' ? 'DF::' + notice : notice ); - - /** If debugging is disabled, or the current browser does not support it, do nothing */ - if ( !override_debug && ( !s.settings.debug || !window.console ) ) { - return notice; - } - - /** Check if this log type should be displayed */ - if( !override_debug && typeof s.debug_detail === 'object' && !s.debug_detail[ type ] ) { - return notice; - } - - if ( window.console && console.debug ) { - - switch ( console_type ) { - - case 'error': - console.error( notice ); - break; - - case 'info': - console.info( notice ); - break; - - case 'time': - if( typeof console.time != 'undefined' ) { console.time( notice ); } - break; - - case 'timeEnd': - if( typeof console.timeEnd != 'undefined' ) { console.timeEnd( notice ); } - break; - - case 'debug': - if( typeof console.debug != 'undefined' ) { console.debug( notice ); } else { console.log( notice ); } - break; - - case 'dir': - if( typeof console.dir != 'undefined' ) { console.dir( notice ); } else { console.log( notice ); } - break; - - case 'warn': - if( typeof console.warn != 'undefined' ) { console.warn( notice ); } else { console.log( notice ); } - break; - - case 'clear': - if( typeof console.clear != 'undefined' ) { console.clear(); } - break; - - case 'log': - console.log( notice ); - break; - - } - - } - - if( notice ) { - return notice; - } - - }; - - - /** - * Create the main status bar container or add a message to it - * - * !todo Verify that data-dismiss will work with custom classes. - potanin@UD (4/4/12) - * @since 0.1 - * @author potanin@UD - */ - var status = this.status = function ( message, this_status ) { - - /** Set Settings */ - this_status = jQuery.extend( true, { - element: s.ux.status, - type: 'default', - message: message, - hide: s.settings.timers.notice.hide - }, this_status ); - - log( 'status( ' + message + ' ), type: ' + this_status.type, 'status', 'log' ); - - /** Status is added to DOM in render_ui, if it is not visible at this point, it was disabled completely */ - jQuery( s.ux.status ).show().addClass( s.classes.status_wrapper ); - - if( message === '' ) { - jQuery( s.ux.status ).html( '' ); - jQuery( s.ux.status ).hide(); - } - - /** Save original classes, if they are not yet saved */ - if( !jQuery( s.ux.status ).data( 'original_classes' ) ) { - jQuery( s.ux.status ).data( 'original_classes' , jQuery( s.ux.status ).attr( 'class' ) ); - } - - /** Set classes to original ( to clear out any new classes added previously by this function */ - jQuery( s.ux.status ).attr( 'class' , jQuery( s.ux.status ).data( 'original_classes' ) ); - - /** Remove any old timers */ - clearTimeout( s.active_timers.status.hide ); - - /** Add a custom class if passeed */ - if( typeof s.classes.status[ this_status.type ] === 'string' ) { - jQuery( s.ux.status ).addClass( s.classes.status[ this_status.type ] ); - } - - s.ux.status.html( message ); - - /** If Trigger callback is set, we call it, otherwise bind Dismiss action */ - if( typeof this_status.click_trigger != 'undefined' ) { - jQuery( s.ux.status ).one( 'click', function() { - jQuery( document ).trigger( this_status.click_trigger, {} ); - }); - - } else { - - if( typeof jQuery.prototype.alert === 'function' ) { - jQuery( s.ux.status ).prepend( jQuery( '×' ) ); - jQuery( s.ux.status ).alert(); - } - - } - - /** Schedule removal */ - if ( this_status.hide ) { - s.active_timers.status.hide = setTimeout( function () { - jQuery( s.ux.status ).fadeTo( 3000, 0, function () { - jQuery( s.ux.status ).hide(); - }); - }, this_status.hide ); - } - - if( this_status.type === 'error' ) { - jQuery( document ).trigger( 'dynamic_filter::error_status', this_status ); - } - - }; - - - /** - * Automates configuration, restores a saved DF state for the current user. - * - * Attempt to restore any user-specific configuration for this filter - * - * !todo URL hash checking. - potanin@UD - * !todo URL $_GET variable checking. - potanin@UD - * @author potanin@UD - */ - var prepare_system = this.prepare_system = function ( event, args ) { - - /** Debug can be passed as an object configuring what type of information to log in the console */ - s.debug_detail = jQuery.extend( true, { - ajax_detail: false, - attribute_detail: true, - detail: true, - dom_detail: false, - event_handlers: true, - filter_ux: true, - filter_detail: true, - helpers: false, - instance_detail: true, - log: true, - procedurals: true, - status: false, - supported: true, - timers: true, - ui_debug: false - }, ( typeof s.settings.debug === 'object' ? s.settings.debug : {} ) ); - - /** Create Log History */ - s.log_history = []; - - /** First Log Entry */ - log( 'prepare_system', 'procedurals' ); - - /** Log found third-party libraries */ - jQuery.each( s.supported, function( library, is_used ) { - is_used ? log( 'Support for (' + library + ') verified.', 'supported', 'info' ) : false ; - }); - - /** Save Placeholder Results (any content within the UX Element */ - if( jQuery( s.ux.element ).children().length ) { - s.ux.placeholder_results = jQuery( s.ux.element ).children(); - } - - /** If Chesty is with us, we call him */ - if( s.settings.chesty_puller && typeof jQuery.prototype.animate === 'function' ) { - chesty_puller(); - } - - } - - - /** - * Analyze the specified attributes, must be run before AJAX request. - * - * Builds array of filtertable attributes, which are necessary for server-driven ajax calls. - * - * !todo Need to check that the requested Filter is defined before merging settings - potanin@UD (4/4/12) - * @author potanin@UD - */ - var analyze_attributes = this.analyze_attributes = function ( attribute ) { - log( 'analyze_attributes', 'procedurals' ); - - jQuery( document ).trigger( 'dynamic_filter::analyze_attributes::initialize' ); - - if( typeof s.ajax.args === 'undefined' ) { - s.ajax.args = {}; - } - - /* Convert strings to booleans in Attribute Deftauls */ - jQuery.each( s.attribute_defaults , function( key, value ) { - s.attribute_defaults[ key ] = value === 'true' ? true : ( value === 'false' ? false : value ) ; - }); - - s.ajax.args.attributes = s.ajax.args.attributes ? s.ajax.args.attributes : {}; - s.ajax.args.filter_query = s.ajax.args.filter_query ? s.ajax.args.filter_query : {}; - - - /** - * Analyze Single Attribute - * - */ - analyze_attributes.add_ux_support = function( attribute_key, ux_type, ux_settings ) { - log( 'analyze_attributes.add_ux_support(' + attribute_key + ')', 'procedurals' ); - - s.attributes[ attribute_key ].verified_ux = s.attributes[ attribute_key ].verified_ux ? s.attributes[ attribute_key ].verified_ux : {}; - s.attributes[ attribute_key ].verified_ux[ ux_type ] = ux_settings ? ux_settings : {}; - - } - - - /** - * Analyze Single Attribute - * - */ - analyze_attributes.analyze_single = function( attribute_key, attribute_settings ) { - log( 'analyze_attributes.analyze(' + attribute_key + ')', 'procedurals' ); - - attribute_settings = attribute_settings ? attribute_settings : s.attributes[ attribute_key ]; - - /* Convert strings to booleans */ - jQuery.each( attribute_settings , function( key, value ) { - attribute_settings[ key ] = value === 'true' ? true : ( value === 'false' ? false : value ) ; - }); - - /** Merge Attribute Settings with defaults */ - s.attributes[ attribute_key ] = jQuery.extend( {} , s.attribute_defaults, s.attributes[ attribute_key ].filter ? s.filter_types[ s.attributes[ attribute_key ].filter ] : {}, attribute_settings ); - - s.attributes[ attribute_key ].verified_ux = {}; - - /** Create AJAX request place for this attribute. */ - s.ajax.args.attributes[ attribute_key ] = s.ajax.args.attributes[ attribute_key ] ? s.ajax.args.attributes[ attribute_key ] : {}; - - /** Create AJAX Args query, removing any unsupported values such as callback functions */ - jQuery.each( s.attributes[ attribute_key ] , function( key, settings ) { - s.ajax.args.attributes[ attribute_key ][ key ] = typeof settings !== 'function' ? settings : 'callback'; - }); - - /** If Sortable */ - if( s.attributes[ attribute_key ].sortable ) { - s.data.sortable_attributes[ attribute_key ] = s.attributes[ attribute_key ]; - } - - /** If this Attribute uses a Filter */ - if( s.attributes[ attribute_key ].filter ) { - - /** Add this attribute to the Filterable Attributes object for quick reference */ - s.data.filterable_attributes[ attribute_key ] = { - filter: s.attributes[ attribute_key ].filter - }; - - /** Create Filter Query location */ - s.ajax.args.filter_query[ attribute_key ] = s.ajax.args.filter_query[ attribute_key ] ? s.ajax.args.filter_query[ attribute_key ] : []; - - /** Check if Filter UX is used, and if library exists */ - - - if( typeof attribute_settings.filter_ux !== 'undefined' ) { - - /** Convert incorrectly passed filter UX from string to object in an array */ - if( typeof attribute_settings.filter_ux === 'string' ) { - var this_filter_ux = new Object; - this_filter_ux[ attribute_settings.filter_ux ] = {}; - attribute_settings.filter_ux = [ this_filter_ux ]; - } - - jQuery.each( attribute_settings.filter_ux ? attribute_settings.filter_ux : [] , function( i, filter_ux ) { - - jQuery.each( filter_ux, function( ux_type, settings ) { - - if( s.supported[ ux_type ] ) { - analyze_attributes.add_ux_support( attribute_key, ux_type, settings ); - } - - if( typeof s.supported[ ux_type ] === 'boolean' && s.supported[ ux_type ] === false ) { - s.helpers.attempt_ud_ux_fetch( ux_type, attribute_key, settings ); - } - - }); - - }); - - } - - } - - } - - jQuery.each( s.attributes, function ( attribute_key , attribute_settings ) { - analyze_attributes.analyze_single( attribute_key, attribute_settings ); - }); - - jQuery( document ).trigger( 'dynamic_filter::analyze_attributes::complete' ); - - }; - - - /** - * Prepare DOM by rendering elements and adding custom classes. Ran once. - * - * @author potanin@UD - */ - var render_ui = this.render_ui = function () { - log( 'render_ui', 'procedurals' ); - - /** If UX elements are passed via selectors, find them, add classeses */ - jQuery.each( s.ux, function( wrapper_slug, object ) { - - /** Check if UX Element was passed as a jQuery selector */ - if( object && typeof object != 'object' ) { - s.ux[ wrapper_slug ] = jQuery( object ); - } - - /** Check if UX element is in DOM */ - if( !jQuery( s.ux[ wrapper_slug ] ).length ) { - log( 'render_ui - s.ux.' + wrapper_slug + ' was passed as a selector. Corresponding DOM element could not be found.', 'misconfiguration', 'error' ); - return; - } - - /** Add standard class */ - jQuery( s.ux[ wrapper_slug ] ).addClass( 'df_element' ); - - /** Add Debug Class */ - jQuery( s.ux.element ).addClass( s.debug_detail.ui_debug ? s.classes.wrappers.ui_debug : '' ); - - /** Add wrapper classes */ - jQuery( s.ux[ wrapper_slug ] ).addClass( s.classes.wrappers[ wrapper_slug ] ); - - }); - - /** The Results Wrapper is rendered automatically */ - if( jQuery( s.ux.results_wrapper ).not( ':visible' ).length ) { - jQuery( s.ux.element ).prepend( s.ux.results_wrapper ); - } - - /** Sorter UI */ - if( jQuery( s.ux.sorter ).not( ':visible' ).length ) { - jQuery( s.ux.element ).prepend( s.ux.sorter ); - } - - /** The Results Container is rendered automatically */ - if( jQuery( s.ux.results ).not( ':visible' ).length ) { - jQuery( s.ux.results_wrapper ).append( s.ux.results ); - } - - /** Append the results DOM element to the wrapper element. This element can be disabled by being set to false. */ - if( s.ux.filter && !jQuery( s.ux.filter, 'body' ).is( ':visible' ) ){ - jQuery( s.ux.element ).prepend( s.ux.filter ); - jQuery( s.ux.filter ).addClass( s.classes.filter ); - } - - /** Show the message container if not already rendered. This element can be disabled by being set to false. */ - if( s.ux.status && !jQuery( s.ux.status ).is( ':visible' ) ) { - jQuery( s.ux.element ).before( s.ux.status ); - jQuery( s.ux.status ).hide(); - } - - /** Append Load More element to wrapper */ - if( s.ux.load_more && !jQuery( s.ux.load_more ).is( ':visible' ) ) { - jQuery( s.ux.results_wrapper ).append( s.ux.load_more ); - - jQuery( s.ux.load_more ).click( function ( event ) { - - /** Disable click until AJAX request is done */ - if( s.status.loading ) { - return; - } - - jQuery( s.ux.load_more ).unbind( 's.ux.load_more' ); - jQuery( document ).trigger( 'dynamic_filter::load_more' ); - - }); - - jQuery( s.ux.load_more ).hide(); - - } - - /** Use Isotype for aesthetics if available */ - if( s.supported.isotope ) { - jQuery( s.ux.results ).isotope({ - itemSelector : '.' + s.classes.results.row - }); - }; - - }; - - - /** - * Draws the User Interface for sorting. - * - * - * @author potanin@UD - */ - var render_sorter_ui = this.render_sorter_ui = function () { - - /** If Sort By is set and it corresponds to an attribute, we force-add Sortable setting to Attribute */ - if( s.settings.sort_by !== '' && typeof s.attributes[ s.settings.sort_by ] === 'object' ) { - s.attributes[ s.settings.sort_by ].sortable = true; - } - - /** Update Sortable Attributes */ - jQuery.each( s.attributes ? s.attributes : {} , function( attribute_key, settings) { - if( s.attributes[ attribute_key ].sortable ) { - s.data.sortable_attributes[ attribute_key ] = s.attributes[ attribute_key ]; - } - }); - - - /** Render each Sort Button and attach Click event */ - jQuery.each( s.data.sortable_attributes ? s.data.sortable_attributes : {} , function( attribute_key, settings ) { - if( !jQuery('div[attribute_key="' + attribute_key + '"]', s.ux.sorter ).length ) { - s.ux.sorter.append( s.ux.sorter[ attribute_key ] = jQuery( s.ux.sorter_button ).clone(false).addClass( s.classes.sorter.button ).attr( 'attribute_key', attribute_key ).attr( 'sort_direction', 'ASC' ).text( settings.label ) ); - jQuery( s.ux.sorter[ attribute_key ] ).click( function( event ) { - s.settings.sort_by = this.getAttribute('attribute_key'); - s.settings.sort_direction = this.getAttribute('sort_direction'); - jQuery( 'div', s.ux.sorter ).removeClass( s.classes.sorter.button_active ); - jQuery( this ).addClass( s.classes.sorter.button_active ); - jQuery( document ).trigger( 'dynamic_filter::execute_filters' ); - }) - } - }); - - } - - - /** - * Renders the filters. Ran once before Filter Values are known. - * - * Creates s.ux_filters - an associative object for associating filtertable attributes with their DOM filter containers. - * - * !todo This does not take into account that Filter Values can be declared with the attribute - potanin@UD (4/5/12) - * @author potanin@UD - */ - var render_filter_ui = this.render_filter_ui = function ( args ) { - log( 'render_filter_ui', 'procedurals'); - jQuery( document ).trigger( 'dynamic_filter::render_filter_ui::initiate' ); - - if( typeof s.data.filters != 'object' ) { - log( 'render_filter_ui - s.data.filters is not an object. Creating initial DOM References for filters.', 'dom_detail' ); - s.data.filters = {} - } - - /** Cycle through each filterable attribute */ - jQuery.each( s.data.filterable_attributes, function ( attribute_key , filter_data ) { - render_single_filter( attribute_key, filter_data, args ); - }); - - jQuery( document ).trigger( 'dynamic_filter::render_filter_ui::complete' ); - - } - - - /** - * Update Filter Values and counts once updated - * - * @author potanin@UD - */ - var update_filters = this.update_filters = function ( args ) { - log( 'update_filters', 'procedurals' ); - jQuery( document ).trigger( 'dynamic_filter::update_filters::initialize' ); - - jQuery.each( s.data.filterable_attributes , function ( attribute_key , filter_data ) { - /** Can happen if server returns a non-existing Current Filter - e.g. if result was cached */ - if( typeof s.attributes[ attribute_key ] === 'undefined' ) { - return; - } - - render_single_filter( attribute_key, filter_data, args ); - - }); - - jQuery( document ).trigger( 'dynamic_filter::update_filters::complete' ); - - } - - - /** - * Render, or update, a Filter Input. - * - * @author potanin@UD - */ - var render_single_filter = this.render_single_filter = function ( attribute_key, filter_data ) { - log( 'render_filter_ui( ' + attribute_key + ', ' + typeof( filter_data ) + ' ) ', 'procedurals' ); - - var attribute = s.attributes[ attribute_key ]; - var filter = s.data.filters[ attribute_key ]; - var keys_to_remove = {}; - var args = {}; - - var change_selection = function( element, action ) { - if( action === 'enable' || !action ) { - element.prop( 'checked', true ).closest( 'li' ).addClass( s.classes.filter.selected ); - } else { - element.prop( 'checked', false ).closest( 'li' ).removeClass( s.classes.filter.selected ); - } - } - - /** Check if Filter UI has not been rendered yet - this is only run once. */ - if( typeof filter === 'undefined' ) { - - args.initial_run = true; - - /** Create UX object of Filter DOM elements and settings that is applicable to all filters */ - filter = { - inputs_list_wrapper: jQuery( '
                ' ), - filter_label: jQuery( s.ux.filter_label ).clone( true ).attr( 'class', s.classes.filter.filter_label ).text( s.attributes[ attribute_key ].label ), - inputs_list: jQuery( '
                  ' ), - show_more: jQuery( '
                  ' + s.settings.messages.show_more + '
                  ' ).hide(), - show_less: jQuery( '
                  ' + s.settings.messages.show_less + '
                  ' ).hide(), - filter_note: jQuery( '
                  ' ).hide(), - items: {}, - triggers: [] - }; - - /** Hide the label if it isn't supposed to be seen */ - if( !s.attributes[ attribute_key ].filter_show_label ) { - filter.filter_label.hide(); - } - - /** Create DOM elements that apply to all Input Types: Inputs List Wrapper, Label, Inputs List and Dynamic Text */ - s.ux.filter.append( filter.inputs_list_wrapper ); - filter.inputs_list_wrapper.append( filter.filter_label ); - filter.inputs_list_wrapper.append( filter.inputs_list ); - filter.inputs_list_wrapper.append( filter.filter_note ); - filter.inputs_list_wrapper.append( filter.show_more ); - filter.inputs_list_wrapper.append( filter.show_less ); - - /** Show Filter Note if it exists */ - if( attribute.filter_note !== '' ) { - filter.filter_note.show(); - } - - /** If no Label is empty, hide the Label element */ - if( attribute.label === '' ) { - filter.filter_label.hide(); - } - - s.data.filters[ attribute_key ] = filter; - - filter.show_more.click( function() { - jQuery( '.' + s.classes.filter.extended_option, filter.inputs_list_wrapper ).show(); - filter.inputs_list_wrapper.toggleClass( s.classes.filter.currently_extended ); - filter.show_more.toggle(); - filter.show_less.toggle(); - }) - - filter.show_less.click( function() { - jQuery( '.' + s.classes.filter.extended_option, filter.inputs_list_wrapper ).hide(); - filter.inputs_list_wrapper.toggleClass( s.classes.filter.currently_extended ); - filter.show_more.toggle(); - filter.show_less.toggle(); - }) - - } /* Initial Filter Run */ - - log({ - 'Attribute Key': attribute_key, - 'Attribute Settings': attribute, - 'Filter Type': attribute.filter, - 'Filter Detail': filter, - 'Verified UX': jQuery.map( attribute.verified_ux ? attribute.verified_ux : {} , function( value, key ) { return key; } ), - 'Filter Items': filter.items - }, 'filter_detail', 'dir' ); - - /** The standard DOM elements have been added - add Input-Type-specific UI */ - switch ( attribute.filter ) { - - /** - * Standard text input box - can be rendered now since not dependent on Filter Values. - * - */ - case 'input': - - if( args.initial_run ) { - - filter.items.single = { - wrapper: jQuery( '
                • ' ), - label: jQuery( '' ), - trigger: jQuery( '' ) - } - - /** Add to DOM */ - jQuery( filter.inputs_list ).append( filter.items.single.wrapper ); - - filter.items.single.wrapper.append( filter.items.single.label ); - filter.items.single.label.append( filter.items.single.trigger ); - - jQuery( filter.items.single.trigger ).unbind( 'keyup' ).keyup( function( event ) { - s.ajax.args.filter_query[ attribute_key ] = filter.items.single.trigger.val(); - jQuery( document ).trigger( 'dynamic_filter::execute_filters' ); - }); - - /** If a value is set in Fitler Query for this attribute, we load it into the Input field */ - if( s.ajax.args.filter_query[ attribute_key ] != '' ) { - filter.items.single.trigger.val( s.ajax.args.filter_query[ attribute_key ] ); - } - - /** Initiated Filter Query */ - filter.items.single.execute_filter = function() { - s.ajax.args.filter_query[ attribute_key ] = filter.items.single.trigger.val(); - jQuery( document ).trigger( 'dynamic_filter::execute_filters' ); - }; - - } - - /** If autocomplete was requested and exists */ - if( attribute.verified_ux.autocomplete ) { - log( 'render_filter_ui() - Adding AutoComplete UX to (' + attribute_key + ').' , 'filter_ux', 'info' ); - - jQuery( filter.items.single.trigger ).unbind( 'keyup' ); - - jQuery( filter.items.single.trigger ).autocomplete({ - appendTo: filter.items.single.wrapper, - source: jQuery.map( attribute.filter_values ? attribute.filter_values : [], function( value, key ) { - return typeof value === 'object' ? value.value : false; - }), - select: function( event, ui ) { - filter.items.single.execute_filter(); - }, - change: function( event, ui ) { - filter.items.single.execute_filter(); - } - }); - - } - - break; - - - /** - * Dropdown values are fully refreshed every time CF changes. - * - * - */ - case 'dropdown': - - if( args.initial_run ) { - - filter.items.single = { - wrapper: jQuery( '
                • ' ), - label: jQuery( '' ), - trigger: jQuery( '' ), - empty_placeholder: jQuery( '' ) - } - - /** Add to DOM */ - jQuery( filter.inputs_list ).append( filter.items.single.wrapper ); - filter.items.single.wrapper.append( filter.items.single.label ); - filter.items.single.label.append( filter.items.single.trigger ); - filter.items.single.trigger.append( filter.items.single.empty_placeholder ); - - jQuery( filter.items.single.trigger ).keyup( function( event ) { - s.ajax.args.filter_query[ attribute_key ] = filter.items.single.trigger.val(); - jQuery( document ).trigger( 'dynamic_filter::execute_filters' ); - }); - - jQuery( filter.items.single.trigger ).unbind( 'change' ).change( function ( event ) { - - filter.items.single.trigger.value = jQuery( ':selected', this ).val(); - - if( jQuery.inArray( filter.items.single.trigger.value, s.ajax.args.filter_query[ attribute_key ] ) === -1 ) { - s.ajax.args.filter_query[ attribute_key ] = [ filter.items.single.trigger.value ]; - } else { - s.ajax.args.filter_query[ attribute_key ] = []; - } - - jQuery( document ).trigger( 'dynamic_filter::execute_filters' ); - - }); - - } - - jQuery( '> option', filter.items.single.trigger ).each( function() { - if( jQuery( this ).attr( 'filter_key' ) ) { - keys_to_remove[ jQuery( this ).attr( 'filter_key' ) ] = jQuery( this ); - } - }); - - /** Cycle through each filter Value - if exist */ - jQuery.each( attribute.filter_values ? attribute.filter_values: [] , function ( index, filter_value ) { - - if( typeof filter_value !== 'object' ) { - return; - } - - delete keys_to_remove[ filter_value.filter_key ]; - - /** Get ' ); - - /** If we want to show the count */ - if( attribute.filter_show_count && filter_value.value_count ) { - filter_value.element.append( ' (' + filter_value.value_count + ')' ); - } - - } else { - /** If we want to show count, here we replace the value */ - if( attribute.filter_show_count ){ - filter_value.element.text( filter_value.element.text().replace( /\(\d+\)$/, '(' + filter_value.value_count + ')' ) ); - } - - } - - /** Insert Option at position in index */ - insert_at( filter.items.single.trigger, filter_value.element, ( index + 1 ) ); - - }); - - /** If a value is set in Fitler Query for this attribute, we load it into the Input field */ - if( s.ajax.args.filter_query[ attribute_key ] != '' && filter.items.single.trigger.val() === '' ) { - filter.items.single.trigger.val( s.ajax.args.filter_query[ attribute_key ] ); - } - - break; - - - /** - * Creates an input field for every returned value and the count. - * - * Should remove all existing filter values once have new site unless filter_show_disabled_values is set to true - */ - case 'checkbox': - - if( args.initial_run ) { - } - - /** Build array of all current inputs for potential later removal */ - jQuery( ' > .' + s.classes.filter.value_wrapper , filter.inputs_list ).each( function() { - if( jQuery( this ).attr( 'filter_key' ) ) { - keys_to_remove[ jQuery( this ).attr( 'filter_key' ) ] = jQuery( this ); - } - }); - - if( attribute.default_filter_label != '' ) { - attribute.filter_values[ 0 ] = { - filter_key: 'show_all', - value: attribute.default_filter_label, - css_class: s.classes.filter.default_filter - }; - } - - /** Cycle through each filter Value - if exist */ - jQuery.each( attribute.filter_values ? attribute.filter_values: [] , function ( index, filter_value ) { - - if( typeof filter_value !== 'object' ) { - return; - } - - index = parseInt( index ); - - var this_element = filter.items[ filter_value.filter_key ] = filter.items[ filter_value.filter_key ] ? filter.items[ filter_value.filter_key ] : {}; - - /** Do not remove this input */ - delete keys_to_remove[ filter_value.filter_key ]; - - filter_value.css_class = filter_value.css_class ? filter_value.css_class : s.classes.filter.value_wrapper; - - /** Look for existing element */ - this_element.wrapper = jQuery( 'li[filter_key="' + filter_value.filter_key + '"]', filter.inputs_list ); - - /** If no wrapper - create and append all elements, otherwise load from this_element */ - if( !this_element.wrapper.length ) { - this_element.wrapper = jQuery( '
                • ' ); - - this_element.label_wrapper = jQuery( '' ); - this_element.trigger = jQuery( '' ); - this_element.label = jQuery( '' + filter_value.value + ' ' ); - this_element.count = jQuery( '' ); - - this_element.label_wrapper.append( this_element.trigger ); - this_element.label_wrapper.append( this_element.label ); - this_element.label_wrapper.append( this_element.count ); - - this_element.wrapper.append( this_element.label_wrapper ); - - }; - - if( filter_value.filter_key !== 'show_all' ) { - filter.triggers.push( this_element.trigger ); - } - - if( typeof attribute.filter_collapsable === 'number' && index > attribute.filter_collapsable ) { - this_element.wrapper.addClass( s.classes.filter.extended_option ); - - //** If Inputs List is already extended, we do not hide "extra" inputs */ - if( !filter.inputs_list_wrapper.hasClass( s.classes.filter.currently_extended ) ) { - this_element.wrapper.addClass( s.classes.filter.extended_option ).hide(); - filter.show_more.show(); - filter.show_less.hide(); - } - - } else { - this_element.wrapper.removeClass( s.classes.filter.extended_option ); - } - - this_element.wrapper.removeClass( s.classes.disabled_item ); - this_element.trigger.prop( 'disabled', false ); - - /** If Value Count has not been created, or is empty */ - if( typeof filter_value.value_count !== 'undefined' || ( typeof filter_value.value_count == 'object' && filter_value.value_count.val() === '' ) ) { - this_element.count.text( ' (' + filter_value.value_count + ') ' ); - } - - if( !attribute.filter_show_count ) { - jQuery( this_element.count ).hide(); - } - - /** Insert at position, increase index by 1 to give space to Default Filter Label */ - insert_at( filter.inputs_list, this_element.wrapper, ( index + 1 ) ); - - jQuery( this_element.trigger ).unbind( 'change' ).change( function () { - - /** Do not allow Show All to be unchecked */ - if( jQuery( this ).val() === 'show_all' && !jQuery( this ).prop( 'checked' ) ) { - change_selection( filter.items[ 'show_all' ].trigger, 'enable' ); - return false; - } - - /** If regular input is checked, uncheck Show All */ - if( jQuery( this ).val() != 'show_all' && jQuery( this ).prop( 'checked' ) ) { - - change_selection( jQuery( this ), 'enable' ); - change_selection( filter.items[ 'show_all' ].trigger, 'disable' ); - - if( jQuery.inArray( this_element.trigger.val(), s.ajax.args.filter_query[ attribute_key ] ) === -1 ) { - s.ajax.args.filter_query[ attribute_key ].push( this_element.trigger.val() ); - } else { - s.ajax.args.filter_query[ attribute_key ] = remove_from_array( this_element.trigger.val() , s.ajax.args.filter_query[ attribute_key ] ); - } - - jQuery( document ).trigger( 'dynamic_filter::execute_filters' ); - - } - - /** If Show All is checked, uncheck all other inputs */ - if( jQuery( this ).val() === 'show_all' && jQuery( this ).prop( 'checked' ) ) { - change_selection( jQuery( this ), 'enable' ); - - jQuery( filter.triggers ).each( function() { - change_selection( jQuery( this ), 'disable' ); - }); - - s.ajax.args.filter_query[ attribute_key ] = []; - - jQuery( document ).trigger( 'dynamic_filter::execute_filters' ); - - } - - }); - - /** If a value is set in Filter Query for this attribute, we load it into the Input field */ - if( jQuery.inArray( filter_value.filter_key, s.ajax.args.filter_query[ attribute_key ] ) !== -1 ) { - change_selection( this_element.trigger, 'enable' ); - } - - }); - - if( jQuery.isEmptyObject( s.ajax.args.filter_query[ attribute_key ] ) && typeof filter.items[ 'show_all' ] === 'object' ) { - change_selection( filter.items[ 'show_all' ].trigger, 'enable' ); - } - - - break; - - - /** - * Builds Range Input (or a slider) based off minimum and maximum Filter Values. - * - */ - case 'range': - - if( args.initial_run ) { - - filter.items.single = { - wrapper: jQuery( '
                • ' ), - label: jQuery( '' ), - min: jQuery( '' ), - max: jQuery( '' ) - } - - /** Add to DOM ( Not properly nested, hack. ) */ - jQuery( filter.inputs_list ).append( filter.items.single.min ); - jQuery( filter.inputs_list ).append( filter.items.single.max ); - - jQuery( filter.items.single.min ).unbind( 'keyup' ).keyup( function( event ) { - s.ajax.args.filter_query[ attribute_key ] = { - min: filter.items.single.min.val(), - max: filter.items.single.max.val() - } - jQuery( document ).trigger( 'dynamic_filter::execute_filters' ); - }); - - jQuery( filter.items.single.max ).unbind( 'keyup' ).keyup( function( event ) { - s.ajax.args.filter_query[ attribute_key ] = { - min: filter.items.single.min.val(), - max: filter.items.single.max.val() - } - jQuery( document ).trigger( 'dynamic_filter::execute_filters' ); - }); - - } - - /** If autocomplete was requested and exists */ - if( attribute.verified_ux.date_selector ) { - log( 'render_filter_ui() - Updating DateSelector UX to (' + attribute_key + ').' , 'filter_ux', 'info' ); - - /** Render full object only once */ - if( typeof filter.items.single.range_selector === 'undefined' ) { - jQuery( filter.items.single.min ).remove(); - jQuery( filter.items.single.max ).remove(); - - jQuery( filter.inputs_list ).append( filter.items.single.date_selector_field = jQuery('
                  ') ); - jQuery( filter.inputs_list ).append( filter.items.single.range_selector = jQuery('
                  ') ); - - filter.items.single.range_selector.date_selector({ - flat: true, - calendars: 2, - position: 'left', - format: 'ymd', - mode: 'range', - onChange: function( range ) { - filter.items.single.date_selector_field.val( typeof range === 'object' ? range.join(' - ') : '' ); - s.ajax.args.filter_query[ attribute_key ] = { min: range[0], max: range[1] } - jQuery( document ).trigger( 'dynamic_filter::execute_filters' ); - } - }); - - jQuery( document ).bind( 'dynamic_filter::get_data', function() { - //filter.items.single.range_selector.hidePicker(); - }); - - filter.items.single.date_selector_field.focus( function() { - //console.log( filter.items.single.range_selector.showPicker() ); - }); - - } - - /** If a value is set in Fitler Query for this attribute, we load it into the Date Selector */ - if( typeof s.ajax.args.filter_query[ attribute_key ] === 'object' ) { - filter.items.single.range_selector.setDate( [ s.ajax.args.filter_query[ attribute_key ].min, s.ajax.args.filter_query[ attribute_key ].max ] ); - } - - } /* end date_selector */ - - - break; - - } - - /** Remove old filter keys */ - jQuery.each( keys_to_remove, function( filter_key ) { - - if( attribute.filter_show_disabled_values ) { - - if( typeof filter.items[ filter_key ] === 'object' && filter.items[ filter_key ].count ) { - filter.items[ filter_key ].wrapper.addClass( s.classes.disabled_item ); - filter.items[ filter_key ].trigger.prop( 'disabled', true ); - filter.items[ filter_key ].count.text( '' ); - } - - } else { - jQuery( this ).remove(); - } - - }); - - - /** Toggle Filter List Wrapper if there are no values - unless it should always be dispalyed */ - if( !attribute.filter_always_show && jQuery.isEmptyObject( attribute.filter_values ) ) { - log( 'render_filter_ui - No Filter Values for ' + attribute_key + ' - hiding input.', 'filter_detail', 'info' ); - filter.inputs_list_wrapper.hide(); - } else { - filter.inputs_list_wrapper.show(); - } - - } - - - /** - * Gets remote data to match the Requested Range and query. - * - * @author potanin@UD - */ - var get_data = this.get_data = function ( event, args ) { - jQuery( document ).trigger( 'dynamic_filter::get_data::initialize', [args] ); - - s.status.loading = true; - - /** Merge defaults with passed args */ - args = jQuery.extend( true, { - silent_fetch: false, - append_results: false - }, args ); - - /** Request counter */ - s.data.get_count = typeof s.data.get_count === 'number' ? ( s.data.get_count + 1 ) : 1; - - /** Set ranges */ - if( !s.settings.request_range.start ) { - s.settings.request_range.start = 0; - } - - if( !s.settings.request_range.end ) { - s.settings.request_range.end = s.settings.dom_limit; - } - - /** Combine defined AJAX args with settings, which include query */ - var ajax_request = jQuery.extend( true, s.ajax.args, s.settings, { - filterable_attributes: s.data.filterable_attributes - }); - - if( !args.silent_fetch ) { - jQuery( document ).trigger( 'dynamic_filter::doing_ajax', { settings: s, args: args, ajax_request: ajax_request } ); - } - - log( ajax_request.filter_query, 'ajax_detail', 'dir' ); - - jQuery.ajax({ - dataType: s.ajax.format, - type: 'POST', - cache: s.ajax.cache, - async: s.ajax.async, - url: s.ajax.url, - data: ajax_request, - success: function ( ajax_response, textStatus, jqXHR ) { - log( 'get_data - Have AJAX response.', 'ajax_detail', 'debug' ); - - delete s.status.loading; - - /** Make sure callback returns notice. Apply any filters and callbacks to the s.data.all_results */ - var maybe_ajax_response = s.callbacks.result_format( ajax_response ); - if( maybe_ajax_response && typeof maybe_ajax_response === 'object' ) { - ajax_response = maybe_ajax_response; - } - - log( ajax_response, 'ajax_detail', 'dir' ); - - /** Ensure AJAX Response has proppery formatting */ - if( typeof ajax_response.all_results !== 'object' ) { - log( 'get_data() - AJAX response missing all_results array.', 'log', 'error' ); - return false; - } - - /** BLank out Filter Values */ - jQuery.each( s.attributes , function( attribute_key, attribute_data ) { - s.attributes[ attribute_key ].filter_values = []; - }); - - /** Cycle through Current Filters and copy returned data into s.attributes */ - jQuery.each( ajax_response.current_filters ? ajax_response.current_filters : {} , function( attribute_key, attribute_filters ) { - - if( !s.attributes[ attribute_key ] ) { - return; - } - - if( typeof attribute_filters.min !== 'undefined' && typeof attribute_filters.max !== 'undefined' ) { - s.attributes[ attribute_key ].filter_values = attribute_filters; - } - - /** Cycle through Filters and determine the best key to use ( Value, Label or index count ) */ - jQuery.each( attribute_filters, function( index, data ) { - - /** Must have a filter_key */ - if( typeof data.filter_key === 'undefined' || data.filter_key === null ) { - return; - } - - if( typeof data.value === 'undefined' || data.value == '' || data.value === null ) { - data.value = data.filter_key; - } - - if( !data.value.length ) { - return; - } - - /** Add to Filter Values, leaving 0 index in for default */ - s.attributes[ attribute_key ].filter_values[ ( parseInt( index ) + 1 ) ] = data; - - }); - - }); /* end ajax_response.current_filters */ - - /** Make sure that All Results contains data, or else we fail */ - if( !jQuery.isEmptyObject( ajax_response ) ) { - jQuery( document ).trigger( 'dynamic_filter::get_data::complete', jQuery.extend( args, ajax_response ) ); - - } else { - /** No Results returned - is there a rendered query in history? */ - if( typeof s.data.rendered_query[0] === 'object') { - status( s.settings.messages.no_results , { type: 'error', hide: false, click_trigger: 'dynamic_filter::undo_last_query' }); - - } else { - status( s.settings.messages.no_results , { type: 'error', hide: false, click_trigger: ( s.settings.debug ? 'dynamic_filter::get_data' : '' ) }); - jQuery( document ).trigger( 'dynamic_filter::get_data::fail', args ); - - } - - } - - }, - error: function ( jqXHR, textStatus, errorThrown ) { - status( s.settings.messages.server_fail , { type: 'error', hide: false, click_trigger: ( s.settings.debug ? 'dynamic_filter::get_data' : '' ) }); - jQuery( document ).trigger( 'dynamic_filter::get_data::fail', args ); - - } - }); - - }; - - - /** - * Handles DFRO conversion and inserts DFRO DOM elements into All Results UX - * - * All results inserted at their positions as hidden elements, existing results are not hidden, only moved. - * If a DFRO's Result Count has changed, then we assume that the query has changed since on Load More and Silent Fetch - * the Result Count should stay the same from one request to the next. - * - * @author potanin@UD - */ - var append_dom = this.append_dom = function ( event, args ) { - log( 'append_dom()', 'procedurals' ); - - jQuery( document ).trigger( 'dynamic_filter::append_dom::initialize', args ); - - s.data.all_results = s.data.all_results ? s.data.all_results : []; - - if( !args.append_results ) { - s.data.all_results = []; - } - - /** Remove Placeholder Results */ - if( s.ux.placeholder_results && args.initial_request && s.ux.placeholder_results.length ) { - log( 'Removing Placeholder Results.', 'dom_detail', 'info' ); - jQuery( s.ux.placeholder_results ).remove(); - /* s.helpers.purge( s.ux.placeholder_results ); */ - } - - /** Processes single DFRO's attributes */ - append_dom.process_attributes = function( dfro ) { - - /** Create Attribute Wrapper container */ - dfro.dom.row.append( dfro.dom.attribute_wrapper ); - - /** Cycle through individual attributes in the result row */ - jQuery.each( dfro.attribute_data , function ( attribute_key, attribute_value ) { - - /** Skip if returned attribute has not been defined */ - if( !s.attributes[ attribute_key ] ) { - return; - } - - /** If this attribute has a filter, add the key and value to the Result Row as an argument */ - if( s.attributes[ attribute_key ].filter ) { - dfro.dom.row.attr( attribute_key, attribute_value ); - } - - /** If this Attribute is not displayed, there is nothing else to do */ - if( !s.attributes[ attribute_key ].display ) { - log( 'append_dom.process_attributes - Returned attribute (' + attribute_key +') is defined, but not for display - skipping.', 'attribute_detail', 'info' ); - return; - } - - /** Concatenate array of Attribute Values */ - if( jQuery.isArray( attribute_value ) ) { - log( 'append_dom.process_attributes - Value returned as an array for ' + attribute_key, 'attribute_detail', 'info' ); - attribute_value = attribute_value.join( concatenation_character ); - } - - /** If this attribute has a Render callback, we call it */ - if( typeof s.attributes[ attribute_key ].render_callback == 'function' ) { - log( 'append_dom.process_attributes - Callback function found for ' + attribute_key + '.', 'attribute_detail', 'info' ); - attribute_value = s.attributes[ attribute_key ].render_callback( attribute_value, { data: dfro.attribute_data, dfro: dfro }); - } - - /** Create DOM reference for this attribute in DFRO and append it to Attribute Wrapper */ - dfro.dom.attribute_wrapper.append( dfro.dom.attributes[ attribute_key ] = jQuery( '
                • ' + ( attribute_value !== null ? attribute_value : '' ) + '
                • ' ) ); - - log({ - 'Log Event' : 'Appended dfro.dom.attributes[' + attribute_key + '] attribute.', - 'Attribute Key': attribute_key, - 'Attribute Value': attribute_value, - 'Attribute Value Type': typeof attribute_value, - 'Attribute DOM': dfro.dom.attributes[ attribute_key ] - }, 'attribute_detail', 'dir' ); - - }); /* end of single attribute processing */ - - } /* end append_dom.process_attributes() */ - - var to_remove = jQuery.extend( {}, s.data.dom_results ); - - /** Cycle through All Results and convert raw JSON items into DFROs */ - jQuery.each( args.all_results, function ( result_count, attribute_data ) { - - /** Indeces must be numeric since they establish Result Count (rendered order) */ - if( typeof result_count != 'number' ) { - log( 'append_dom() - Unexpected Data Error! "index" is (' + typeof result_count + '), not a numeric value as expected.', 'log', 'error' ); - return true; - } - - /** If we are appending - then the Result Count is modified based on current results */ - if( args.append_results ) { - result_count = s.data.total_in_dom + result_count; - } - - /** Get the Unique DOM ID for this DFRO */ - var dom_id = 'df_' + ( s.settings.unique_tag ? s.settings.unique_tag : 'row' ) + '_' + ( typeof s.settings.unique_tag === 'string' && typeof attribute_data[ s.settings.unique_tag ] !== 'undefined' ? attribute_data[ s.settings.unique_tag ] : s.helpers.random_string() ); - - delete to_remove[ dom_id ]; - - /* Check if this result is already in DOM */ - if( typeof s.data.dom_results[ dom_id ] === 'object' ) { - log( 'append_dom() - Result #' + dom_id + ' already in DOM - moving to position ' + result_count, 'dom_detail', 'info' ); - insert_at( s.ux.results, s.data.dom_results[ dom_id ].dom.row, result_count ); - s.data.all_results[ result_count ] = s.data.dom_results[ dom_id ]; - return true; - } - - /** Create structure for DFRO, move raw JSON data into attribute_data */ - var dfro = s.data.dom_results[ dom_id ] = s.data.all_results[ result_count ] = jQuery.extend( {}, { - attribute_data: attribute_data, - unique_id: typeof s.settings.unique_tag === 'string' ? attribute_data[ s.settings.unique_tag ] : false, - dom: { - row: s.ux.result_item.clone( false ), - attribute_wrapper: jQuery( '
                    ' ), - attributes: {} - }, - dom_id: dom_id, - result_count: result_count - }); - - jQuery( document ).trigger( 'dynamic_filter::render_data::row_element', dfro ); - - dfro.dom.row.attr( 'id', dom_id ).attr( 'class', s.classes.results.row ).attr( 'df_result_count', result_count ).attr( 'style', s.css.results.hidden_row ); - - log({ - 'Log Event' : 'append_dom() - #' + dfro.dom_id + ' - DOM created.', - 'DOM ID': '#' + dfro.dom_id, - 'Result Count': dfro.result_count, - 'DOM': dfro.dom, - 'Attribute Data': dfro.attribute_data - }, 'attribute_detail', 'dir' ); - - append_dom.process_attributes( dfro ); - - /** Swiftly, silently and deadly append the new DFRO to UX All Results at position */ - if( insert_at( s.ux.results, dfro.dom.row, dfro.result_count ) ) { - log( 'append_dom() - Inserted #' + dfro.dom_id + ' at position ' + dfro.result_count + '.', 'dom_detail', 'info' ); - } else { - log( 'append_dom() - Unable to insert #' + dfro.dom_id + ' at position ' + dfro.result_count + '.', 'dom_detail', 'error' ); - } - - }); /** DFRO has been created and appended */ - - if( !args.append_results ) { - jQuery.each( to_remove ? to_remove : {}, function( dom_id, data ) { - log( 'append_dom() - Removing #' + dom_id + ', no longer in result set.', 'dom_detail', 'info' ); - data.dom.row.remove(); - delete s.data.dom_results[ dom_id ]; - }); - } - - if( s.data.all_results.length > 0 ) { - jQuery( s.ux.element ).addClass( s.classes.element.have_results ); - } else { - jQuery( s.ux.element ).removeClass( s.classes.element.have_results ); - } - - jQuery( document ).trigger( 'dynamic_filter::append_dom::complete', args ); - - /** Count of all possible results based on current query. */ - s.data.total_results = args.total_results ? args.total_results : s.data.all_results.length; - - /** Numeric count of elements in DOM, regardless of visibility status. */ - s.data.total_in_dom = parseInt( s.data.all_results.length ); - - /** Numeric count of additional results, matching current query, that are not in DOM. */ - s.data.more_available_on_server = s.data.total_results - s.data.total_in_dom; - - return args; - - } - - - /** - * Visually render DFROs. - * - * @author potanin@UD - */ - var render_data = this.render_data = function ( event, args ) { - log( 'render_data()', 'procedurals' ); - - jQuery( document ).trigger( 'dynamic_filter::render_data::initialize', args ); - - /** Set default visible range */ - if( !s.settings.visible_range ) { - s.settings.visible_range = { - start: 0, - end: s.settings.per_page ? s.settings.per_page : 25 - } - } - - /** Numeric count of the currently visible results based on s.settings.visible_range (does not take into account remainders) */ - s.data.now_visible = parseInt( s.settings.visible_range.end ) - parseInt( s.settings.visible_range.start ); - - /** Numeric count of available results that are in DOM, but are not visible. */ - s.data.more_available_in_dom = parseInt( s.data.total_in_dom ) - parseInt( s.data.now_visible ); - - /** Numeric count of the number of results that are expected to be rendered when "Load More" is pressed, regardless of if a server call will be necesary*/ - s.data.next_batch = ( s.data.total_results - s.settings.visible_range.end ) < s.settings.per_page ? ( s.data.total_results - s.settings.visible_range.end ) : s.settings.per_page; - - log({ - 'Total In DOM': s.data.total_in_dom, - 's.data.all_results.length': s.data.all_results.length, - 'Now Visible': s.data.now_visible, - 'Next Batch': s.data.next_batch, - 'Per Page': s.settings.per_page, - 'More Available in DOM': s.data.more_available_in_dom, - 'More Available on Server': s.data.more_available_on_server, - 'Total Results': s.data.total_results - }, 'dom_detail', 'dir' ); - - /** Use Isotope to render results */ - if( s.supported.isotope ) { - - /** Show current row if it is within the Visible Range */ - if( s.settings.visible_range.start <= index && index < s.settings.visible_range.end ) { - s.ux.results.isotope( 'insert', result.dom.row.row ); - } else { - result.dom.row.show(); - } - - /** {missing description} */ - if( s.supported.isotope ) { - s.ux.results.isotope( 'destroy' ).isotope({ - itemSelector : '.' + s.classes.results.row + ':visible' - }); - } - - } else { - - /** Cycle through the All Results array, this time simply referencing the DOM Object */ - jQuery.each( s.data.all_results , function ( result_count, result ) { - /** Hide Result Row if it is outside of Visible Range */ - if( s.settings.visible_range.start <= result_count && result_count < s.settings.visible_range.end ) { - log( 'render_data - #' + result.dom_id + ' - Appending to Results, index: (' + result_count + '). Displaying.', 'dom_detail' ); - result.dom.row.attr( 'style', s.css.results.visible_row ); - - } else { - log( 'render_data - #' + result.dom_id + ' - Appending to Results, index: (' + result_count + '). Hiding.', 'dom_detail' ); - result.dom.row.attr( 'style', s.css.results.hidden_row ); - } - - }); - - } - - /** If less results than rendered in first view, no "Load More" button */ - if( s.data.next_batch <= 0 ) { - jQuery( s.ux.load_more ).hide(); - } else { - jQuery( s.ux.load_more ).show(); - jQuery( s.ux.load_more ).html( sprintf( s.settings.messages.load_more , [s.data.now_visible, s.data.total_results, s.data.next_batch] ) ); - - } - - /** Save Rendered Query to history. */ - s.data.rendered_query.unshift( jQuery.extend( true, {}, s.ajax.args.filter_query) ); - - jQuery( document ).trigger( 'dynamic_filter::render_data::complete', s.data ); - - /** Since we have results, we save certain configurations */ - jQuery( document ).trigger( 'dynamic_filter::instance::set', s.data ); - - return true; - - } - - - /** - * Initiated after a filter has been changed, and user intent has been established. - * - * No triggers on purpose since this function can be called very often and rapidly when triggered on keyupresses. - * - * @author potanin@UD - */ - var execute_filters = this.execute_filters = function ( value ) { - - clearTimeout( s.active_timers.filter_intent ); - - jQuery( s.ux.element ).addClass( s.classes.element.filter_pending ); - - s.active_timers.filter_intent = setTimeout( function () { - - /** These Request Range values force a reset of request range in get_data() */ - s.settings.request_range = { - start: 0, - end: /* s.settings.dom_limit */ false - } - - jQuery( document ).trigger( 'dynamic_filter::get_data' ); - - }, s.settings.timers.filter_intent ); - - } - - - /** - * Loads more listings - * - * @author potanin@UD - */ - var load_more = this.load_more = function () { - - /* Update Visible Range */ - s.settings.visible_range.end = s.settings.visible_range.end + s.settings.per_page; - - /* Render the results with the updated Visible Range */ - render_data(); - - /** If next batch requires a server call, make it now */ - if( s.data.total_in_dom <= ( s.data.now_visible + s.data.next_batch ) && parseInt( s.data.more_available_on_server > 0 ) ) { - - log( 'load_more - fetching more results.', 'detail' ); - - /** Update ranges */ - s.settings.request_range = { - start: s.data.total_in_dom, - end: s.data.total_in_dom + ( s.settings.per_page * s.settings.load_ahead_multiple ) - }; - - jQuery( document ).trigger( 'dynamic_filter::get_data', { - silent_fetch: true, - append_results: true - }); - - } - - } - - - /** - * Scrolls the sidebar along with view. - * - * Function does not check if .animate exists, so must be checked before this is called. - * - * !todo Bugs out in IE7 when used with UserVoice widget. - potanin@UD - * @since 1.0.7 - * @author potanin@UD - */ - var chesty_puller = this.chesty_puller = function ( args ) { - - s.settings.chesty_puller = jQuery.extend( true, { - top_padding: 45, - offset: jQuery( s.ux.filter ).offset() - }, s.settings.chesty_puller ); - - - chesty_puller.move_chesty = function () { - var args = s.settings.chesty_puller; - - if ( jQuery( window ).scrollTop() > args.offset.top ) { - jQuery( s.ux.filter ).stop().animate({ marginTop: jQuery( window ).scrollTop() - args.offset.top + args.top_padding }); - } else { - jQuery( s.ux.filter ).stop().animate({ marginTop: 0 }); - }; - - } - - jQuery( window ).scroll( move_chesty ); - - - } - - - /** - * Serialize an object. Alternative to JSON.stringify() which IE7 does not have. - * - * @author potanin@UD - */ - var serialize_json = function( obj ) { - log( 'serialize_json()', 'helpers' ); - - if( typeof JSON === 'object' && typeof JSON.stringify === 'function' ) { - return JSON.stringify( obj ); - } - - var t = typeof(obj); - if(t != "object" || obj === null) { - if(t === "string") obj = '"' + obj + '"'; - return String(obj); - - } else { - var json = [], arr = (obj && obj.constructor === Array); - - jQuery.each(obj, function(k, v) { - t = typeof(v); - if(t === "string") v = '"' + v + '"'; - else if (t === "object" & v !== null) v = serialize_json(v) - json.push((arr ? "" : '"' + k + '":') + String(v)); - }); - - return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}"); - } - } - - - /** - * Replaces values in a string. - * - * For now this is a very basic implementation, only replacing a single instance. - * - * @author potanin@UD - */ - var sprintf = function( string, value ) { - log( 'sprintf()', 'helpers' ); - - /** Ensure an array */ - if( typeof value != 'array' ){ - var arr = [ value ]; - }else{ - var arr = value; - } - - /** Setup our ret */ - var ret = string; - - /** Loop through the array replacing all the values as we go through */ - for( var x in value ){ - - var pos = parseInt( x ) + 1; - // log( 'Replace::' + x + '::' + pos ); - // log( 'Value::' + value[ x ] ); - ret = ret.replace( '{' + pos + '}', value[ x ] ); - - } - - /** Return */ - return ret; - } - - - /** - * Unserialize a string if it is serialized, or leave be if already an object - * - * !todo Needs to be done so cookie-data can be restored and merged into the settings object. - potanin@UD - * @author potanin@UD - */ - var maybe_unserialize_json = function( string ) { - - if( typeof string === 'object' ) { - return string; - } - - if( typeof JSON === 'object' && typeof JSON.parse === 'function' ) { - return JSON.parse( string ); - } - - /** TO DO: add equivilant to parse */ - - } - - - /** - * Helper: Remove from an array by value - * - * @author potanin@UD - */ - var remove_from_array = this.remove_from_array = function( value, arr ) { - log( 'remove_from_array()', 'helpers' ); - - return jQuery.grep(arr, function(elem, index) { - return elem !== value; - }); - } - - - /** - * Helper: Insert an element at a position - * - * !todo Add logic to ensure that element was inserted at position. - * @author potanin@UD - */ - var insert_at = this.insert_at = function( container, element, index ) { - log( 'insert_at()', 'procedurals' ); - - container = jQuery( container ); - - var size = container.children().size(); - var index = parseInt( index ); - -//console.log( element ); -//console.log( container.html() ); - - /** If the container does not have any children, we insert the element at first position */ - if( index === 0 || !container.children().eq( (index - 1) ).length ) { - container.append( element ); - - } else { - - container.append( element ); - - /** @todo After the element is appended, then we should move it to a position */ - - //container.children().eq( index - 1 ).after( element ); - - } - - return true; - -//console.log( 'Index: ' + index + ', Actual Index: ' + element.index() ); - - } - - - /** - * Meant to be run on initializtion only, otherwise will overwrite our s.history object - * - * URL-parameters overwrite cookie settings when there is a value conflict. - * - * author potanin@UD - */ - s.instance.load = typeof s.instance.load === 'function' ? s.instance.load : function( args ) { - log( 's.instance.load()', 'procedurals' ); - - /** Load Cookie Data */ - if( s.supported.cookies ) { - s.instance.rendered_query = jaaulde.utils.cookies.get( s.settings.filter_id + '_rendered_query' ); - //s.instance.result_range = jaaulde.utils.cookies.get( s.settings.filter_id + '_result_range' ); - s.instance.per_page = jaaulde.utils.cookies.get( s.settings.filter_id + '_per_page' ); - s.instance.sort_by = jaaulde.utils.cookies.get( s.settings.filter_id + '_sort_by' ); - s.instance.sort_direction = jaaulde.utils.cookies.get( s.settings.filter_id + '_sort_direction' ); - } - - /** Ensure Rendered Query is an object before checking URL for data */ - s.instance.rendered_query = s.instance.rendered_query ? s.instance.rendered_query : {}; - - /** Check URL hash for data, if found - append Filter Query and overwrite cookie settings */ - jQuery.each( s.helpers.url_to_object(), function( key, value ) { - - if( jQuery.inArray( key, [ 'sort_by', 'sort_direction', 'per_page' ] ) !== -1 ) { - s.instance[ key ] = value[0]; - } else { - s.instance.rendered_query[ key ] = value; - } - - }); - - //log( s.instance, 'instance_detail', 'dir' ); - - /** Apply Instance Data */ - s.ajax.args.filter_query = jQuery.extend( true, s.ajax.args.filter_query, s.instance.rendered_query ); - s.settings.sort_by = s.instance.sort_by ? s.instance.sort_by : s.settings.sort_by; - s.settings.sort_direction = s.instance.sort_direction ? s.instance.sort_direction : s.settings.sort_direction; - s.settings.per_page = parseInt( s.instance.per_page ? s.instance.per_page : s.settings.per_page ); - - /** Result Rnage (Disabled for now, the URL-stored values are all being placed into Rendered Query, so rules are needed to prevent that */ - if( s.instance.result_range ) { - s.settings.request_range = { - start: s.instance.result_range.split( '-' )[0], - end: s.instance.result_range.split( '-' )[1] - } - log( 's.instance.clear() - Setting Result Range: (' + s.settings.request_range.start + ' - ' + s.settings.request_range.end +').', 'instance_detail' ); - } - - } - - - /** - * Saves current instance. - * - * author potanin@UD - */ - s.instance.set = typeof s.instance.set === 'function' ? s.instance.set : function( key, value ) { - log( 's.instance.set()', 'procedurals' ); - - /** Set Instance Data object */ - s.instance.data = { - cookies: { - rendered_query: s.data.rendered_query ? s.data.rendered_query[0] : '', - sort_direction: s.settings.sort_direction, - per_page: s.settings.per_page, - sort_by: s.settings.sort_by - }, - hash: { - sort_direction: s.settings.sort_direction, - per_page: s.settings.per_page, - sort_by: s.settings.sort_by - }, - window_history: { - rendered_query: s.data.rendered_query ? s.data.rendered_query[0] : '' - } - } - - /** Build URL query from latest Rendered Query */ - jQuery.each( s.data.rendered_query && s.data.rendered_query ? s.data.rendered_query[0] : [], function( k, v ) { - s.instance.data.hash[ k ] = v; - }); - - /** Save Cookie Data stuff */ - if( s.supported.cookies ) { - jQuery.each( s.instance.data.cookies, function( key, value ) { - jQuery.cookies.set( s.settings.filter_id + '_' + key, value ); - }); - } - - /** Update URL location hash tags */ - if( s.settings.set_url_hashes ) { - window.location.hash = s.helpers.object_to_url( s.instance.data.hash ); - } else { - window.location.hash = ''; - } - - if( s.supported.window_history ) { - //history.pushState( s.instance.data.window_history , '' ); - } - - return; - - } - - - /** - * Clear our current instance - * - * author potanin@UD - */ - s.instance.clear = typeof s.instance.clear === 'function' ? s.instance.clear : function( args ) { - - /** Clear out Cookie Data if used */ - if( s.supported.cookies ) { - delete s.instance.cookie_data; - jaaulde.utils.cookies.del( s.settings.filter_id + '_rendered_query' ); - jaaulde.utils.cookies.del( s.settings.filter_id + '_result_range' ); - jaaulde.utils.cookies.del( s.settings.filter_id + '_sort_by' ); - jaaulde.utils.cookies.del( s.settings.filter_id + '_sort_direction' ); - } - - return log( 's.instance.clear() - All Instance data cleared out. ', 'instance_detail' ); - } - - - /** - * Tries to load an external library when it is needed. - * - * @author potanin@UD - */ - s.helpers.attempt_ud_ux_fetch = typeof s.helpers.attempt_ud_ux_fetch === 'function' ? s.helpers.attempt_ud_ux_fetch : function( ux_type, attribute_key, ux_settings ) { - - s.helpers.attempt_ud_ux_fetch.attempted = s.helpers.attempt_ud_ux_fetch.attempted ? s.helpers.attempt_ud_ux_fetch.attempted : {}; - - switch( ux_type ) { - - case 'date_selector': - var script_url =' http://cdn.usabilitydynamics.com/jquery.ud.date_selector.js'; - break; - - default: - /** Callback maybe? */ - break; - - } - - /** If already tried, or unknown, fail */ - if( s.helpers.attempt_ud_ux_fetch.attempted[ ux_type ] || !script_url ) { - return false; - } - - s.helpers.attempt_ud_ux_fetch.fail = function( ux_type, attribute_key ) { - log( 'Library (' + ux_type + ') could not be loaded for: (' + attribute_key + '), but we did try.', 'filter_ux', 'info' ); - } - - s.helpers.attempt_ud_ux_fetch.success = function( ux_type, attribute_key ) { - log( 'Library (' + ux_type + ') loaded automatically from UD. Applying to: (' + attribute_key + '). You are welcome.', 'filter_ux', 'info' ); - analyze_attributes.add_ux_support( attribute_key, ux_type, ux_settings ) - } - - /** Mark this script as attempted */ - s.helpers.attempt_ud_ux_fetch.attempted[ ux_type ] = true; - - jQuery.getScript( 'http://cdn.usabilitydynamics.com/jquery.ud.date_selector.js', function( data, textStatus, jqxhr ) { - if( typeof jQuery.prototype.date_selector === 'function' ) { - s.helpers.attempt_ud_ux_fetch.success( attribute_key, ux_type ); - } else { - s.helpers.attempt_ud_ux_fetch.fail( attribute_key, ux_type ); - } - }).fail(function(jqxhr, settings, exception) { - s.helpers.attempt_ud_ux_fetch.fail( attribute_key, ux_type ); - }); - - } - - - /** - * Convert object to URL string. - * - * @author potanin@UD - */ - s.helpers.object_to_url = typeof s.helpers.object_to_url === 'function' ? s.helpers.object_to_url : function( data ) { - log( 's.helpers.object_to_url()', 'helpers' ); - - /** If an object is not passed, return as if its a string, or blank string of something else */ - if( typeof data !== 'object' ) { - return typeof data === 'string' ? data : ''; - } - - var hash = jQuery.map( data, function( value, key ) { - - if( typeof value === 'string' && value !== '' ) { - value = value; - } else if ( typeof value.join === 'function' ) { - value = value.join( ',' ); - } else if ( typeof value === 'object' ) { - value = jQuery.map( value, function( value, index ) { return value; } ).join( '-' ); - } - - if( value ) { - return key + '=' + value + ''; - } - - }); - - return hash.length ? encodeURI( hash.join( '&' ) ) : ''; - - } - - - /** - * Convert URL string to object. - * - * @author potanin@UD - */ - s.helpers.url_to_object = typeof s.helpers.url_to_object === 'function' ? s.helpers.url_to_object : function( url ) { - log( 's.helpers.url_to_object()', 'helpers' ); - - var hash = url ? url : decodeURI( window.location.hash.replace( '#', '' ) ); - var object = {}; - - jQuery.each( hash.split( '&' ), function( key, value ) { - - if( !value ) { - return; - } - - key = value.split( '=' )[0]; - value = value.split( '=' )[1]; - - if( value.indexOf( '-' ) !== -1 ) { - value = { - min: value.split( '-' )[0], - max: value.split( '-' )[1] - } - } else if ( typeof value === 'string' ) { - value = [ value ]; - } - - object[ key ] = value; - - }) - - return object; - - } - - - /** - * Get Instance Data from URL - * - * @source http://stackoverflow.com/questions/1349404/generate-a-string-of-5-random-characters-in-javascript - * @author potanin@UD - */ - s.helpers.random_string = typeof s.helpers.random_string === 'function' ? s.helpers.random_string : function( string , possible ) { - log( 'random_string()', 'helpers' ); - - string = typeof string === 'string' ? string : ''; - possible = typeof possible === 'string' ? possible : 'abcdefghijklmnopqrstuvwxyz'; - - for( var i=0; i < 10; i++ ) { - string += possible.charAt( Math.floor( Math.random() * possible.length ) ); - } - - return string; - - } - - - /** - * {} - * - * @source http://javascript.crockford.com/memory/leak.html - * @author potanin@UD - */ - s.helpers.purge = typeof s.helpers.purge === 'function' ? s.helpers.purge : function( d ) { - var a = d.attributes, i, l, n; - if (a) { - for (i = a.length - 1; i >= 0; i -= 1) { - n = a[i].name; - if (typeof d[n] === 'function') { - d[n] = null; - } - } - } - a = d.childNodes; - if (a) { - l = a.length; - for (i = 0; i < l; i += 1) { - s.helpers.purge( d.childNodes[i] ); - } - } - } - - - /** - * Enable the script, ran once on initialization - * - * Binds DF events for API access. - * - * @author potanin@UD - */ - var enable = this.enable = function() { - - /** {missing description} */ - jQuery( document ).bind( 'dynamic_filter::doing_ajax', function() { - log( 'doing_ajax' , 'event_handlers' ); - jQuery( s.ux.element ).removeClass( s.classes.element.filter_pending ); - jQuery( s.ux.element ).removeClass( s.classes.element.server_fail ); - jQuery( s.ux.element ).addClass( s.classes.element.ajax_loading ); - }); - - /** {missing description} */ - jQuery( document ).bind( 'dynamic_filter::ajax_complete', function() { - log( 'ajax_complete', 'event_handlers' ); - jQuery( s.ux.element ).removeClass( s.classes.element.ajax_loading ); - }); - - /** {missing description} */ - jQuery( document ).bind( 'dynamic_filter::get_data', function( event, args ) { - log( 'get_data', 'event_handlers' ); - get_data( event, args ); - }); - - /** Called whenever an instance/history related event takes place. */ - jQuery( document ).bind( 'dynamic_filter::instance::set', function() { - s.settings.use_instances ? s.instance.set() : false; - }); - - /** Triggered after AJAX JSON results have been successfully loaded. */ - jQuery( document ).bind( 'dynamic_filter::get_data::complete', function( event, args ) { - log( 'get_data::complete', 'event_handlers' ); - jQuery( document ).trigger( 'dynamic_filter::ajax_complete' , args ); - - append_dom( event, args ) - - if( !args.silent_fetch ) { - render_data( event, args ); - update_filters( event, args ); - } - - }); - - /** {missing description} */ - jQuery( document ).bind( 'dynamic_filter::get_data::fail', function() { - jQuery( document ).trigger( 'dynamic_filter::ajax_complete' ); - jQuery( s.ux.element ).addClass( s.classes.element.server_fail ); - }); - - /** {missing description} */ - jQuery( document ).bind( 'dynamic_filter::undo_last_query', function() { - log( 'undo_last_query', 'event_handlers' ); - jQuery( s.ux.element ).removeClass( s.classes.element.server_fail ); - jQuery( s.ux.element ).removeClass( s.classes.element.ajax_loading ); - status( '' ); - }); - - /** Call to display results based on... ? */ - jQuery( document ).bind( 'dynamic_filter::render_data', function() { - log( 'render_data', 'event_handlers' ); - render_data(); - }); - - /** {missing description} */ - jQuery( document ).bind( 'dynamic_filter::render_data::complete', function() { - log( 'render_data::complete', 'event_handlers' ); - }); - - /** {missing description} */ - jQuery( document ).bind( 'dynamic_filter::execute_filters', function() { - log( 'execute_filters', 'event_handlers' ); - execute_filters(); - }); - - /** {missing description} */ - jQuery( document ).bind( 'dynamic_filter::update_filters::complete', function() { - log( 'update_filters::complete', 'event_handlers' ); - }); - - /** {missing description} */ - jQuery( document ).bind( 'dynamic_filter::load_more', function() { - log( 'load_more', 'event_handlers' ); - load_more(); - }); - - /** Whenever History Entry changes (HTML5 browsers as of now) */ - jQuery( document ).bind( 'dynamic_filter::onpopstate', function( args ) { - log( 'dynamic_filter::onpopstate', 'log', 'info' ); - }); - - /** {missing detail} */ - prepare_system(); - - /** Walyze the passed attributes */ - analyze_attributes(); - - /** Load instance-specific information */ - s.settings.use_instances ? s.instance.load() : false; - - /** Render UI elements (containers) and add custom classes */ - render_ui(); - - /** Render the filters */ - render_filter_ui(); - - /** Render UI for sorting, if enabled */ - render_sorter_ui(); - - /** If Auto Request enable, Get Data, after an optional pause */ - if( s.settings.auto_request ) { - - if( s.settings.timers.initial_request ) { - log( 'Doing Initial Request with a ' + s.settings.timers.initial_request + 'ms pause.', 'log', 'info' ); - } - - setTimeout( function () { jQuery( document ).trigger( 'dynamic_filter::get_data', { initial_request: true } ); }, s.settings.timers.initial_request ); - } - - } /* end enable() */ - - /** If this browser support Pop State, we bind to it */ - window.onpopstate = function( event ) { - jQuery( document ).trigger( 'dynamic_filter::onpopstate', event ); - } - - /** Initialize the script */ - enable(); - - /** Return object for chaining */ - return this; - - }; - -} ( jQuery ) /* p.s. No dog balls. */ ); - - diff --git a/vendor/udx/lib-utility/scripts/src/jquery.ud.elastic_filter.js b/vendor/udx/lib-utility/scripts/src/jquery.ud.elastic_filter.js deleted file mode 100644 index 5771d732a..000000000 --- a/vendor/udx/lib-utility/scripts/src/jquery.ud.elastic_filter.js +++ /dev/null @@ -1,938 +0,0 @@ -/** ========================================================= - * jquery.ud.elastic_filter.js v0.5 - * http://usabilitydynamics.com - * ========================================================= - * - * Commercial use requires one-time license fee - * http://usabilitydynamics.com/licenses - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS".. - * http://usabilitydynamics.com/warranty - * - * Copyright 2012-2013 Usability Dynamics, Inc. (usabilitydynamics.com) - * * - * Console Log Commands - * ==================== - * Last Query: elastic_filter.computed_query(); - * - * ========================================================= */ - -new (function( args ) { - - // Merge Custom Args into Default Args and then into Self - var app = window.ef_app = jQuery.extend( true, this, { - - // Local Settings. - 'settings': { - - 'account_id' : undefined, - - 'access_key' : undefined, - - 'per_page': 10, - - 'debug': false, - - 'visual_debug': false, - - 'url': 'https://cloud.usabilitydynamics.com', - - 'index' : '' - - }, - - // Result Items. - 'documents' : [], - - // Facet Objects. - 'facets' : [], - - // Available Sorting Types - 'sort_options': [], - - // Defaults from CloudAPI - 'defaults' : null, - - // Overall App State - 'state' : 'loading', - - // Query Object - 'query' : { - - // Full Text Search - 'full_text': null, - - // Single Field Search(es) - 'field' : [], - - // Multiple Term Search(es) - 'terms' : [], - - // Range Search(es) - 'range' : [], - - // Fuzzy Term / Date / Number Search(es) - 'fuzzy' : [], - - // Start Result - 'from' : 0 - - }, - - 'size' : 0, - - // Sort Order - 'sort' : null, - - 'bindings_initialized': [], - - // Total available results. Integer - 'total' : null, - - // General Status Message. String. - 'message' : '', - - // Set to true once fully loaded - 'elastic_ready': false, - - // Socket Session ID - 'session_id' : null, - - // Global Variable for Data Storage - 'global' : window.__elastic_filter = {}, - - // Initialization Complete - 'ready' : function() {}, - - // Required Assets - '_required' : { - 'io' : '//ud-cdn.com/js/ud.socket/1.0.0/ud.socket.js', - 'ko.mapping' : '//ud-cdn.com/js/knockout.mapping/2.3.2/knockout.mapping.js', - 'async' : '//ud-cdn.com/js/async/1.0/async.js', - 'ud.ko' : '//ud-cdn.com/js/knockout.ud/1.0/knockout.ud.js', - 'ud.select' : '//ud-cdn.com/js/ud.select/3.2/ud.select.js', - 'jq-lazyload': '//ud-cdn.com/js/jquery.lazyload/1.8.2/jquery.lazyload.js' - }, - - // Application Event Log - '_log' : { - - // Active Socket Subscriptions - 'subscriptions': {}, - - // Search History - 'search' : [], - - // Debug History - 'debug' : [], - - // Active Profilers - 'profilers' : {} - - } - - }, args ); - - /** - * Document constructor. Use to normalize incoming object. - */ - app._document = function( item ) {return item;}; - - /** - * Facet constructor. Use to normalize incoming object. - */ - app._facet = function( item, title ) { - - var options = []; - for( var i in item.terms ) { - options.push( { - 'text' : item.terms[i].term, - 'id': item.terms[i].term - }); - } - item._label = title; - - // Objervable dropdown options - item.options = ko.observableArray( options ); - - // Observable value - item.value = ko.observable(); - - // Observable multiple options - item.select_multiple = ko.observableArray(); - - // Build Terms Query based on Facet Selections - item.select_multiple.subscribe( function( value ) { - - // Organize terms inside query - app.view_model.query.terms.remove( - ko.utils.arrayFirst( app.view_model.query.terms(), function( term ) { - return typeof term[title] != 'undefined'; - } ) - ); - - if( value.length ) { - var object = {}; - object[title] = value; - app.view_model.query.terms.push( object ); - } - - // Set default size - app.view_model.size( parseInt( app.view_model.settings.per_page() ) ); - - // Do request - app.search_request(); - - } ); - - // Add CSS class for wrapper of facet to be able to manage its appearence in different states - item.css_class = ko.computed(function(){ - var len = typeof item.options() !== 'undefined' ? item.options().length : 0; - var len_class = len == 1 ? 'eff_single_option' : (!len ? 'eff_no_options': 'eff_options_'+len); - return len_class+' ef_facet_'+title.replace(' ','_'); - }); - - return item; - }; - - /** - * Profiler. A note is required to output. - * - * @version 0.1.1 - * @updated 0.1.5 - */ - app.profile = function( name, note, args ) { - - // If note is set, output timer. - if( app._log.profilers[ name ] && note ) { - - var output = [ 'Profiler', name, note, ( new Date().getTime() - app._log.profilers[ name ] ) / 1000 ]; - - if( args ) { - output.push( args ); - } - - return app.log.apply( this, output ); - } - - // Mark app.profiler as active - app._log.profilers[ name ] = new Date().getTime(); - - return this; - } - - /** - * Internal logging function - * - * @updated 0.4 - * @since 0.1 - */ - app.log = function() { - - if ( typeof console === 'undefined' ) { - return arguments ? arguments : null; - } - - if( arguments[0] instanceof Error ) { - console.error( 'ElasticFilter Fatal Error:', arguments[0].message ); - return arguments; - } - - console.log( arguments ); - - return arguments ? arguments : null; - - }; - - /** - * Debug Logging. Requires debug to be set to true, unless an Error object is passed. - * - * @author potanin@UD - */ - app.debug = function() { - - app._log.debug.push( {'time': new Date().getTime(), 'data': arguments} ); - - return ( ko.utils.unwrapObservable( app.settings.debug ) || arguments[0] instanceof Error ? app.log.apply( this, arguments ) : arguments ); - - } - - /** - * Initial Asynchronous Initialization - * - * @todo Add Meta Mapping and have them return labels - * @author potanin@UD - */ - app.init = function() { - - utils.back_support(); - - app.debug( 'init' ); - - // Make Things Happen. - async.auto( { - - /** - * Verify Dependancies and Create Knockout Bindings for Elastic Filter Elements - */ - 'binding_handlers': [ function( next, report ) { - app.debug( 'init', 'auto', 'binding_handlers' ); - - if( typeof ko !== 'object' ) { - return next( new Error( 'Missing Knockout.' ) ); - } - - if( typeof io !== 'object' ) { - return next( app.debug( new Error( 'Missing Socket.io.' ) ) ); - } - - // Main Configurations. Merges DOM Settings into app.settings - ko.bindingHandlers[ 'elastic-filter' ] = { - - 'init': function( element, valueAccessor ) { - app.log( 'binding_handlers', 'elastic-filter', 'init' ); - ko.mapping.fromJS( {'settings': jQuery.extend( true, {}, app.settings, ko.utils.unwrapObservable( valueAccessor() ) )}, app.view_model ); - app.bindings_initialized.push('elastic-filter'); - } - - } - - /** - * Handler for fulltext search function. Similar to "select" - * - */ - ko.bindingHandlers[ 'fulltext-search' ] = { - - 'init': function( element, valueAccessor, allBindingsAccessor, viewModel, bindingContext ) { - app.debug( 'binding_handlers', 'fulltext-search', 'init' ); - - if( typeof jQuery().select2 == 'undefined' ) return new Error( 'Select2 library is required for Fulltext Search feature' ); - - jQuery( element ).select2(valueAccessor()); - - if ( typeof allBindingsAccessor().elastic_settings != 'undefined' ) - ko.mapping.fromJS( {'settings': allBindingsAccessor().elastic_settings}, app.view_model ); - - ko.utils.domNodeDisposal.addDisposeCallback( element, function() { - jQuery( element ).select2( 'destroy' ); - }); - - app.bindings_initialized.push('fulltext-search'); - } - - }; - - return next( null, [ ko.bindingHandlers ] ); - - }], - - /** - * Create Observables and Computed Functions - * - */ - 'observable': [ 'binding_handlers', function( next, report ) { - app.debug( 'init', 'auto', 'observable' ); - - // Create Initial JSON Object from App, and Extend Template Functions into Root - app.view_model = ko.mapping.fromJS( app, { - - 'ignore': utils.get_methods( app ).concat( '_log', '_required', 'model_functions', 'facet_functions', 'document_functions', 'utils', 'success', 'global' ) - - }); - - /*app.view_model.query.full_text.subscribe(function(value){ - app.search_request(); - });*/ - - // Execute Binding Magic - ko.applyBindings( app.view_model ); - - // Expand Additional Template Functions into View Model - jQuery.extend( true, app.view_model, app.facet_functions, app.document_functions ); - - // Always a success. - return next( null, app ); - - }], - - /** - * Initialize Socket Connection - * - */ - 'socket': [ 'observable', function( next ) { - app.debug( 'init', 'auto', 'socket' ); - - if ( !app.bindings_initialized.length ) return; - - if ( typeof app.view_model.settings[ 'account_id' ] == 'undefined' || - typeof app.view_model.settings[ 'access_key' ] == 'undefined' ) { - return next( new Error('Empty credentials.') ); - } - - ud.socket.connect( ko.utils.unwrapObservable( app.view_model.settings[ 'url' ] ), { - 'resource': 'websocket.api/1.5', - 'account-id': ko.utils.unwrapObservable( app.view_model.settings[ 'account_id' ] ), - 'access-key': ko.utils.unwrapObservable( app.view_model.settings[ 'access_key' ] ) - }, function( error, socket ) { - - app.socket = socket; - - // Break initializtion chain since a WebSocket connection is required - if( error ) { - return next( error ); - } - - app.socket.once( 'reconnect', function() { - app.debug( new Error( 'Reconnecting, re-initializing ElasticFilter.' ). arguments ); - app.init(); - }); - - app.view_model.session_id( app.socket.sessionid ); - - return next( null, app.socket ); - - }); - - }], - - /** - * Load Settings and setup Defaults. Settings request could also be filtered via { 'path': 'defaults' } - * - */ - 'settings': [ 'socket', function( next, report ) { - app.debug( 'init', 'auto', 'settings' ); - - app.socket.request( 'get', 'api/v1/settings', function( error, response ) { - - app.log('settings', response); - - if( error || !response ) { - return next( app.log( error || new Error( 'Request for index settings returned no results.' ) ) ); - } - - ko.mapping.fromJS({'settings': response.settings}, app.view_model ); - - app.ready(); - - return next( null, app.settings ); - - }); - - }], - - /** - * Fully Loaded, make initial request - * - */ - 'ready': [ 'settings', function( next, report ) { - app.debug( 'init', 'auto', 'ready', report ); - - // Make Default Search Requests - app.view_model.sort( ko.mapping.toJS( app.view_model.settings.defaults.sort ) ); - app.view_model.size( parseInt( app.view_model.settings.per_page() ) ); - - // Do this only if elastic-filter binding exists on the page - if( app.bindings_initialized.indexOf( 'elastic-filter' ) !== -1 ) { - app.search_request(); - } - - // Fully loaded. - app.view_model.elastic_ready( true ); - - next( null, app.view_model.elastic_ready() ); - - }] - - }, app.initialized ); - - return this; - - } - - /** - * Execute Search Request. Gets value from computed_query observable - * - * @since 0.1.5 - */ - app.search_request = function( callback ) { - - app.profile( 'search_request' ); - - var request = { - index : app.view_model.settings.index(), - query : jQuery.extend( true, {'match_all': {}}, ko.mapping.toJS( app.view_model.query ) ), - facets : ko.mapping.toJS( app.view_model.settings.facets ), - size : app.view_model.size(), - sort : app.view_model.sort() - } - - request = utils.clean_object( request ); - - /** Temp logger */ - app.computed_query = function() { - return request; - } - - app.log( 'search_request_data', 'Data Before Send', request ); - - app.view_model.state( 'loading' ); - - app.socket.request( 'post', 'api/v1/search', request, function( error, response ) { - - /** Temp logger */ - app.last_response = function() { - return response; - } - - //** Profiling */ - app.profile( 'search_request', 'Have Cloud Response.', response ); - app.profile( 'search_request', 'Request Mapping Start.' ); - - var documents = []; - jQuery.each(typeof response.documents !== 'undefined' ? response.documents : [], function(){ - documents.push(arguments[1]); - }); - - app.view_model.documents( ko.utils.arrayMap( documents, function( item ) { - return new app._document( item ); - })); - - for( var i in typeof response.meta.facets != 'undefined' ? response.meta.facets : {} ) { - var found = false; - - ko.utils.arrayForEach( app.view_model.facets(), function( existing_facet ) { - if( i == existing_facet._label ) { - //existing_facet.options( item.options ); - found = true; - } - }); - - if( !found ) { - app.view_model.facets.push( new app._facet( response.meta.facets[i], i ) ); - } - } - - app.view_model.total( typeof response.meta.total != 'undefined' ? response.meta.total : 0 ); - app.view_model.state( 'ready' ); - - //** Profiling */ - app.profile( 'search_request', 'Request Mapping Complete.' ); - - return typeof callback === 'function' ? callback( error, response ) : response; - - }); - - }; - - /** - * Custom search requester. - */ - app.custom_search = function( callback ) { - app.profile( 'custom_search_start' ); - - var request = { - index : app.view_model.settings.index(), - query : { "query_string": { "query": app.view_model.query.full_text() } }, - size : app.view_model.size(), - sort : app.view_model.sort() - } - - app.socket.request( 'post', 'api/v1/search', request, callback ); - - app.profile( 'custom_search_end' ); - - return true; - } - - /** - * Get JSON Output of full View Model - * - * @since 0.1.5 - */ - app.get_json = function() { - return JSON.parse( ko.mapping.toJSON( app.view_model ) ); - }; - - /** - * Post Initialization - * - */ - app.initialized = function( error, report ) { - app.debug( 'initialized', arguments ); - - app.initialization = app.log( error ? 'Initializaiton Failed.' : 'Initializaiton Done.', ( report ? report : error ) ); - - if( typeof app.ready === 'function' ) { - app.ready( app, error, report ); - } - - return app.initialization; - - }; - - /** - * Facet Functions - * - */ - app.facet_functions = { - - /** - * Single Facet Rendered in DOM - * - * @event afterRender - */ - 'facet_after_render': function( data ) { - }, - - /** - * Before Single Facet is Removed from DOM - * - * @event beforeRemove - */ - 'facet_before_remove': function( element ) { // app.debug( 'facet_functions', 'facet_before_remove' ); - ko.removeNode( element ); - }, - - /** - * After a Single Facet is Added to DOM - * - * @event afterAdd - */ - 'facet_after_add': function( element, something, object ) { - }, - - /** - * Get Best Template for Facet - * - * @todo Use .notifySubscribers() to trigger request() - */ - 'facet_template': function( facet ) { // app.debug( 'facet_functions', 'facet_template' ); - - var templates = []; - - // Add Possible Templates - switch( facet && facet._type ) { - - case 'terms': - templates.push( 'template-facet-terms' ); - break; - - } - - // Default Facet Template - templates.push( 'template-default-facet' ); - - return app.model_functions._get_template( templates ); - - }, - - /** - * Submit Search - */ - 'submit_facets': function( data, event ) { - app.debug( 'facet_functions', 'submit_facets' ); - app.view_model.size( parseInt( app.view_model.settings.per_page() ) ); - app.search_request(); - return; - } - - }; - - /** - * Document Functions - * - */ - app.document_functions = { - - /** - * Single Document Rendered in DOM - * - * @event afterRender - */ - 'document_after_render': function( data, object ) { - }, - - /** - * Before Single Document is Removed from DOM - * - * @event beforeRemove - */ - 'document_before_remove': function( element, something, object ) { // app.debug( 'document_functions', 'document_before_remove' ); - ko.removeNode( element ); - }, - - /** - * After a Single Document is Added to DOM - * - * @event afterAdd - */ - 'document_after_add': function( element, something, object ) { - }, - - /** - * Get Best Template for Document - * - */ - 'document_template': function( document ) { // app.debug( 'document_functions', 'document_template' ); - return app.model_functions._get_template( ['template-default-document' ] ); - }, - - /** - * Toggle Sort Option - */ - 'sort_by': function( data, event ) { - app.debug( 'document_functions', 'sort' ); - - jQuery( event.target ).trigger( 'sort', [data] ); - - var field = jQuery( event.target ).data( 'field' ); - - var sort = ko.utils.arrayFirst( data.sort_options, function( option ) { - return typeof option[field] != 'undefined'; - } ); - - if( app.view_model.sort() ) { - var existing_sort = typeof app.view_model.sort()[field] != 'undefined' ? app.view_model.sort()[field] : false; - if( existing_sort ) - sort[field].order = app.view_model.sort()[field].order == 'desc' ? 'asc' : 'desc'; - } - - app.view_model.sort( sort ); - app.view_model.size( parseInt( app.view_model.settings.per_page() ) ); - app.search_request(); - }, - - /** - * Determine if sort type is active by sort - */ - 'is_active_sort': function( data ) { - if( !app.view_model.sort() ) return 'disabled'; - return typeof app.view_model.sort()[data] != 'undefined' ? 'active' : 'disabled'; - }, - - /** - * If there are more results available - */ - 'have_more': function( data, event ) { - app.debug( 'document_functions', 'have_more()' ); - - // Create Obervable if it has not been created yet. - app.have_more = ko.computed( { - 'owner': this, - 'read' : function() { - return ( app.view_model.total() > app.view_model.documents().length ) ? true : false; - } - } ); - - return app.have_more(); - - }, - - /** - * Load More - * - */ - 'load_more': function( data, event ) { - app.debug( 'document_functions', 'load_more()' ); - app.view_model.size( parseInt( app.view_model.size() ) + parseInt( app.view_model.settings.per_page() ) ); - app.search_request(); - } - - }; - - /** - * Template Functions, expanded into _view_model - * - */ - app.model_functions = { - - /** - * Accepts an array of Knockout template IDs, and returns first one that exists in document - * - */ - '_get_template': function( templates ) { // app.debug( 'model_functions', '_get_template' ); - - for( i in templates ? templates : [] ) { - if( document.getElementById( templates[i] ) ) { - return templates[i]; - } - } - - return templates[0]; - - }, - - /** - * Delete a Document by ID (Could be triggered by subscribed event) - * - * elastic_filter.observable._documents.remove( function( item ) { item.id = 6552 } ); - * - * @todo Does not work. Perhaps some issues with computation.. - */ - '_remove_item': function( index, id ) { // app.debug( 'model_functions', '_remove_item' ); - - var items = this[ index ]; - - ko.utils.arrayFirst( items, function( item ) { - - if( item && parseInt( item.id ) === parseInt( id ) ) { - items.remove( document ); - ko.utils.arrayRemoveItem( item ); - } - - } ); - - } - - }; - - /** - * Utility Functions - * - * @author potanin@UD - */ - var utils = app.utilis = { - - /** - * Adds Compatibility with Crappy Browsers - * - */ - 'back_support': function() { - - //** IE fix for unsupported methods */ - Object.keys = Object.keys || (function() { - var hasOwnProperty = Object.prototype.hasOwnProperty, hasDontEnumBug = !{toString: null}.propertyIsEnumerable( "toString" ), DontEnums = - [ - 'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', - 'constructor' - ], DontEnumsLength = DontEnums.length; - - return function( o ) { - if( typeof o != "object" && typeof o != "function" || o === null ) { - throw new TypeError( "Object.keys called on a non-object" ); - } - - var result = []; - for( var name in o ) { - if( hasOwnProperty.call( o, name ) ) { - result.push( name ); - } - } - - if( hasDontEnumBug ) { - for( var i = 0; i < DontEnumsLength; i++ ) { - if( hasOwnProperty.call( o, DontEnums[i] ) ) { - result.push( DontEnums[i] ); - } - } - } - - return result; - }; - })(); - - }, - - /** - * I know they are not technically methods. - * - * @version 0.1.1 - * @author potanin@UD - */ - 'get_methods': function( object ) { - - var functions = jQuery.map( object, function( item, name ) { - if( typeof item === 'function' ) { - return name; - } - } ); - - return functions; - - }, - - /** - * Load Inline JSON Editor (Needs CSS Fixes and some Logic Fixes to be useful) - * - * @version 0.1.1 - * @author potanin@UD - */ - 'json_editor': function() { - - ud.load.js( {'JSONEditor': 'http://ud-cdn.com/js/ud.json.editor.js'}, function() { - - ud.load.css( 'http://ud-cdn.com/js/assets/ud.json.editor.css' ); - - app.json_editor = new JSONEditor( jQuery( '.elastic_json_editor' ).get( 0 ), { - 'indentation': 2, - 'search' : false, - 'history' : false - } ); - - } ); - - }, - - /** - * Test if Array contains an item - * - * @version 0.1.1 - */ - 'contains': function( a, obj ) { - - for( var i = 0; i < a.length; i++ ) { - if( a[i] === obj ) { - return true; - } - } - - return false; - - }, - - /** - * Remove empty values - * - * @version 0.1.1 - */ - 'clean_object': function( object, args ) { - - jQuery.extend( true, { - 'strip_values': [] - }, args ); - - for( i in object ) { - - if( !object[i] ) { - delete object[i]; - } - - if( object[i] === null ) { - delete object[i]; - } - - if( typeof object[i] === 'object' ) { - - if( Object.keys( object[i] ).length ) { - object[i] = utils.clean_object( object[i], args ); - } else { - delete object[i]; - } - - } - - } - - return object; - } - - } - - // Load Required Assets, and then Initialize - ud.load.js( app._required, function() { - jQuery( document ).trigger( 'elastic_filter::initialize' ); - }); - - return this; - -})(); \ No newline at end of file diff --git a/vendor/udx/lib-utility/scripts/src/jquery.ud.execute-triggers.js b/vendor/udx/lib-utility/scripts/src/jquery.ud.execute-triggers.js deleted file mode 100644 index 2febe2a85..000000000 --- a/vendor/udx/lib-utility/scripts/src/jquery.ud.execute-triggers.js +++ /dev/null @@ -1,161 +0,0 @@ -/* ========================================================= - * jquery.ud.execute_triggers.js v1.0.1 - * http://usabilitydynamics.com - * ========================================================= - * Copyright 2012 Usability Dynamics, Inc. - * - * Validation: http://www.jslint.com/ - * - * The plugin handles jQuery Trigger execution by DOM elements. - * - * ==USAGE== - * - * Initialization: - * jQuery( '.execute_triggers' ).execute_triggers(); - * - * HTML Usage: - * Do Something - * - * Bound Trigger: - * jQuery( document ).bind( 'bound_trigger' , function( event, args ) { - * if( args.attributes.action == 'custom_action' && args.attributes.custom_argument !== 0 ) { - * // Do Stuff - * } - * } - * - * Built-in Attributes: - * - execute_once : Will bind the target action to only run once. By default, the target function will be run everytime. - * - * - * - * Copyright (c) 2012 Usability Dynamics, Inc. ( usabilitydynamics.com ) - * ========================================================= */ - -/*jslint indent: 2 */ -/*global window */ -/*global console */ -/*global clearTimeout */ -/*global setTimeout */ -/*global jQuery */ - -( function ( jQuery ) { - "use strict"; - - jQuery.fn.execute_triggers = function ( s ) { - - /* Set Settings */ - s = jQuery.extend( { - element: this, - ux: {}, - timers: {}, - debug: false - }, s ); - - - /* Internal logging function */ - var log = this.log = function ( something, type ) { - - if ( !s.debug ) { - return; - } - - if ( window.console && console.debug ) { - - if ( type === 'error' ) { - console.error( something ); - } else { - console.log( something ); - } - - } - - }; - - - /** - * The main function ran when the script is initialized. - * - * @author potanin@UD - */ - var enable = this.enable = function () { - log( 'execute_triggers::enable()' ); - - /* Cycle through all triggers */ - jQuery( s.element ).each( function() { - - - if( typeof jQuery( this ).attr( 'execute_once' ) !== 'undefined' ){ - - jQuery( this ).one( 'click', function( event ) { - execute_triggers( event ); - }); - - } else { - - /* Attach "click" listener event to this trgger. Unbind first incase this function is ran more than once. */ - jQuery( this ).unbind( 'click' ).bind( 'click', function( event ) { - execute_triggers( event ); - }); - - } - - }); - - }; - - - /** - * The main function ran when the script is executed. - * - * @author potanin@UD - */ - var execute_triggers = this.execute_triggers = function ( event ) { - log( 'execute_triggers::execute_triggers()' ); - - event.preventDefault(); - - var args = jQuery.extend( true, { - position: [ event.clientX, event.clientY ], - attributes: {}, - element: event.currentTarget, - triggers: jQuery( event.currentTarget ).attr( 'execute_triggers' ) - }, event ); - - /* Bail if there is are no triggers */ - if( typeof( args.triggers ) == 'undefined' || args.triggers == '' ) { - return; - } - - /* Convert all element attributes into an array */ - jQuery.each( args.element.attributes, function( index, attr ) { - args.attributes[attr.name] = attr.value; - }); - - /* Convert trigger string into array */ - args.triggers = args.triggers.split( ',' ); - - /* Do some data cleansing */ - jQuery.each( args.triggers , function( index, trigger_name ) { - args.triggers[ index ] = jQuery.trim( trigger_name ); - }) - - /* Cycle through and actually execute */ - jQuery.each( args.triggers , function( index, trigger_name ) { - - args.this_trigger_count = index; - - jQuery( document ).trigger( trigger_name, args ); - - }); - - }; - - /* Enable */ - this.enable(); - - /* Return object for chaining */ - return this; - - }; - -} ( jQuery ) ); diff --git a/vendor/udx/lib-utility/scripts/src/jquery.ud.form-helper.js b/vendor/udx/lib-utility/scripts/src/jquery.ud.form-helper.js deleted file mode 100644 index c267e88fd..000000000 --- a/vendor/udx/lib-utility/scripts/src/jquery.ud.form-helper.js +++ /dev/null @@ -1,1123 +0,0 @@ -/* ========================================================= - * jquery.ud.form_helper.js v1.1.0 - * http://usabilitydynamics.com - * ========================================================= - * - * Handles various functions related to forms. - * - * ==ClosureCompiler== - * @compilation_level ADVANCED_OPTIMIZATIONS - * @output_file_name jquery.ud.form_helper.min.js - * @js_externs form_helper, jQuery, - * ==/ClosureCompiler== - * - * Copyright (c) 2012 Usability Dynamics, Inc. ( usabilitydynamics.com ) - * - * ========================================================= */ - -( function( jQuery ) { - "use strict"; - - jQuery.fn.form_helper = function( s ) { - - /* Set Settings */ - /** - * Primary function, ran on initialization by default, or on demand when needed. - * - * - Cycles through all forms - * - Processes all required fields - * - Sets up control groups - * - Binds listener events to Input Fields - * - * @todo Make debug-override form-specific, right now it's global. - potanin@UD - * @todo Add check to prevent Form Helper being bound to same form more than once. - potanin@UD - * @todo Add similar function to helpers.css_class_query() that creates class strings that are ready to be inserted into DOM. - potanin@UD - * @author potanin@UD - */ - s = jQuery.extend( true, { - element : this, - settings : { - auto_enable : true, - validate_on_enable : false, - error_on_blank : false, - auto_hide_helpers : true, - check_required_fields : true, - disable_html5_validation : true, - markup_all_fields_on_form_fail : true, - intent_delay : 2500, - initialization_pause : 0 - }, - ajax : { - ajax_url : false, - data : {} - }, - timers : {}, - helpers : {}, - class_selector : {}, - classes : { - help_block : 'help-block', - validate_group : 'validate', - helper_item : 'helper_item', - disabled_helper : 'hide', - active_helper : 'show', - status : { - error : 'error', - blank : 'blank', - success : 'success', - warning : 'warning' - }, - checkbox : { - on : 'c_on', - off : 'c_off' - }, - ajax_form : 'form-ajax' - }, - debug : false - }, s ); - - /* Internal logging function */ - var log = this.log = function( notice, type, force ) { - - if( !s.debug && !force ) { - return; - } - - if( window.console && console.debug ) { - - if( type === 'error' ) { - console.error( notice ); - } - else if( type === 'dir' && typeof console.dir == 'function' ) { - console.dir( notice ); - } - else { - console.log( typeof notice == 'string' ? 'form_helper::' + notice : notice ); - } - - } - - }; - - /** - * Enable Script - * - * @author potanin@UD - */ - var enable = this.enable = function() { - log( 'enable()' ); - - /* Create jQuery selector-ready class versions */ - jQuery.each( s.classes, function( key, settings ) { - s.class_selector[ key] = s.helpers.css_class_query( settings ); - } ) - - /* Cycle through each element - which is usually a Form */ - jQuery( s.element ).each( function( index ) { - var form = this; - - if( form.initialized ) { - log( 'Form Helper already enabled on this form.' ); - } - - /* Allow Debug override. */ - if( jQuery( form ).attr( 'debug_form' ) == 'true' ) { - s.debug = true; - } - - /* Unbind any events in case this is initialized more than once */ - jQuery( form ).unbind( 'submit' ); - - /* Reference for all Input Fields for this form */ - form.form_helper_fields = {}; - - /* Simple Reference for all Control Groups for this form */ - form.form_control_groups = []; - - /* Analyze Attributes with the HTML5 "required" attribute, attempt to figure out the Validation Type, and add classes and attributes to the element's Control Group */ - if( s.settings.check_required_fields ) { - check_required_fields( form ); - } - - /* Automate things by adding the Validate Group class when validation_type or validation_required attributes are set */ - jQuery( '.control-group[validation_required="true"], .control-group[validation_type]', form ).addClass( s.classes.validate_group ); - - /* Add extra classes to checkboxes */ - handle_special_styling(); - - /* Cycle through each Control Group that requires validation, build args, and associate validation function to $.change() event */ - jQuery( '.control-group.' + s.classes.validate_group, form ).each( function() { - - /* Prepare Control Group Settings */ - var control_group = { - form : form, - messages : {}, - timers : {}, - control_group : this, - helpers : false, - attributes : {} - }; - - /* Add this Control Group to the Form Control Group Reference */ - form.form_control_groups.push( control_group.control_group ); - - /* Create placeholders for messages types based on available classes, and get messages passed as Control Group attributes */ - jQuery.each( s.classes.status, function( status_key, status_class ) { - control_group.messages[ status_key ] = jQuery( control_group.control_group ).attr( status_key + '_message' ); - } ); - - /* Convert field attributes from the jQuery format into an associate array */ - jQuery.each( control_group.control_group.attributes, function( index, attr ) { - control_group.attributes[ attr.name ] = attr.value; - } ); - - /* Convert to jQuery Object */ - control_group.control_group = jQuery( control_group.control_group ); - - control_group.validation_required = control_group.control_group.attr( 'validation_required' ) == 'true' ? true : false; - control_group.validation_type = control_group.control_group.attr( 'validation_type' ) != '' ? control_group.control_group.attr( 'validation_type' ) : 'not_empty'; - control_group.do_not_markup = control_group.control_group.attr( 'do_not_markup' ) !== undefined ? true : false; - - if( control_group.validation_type && jQuery( control_group.control_group ).attr( control_group.validation_type ) ) { - control_group[ control_group.validation_type ] = jQuery( control_group.control_group ).attr( control_group.validation_type ); - } - - /* Check if conditional help exists */ - if( jQuery( s.class_selector.help_block, control_group.control_group ).length ) { - control_group.helpers = jQuery( s.class_selector.help_block, control_group.control_group ); - } - - /* Run Validation on every single field, and attach Validation to future change events */ - jQuery( 'input,textarea,select', control_group.control_group ).each( function() { - - /* Build Input Field arg */ - var input_field = { - input_element : jQuery( this ), - input_type : jQuery( this ).attr( 'type' ), - name : jQuery( this ).attr( 'name' ), - type : this.nodeName.toLowerCase() - } - - /* Simple array of Input Fields of same type in same group */ - input_field.related_fields = jQuery.map( jQuery( input_field.type, control_group.control_group ).not( input_field.input_element ), function( element, index ) { - return element; - } ); - - /* Remove any bound change events from this input field */ - jQuery( input_field.input_element ).unbind( 'change' ); - - /* Add any attributes that will not change as the input is interacted with */ - if( !s.settings.disable_html5_validation ) { - jQuery( input_field.input_element ).attr( 'aria-required', 'true' ); - } - - /* Combine Field and Control Group settings and add to Input Field to reference. This groups fields with same name (e.g. checkboxes) together. */ - form.form_helper_fields[ input_field.name ] = jQuery.extend( {}, control_group, input_field ); - - } ); - /* End of single Input Field processing */ - - } ); - /* End of single Control Group processing */ - - log( form.form_helper_fields, 'dir' ); - - /* All Monitored Fields are loaded at this point. Now we cycle through all fields, run initial validaiton, and attach revent handlers to them */ - jQuery.each( form.form_helper_fields, function( name, vs ) { - - /* Save the Validation Settings in DOM object */ - jQuery( vs.input_element ).data( 'validation_settings', vs ); - - vs.inputs_in_group = jQuery( 'input,textarea,select', vs.control_group ).length; - - /* Render, or update, Message via Helpers */ - s.helpers.update_inline_help( vs.control_group, vs ); - - /* Bind initial Validation to Window.load to utilize any autocompleted fields. */ - jQuery( window ).load( function() { - setTimeout( function() { - log( 'enable() - Executing initial field validation.' ); - validate_field( vs.input_element, vs ); - - }, s.settings.initialization_pause ); - } ); - - // Allow Intent Delay override via attribute. - // @todo This should be migrated elsewhere and integrated w/ a better override system - potanin@UD - vs.intent_delay = typeof vs.control_group.attr( 'intent_delay' ) == 'string' ? vs.control_group.attr( 'intent_delay' ) : s.settings.intent_delay; - - monitor_field( vs.input_element, vs, { - check_related : true - } ); - - } ); - /* End of Form Helper Fields processing */ - - form.initialized = true; - - /* Monitor submit event */ - jQuery( form ).submit( function( event ) { - handle_submission( form, event ); - } ); - - } ); - /* End of single Form Procesing */ - - }; - - /** - * Attaches all events to monitored Input Fields - * - * @author potanin@UD - */ - var monitor_field = function( input_element, vs, args ) { - - args = jQuery.extend( {}, { - check_related : false - }, args ); - - /* Monitor change events */ - jQuery( input_element ).bind( 'change', function( e ) { - validate_field( input_element, vs ); - } ); - - /* Monitor keyup events for Inputs and Textareas */ - if( vs.type == 'input' || vs.type == 'textarea' ) { - - jQuery( input_element ).keyup( function( event ) { - - /* Reset Done Typing timer */ - clearTimeout( vs.timers.intent_delay ); - - vs.timers.intent_delay = setTimeout( function() { - validate_field( input_element, vs ); - }, vs.intent_delay ); - - } ); - - /* Kill Typing Timer when user leaves Input Field */ - jQuery( input_element ).blur( function( event ) { - clearTimeout( vs.timers.intent_delay ); - } ); - - } - - jQuery( vs.input_element ).addClass( 'monitored' ); - - /* Attach monitoring to any related fields, that have the same name and are therefore not in form.form_helper_fields */ - if( args.check_related ) { - jQuery.each( vs.related_fields, function( i, related_element ) { - - if( !jQuery( related_element ).hasClass( 'monitored' ) ) { - monitor_field( related_element, vs ); - } - - } ); - } - - } - - /** - * Style checkboxes by adding custom classes to the label element. - * - * @todo This does not seem to be very efficient. - * @author potanin@UD - */ - function handle_special_styling() { - log( 'handle_special_styling()' ); - - if( !jQuery( '.checkbox.styled input' ).length ) { - return; - } - - jQuery( '.checkbox.styled' ).each( function() { - jQuery( this ).closest( 'label' ).removeClass( s.classes.checkbox.on ).addClass( s.classes.checkbox.off ); - } ); - - jQuery( '.checkbox.styled input:checked' ).each( function() { - jQuery( this ).closest( 'label' ).addClass( s.classes.checkbox.on ).removeClass( s.classes.checkbox.off ); - } ); - - jQuery( '.checkbox.styled input' ).click( handle_special_styling ); - - }; - - /** - * A shortcut that looks for enabled Input Fields with a "required" attribute in the form, and modifies the Control Group automatically. - * - * Attempts to determine Validation Type based on Input Type. - * - * Adds to the Control Group of each required field: - * - class: validate - * - attr: validation_required - * - attr: validation_type - * - * Optionally removes the "required" attribute to stop HTML5 validation on modern browsers. - * - * @author potanin@UD - */ - function check_required_fields( form ) { - log( 'check_required_fields()' ); - - jQuery( 'input[required],textarea[required],select[required]', form ).each( function() { - - /* Don't do anything with disabled fields */ - if( this.disabled ) { - log( ' Skipping ' + this.name + ' because it is disabled.' ); - return; - } - - /* If configured, remove attribute to disable built-in browser support for validation */ - if( s.settings.disable_html5_validation ) { - jQuery( this ).removeAttr( 'required' ); - } - - /* Identify our Control Group */ - var control_group = jQuery( this ).closest( '.control-group' ); - - /* If no CG, as of now we do nothing */ - if( !control_group.length ) { - return; - } - - /* Check if Validation Type attribute is declared */ - var validation_type = jQuery( this ).attr( 'validation_type' ) != '' ? jQuery( this ).attr( 'validation_type' ) : false; - - /* If Control Group does not have a defined Validation Requirement, we set it */ - if( !control_group.attr( 'validation_required' ) ) { - control_group.attr( 'validation_required', 'true' ); - } - - /* Mark the CG as needing to be validateed */ - control_group.addClass( s.classes.validate_group ); - - /* If Validation Type was not set, we check Input Type for possible Validation Type */ - if( !validation_type && jQuery( this ).attr( 'type' ) ) { - - switch( jQuery( this ).attr( 'type' ).toLowerCase() ) { - - case 'email' : - control_group.attr( 'validation_type', 'email' ); - break; - - case 'url' : - control_group.attr( 'validation_type', 'url' ); - break; - - case 'tel' : - control_group.attr( 'validation_type', 'tel' ); - break; - - } - - } - - /* If we found a Validation Type, we add it and the type-specific setting to the Control Group */ - if( validation_type ) { - control_group.attr( 'validation_type', validation_type ); - - if( jQuery( this ).attr( validation_type ) ) { - control_group.attr( validation_type, jQuery( this ).attr( validation_type ) ); - } - - } - - jQuery( document ).trigger( 'form_helper::check_required_fields::field_complete', { element : this, validation_type : validation_type } ); - - } ); - - } - - /** - * Ran when from is submitted. - * - * @author potanin@UD - */ - function handle_submission( form, e ) { - log( 'handle_submission()' ); - - /* Sometimes causes error on IE7 */ - form.status = form_status( form ); - - if( form.status.validation_fail ) { - e.preventDefault(); - - /* Cycle through all fields and validate them, to show user what they missed */ - if( s.settings.markup_all_fields_on_form_fail ) { - - jQuery.each( form.form_helper_fields, function( name, settings ) { - - if( settings.status_code != 'success' ) { - validate_field( settings.input_field, settings ); - } - - } ); - - } - - /* Cycle only through failed fields */ - if( !s.settings.markup_all_fields_on_form_fail ) { - - jQuery.each( form.status.failed_fields, function( i, name ) { - validate_field( name ); - - } ); - - } - - return false; - - } - else { - - jQuery( form ).trigger( 'form_helper::success', { form : form, event : e } ); - - if( jQuery( form ).hasClass( s.classes.ajax_form ) ) { - e.preventDefault(); - return false; - } - - } - - //return true; - - } - - /** - * Checks a single field, in relation to it's control group, against the specified validation settings - * - * Function executed on $.ready() and everytime the input is updated, or on demand. - * To call on demand, pass two arguments: - * - input_element (jQuery Object) - target field - * - validation_settings (Object) - see enable() for object information, will vary from one situations to the next - * - * @author potanin@UD - */ - var validate_field = this.validate_field = function( input_element, validation_settings ) { - log( 'validate_field(' + ( typeof validation_settings == 'object' ? validation_settings.name : '?' ) + ')' ); - - /* If this function is being called with only a Field Name, we attempt to get the DOM Oject */ - if( input_element && typeof input_element != 'object' ) { - input_element = jQuery( '[name="' + input_element + '"]' ); - - if( input_element.length ) { - log( 'validate_field(): Input Element not passed as object, but found using name in DOM.' ); - } - else { - log( 'validate_field(): Input Element not passed as object, and could not be found by name (' + input_element + ') in DOM.' ); - } - } - - /* If we have the DOM Input Element Object, but no Validation Settings */ - if( input_element && !validation_settings ) { - validation_settings = input_element.data( 'validation_settings' ); - } - - /* If cannot get Validation Settings, we re-enable */ - if( !validation_settings ) { - return log( 'validate_field(): Warning. validate_field() was called on an Input Field that could not be found, or does not have Validation Settings.', 'error', true ); - } - - /* Merge passed Validation Settings with Defaults */ - var args = jQuery.extend( true, { - validation_type : 'not_empty' - }, validation_settings ); - - var current_value = typeof jQuery( input_element ).val() == 'string' ? jQuery( input_element ).val() : ''; - - /* Determine if this is the first time this field has been put through validation */ - if( typeof args.form.form_helper_fields[ args.name ].status_code === 'undefined' ) { - args.initial_run = true; - } - - var result = { - detail_log : [] - } - - result.detail_log.push( ( args.initial_run ? 'Initial Run' : 'Secondary Run' ) + ': ' + args.name ); - result.detail_log.push( 'args.validation_required: ' + args.validation_required ); - result.detail_log.push( 'args.inputs_in_group: ' + args.inputs_in_group ); - result.detail_log.push( 'current_value: ' + current_value ); - result.detail_log.push( 'validation_type: ' + args.validation_type ); - - switch( args.validation_type ) { - - case 'checked': - - if( jQuery( input_element ).attr( 'type' ) != 'checkbox' ) { - args.status_code = 'success'; - - } - else { - if( jQuery( input_element ).is( ':checked' ) ) { - args.status_code = 'success'; - - } - else { - args.status_code = 'error'; - - } - } - - break; - - /** - * Compare all elements of same type within the Control Group - * - * @todo Bug with last element being excluded from related. So when it is checked, it does not count. - potanin@UD - */ - case 'selection_limit': - - result.detail_log.push( 'Total related: ' + args.related_fields.length ); - - /* Build array of checked elements */ - var checked = jQuery.map( jQuery( args.related_fields ), function( element, index ) { - if( element.checked ) { - return element; - } - } ); - - result.detail_log.push( 'Total checked: ' + checked.length ); - result.detail_log.push( 'Selection limit: ' + validation_settings.selection_limit ); - - if( checked.length === 0 ) { - args.status_code = 'error'; - args.messages[ 'success' ] = 'Please make a selection.'; - } - - if( checked.length > 0 && checked.length < validation_settings.selection_limit ) { - args.status_code = 'success'; - args.messages[ 'success' ] = 'You may select ' + ( validation_settings.selection_limit - checked.length ) + ' more.'; - } - - if( checked.length == validation_settings.selection_limit ) { - args.status_code = 'success'; - args.messages[ 'success' ] = 'You can not select anymore.'; - } - - if( checked.length > validation_settings.selection_limit ) { - jQuery( input_element ).removeAttr( 'checked' ) - } - - /* Update Inline Help */ - s.helpers.update_inline_help( args.control_group, args ); - - break; - - - /** - * Compare all elements of same type within the Control Group - * - * @todo The password strength is temporary. - */ - case 'password': - case 'matching_passwords': - - var other_value; - - /* For password there should only be two, but we cycle through full loop */ - jQuery.each( args.related_fields, function( i, element ) { - other_value = jQuery( element ).val(); - } ); - - if( current_value === '' && other_value === '' ) { - result.detail_log.push( 'Passwords are empty: ' + current_value + ' - ' + other_value ); - args.status_code = 'error'; - break; - } - - if( current_value === other_value ) { - result.detail_log.push( 'Passwords match: ' + current_value + ' - ' + other_value ); - args.status_code = 'success'; - - /* Simple Password Strength (should be done much better via third-party of sort */ - args.password_strength = Math.round( ( other_value.length / 13 ) * 100 ); - args.messages[ 'success' ] = jQuery( '
                    Password Strength:
                    ' ); - - /* Update Inline Help */ - s.helpers.update_inline_help( args.control_group, args ); - - break; - } - - if( current_value != other_value ) { - result.detail_log.push( 'Passwords do not match: ' + current_value + ' - ' + other_value ) - args.status_code = 'error'; - break; - } - - break; - - case 'email': - - if( current_value == '' ) { - args.status_code = 'blank'; - - } - else if( s.helpers.validate_email( current_value ) ) { - args.status_code = 'success'; - - } - else { - args.status_code = 'error'; - - } - - break; - - case 'url': - - if( current_value == '' ) { - args.status_code = 'blank'; - - } - else if( s.helpers.validate_url( current_value ) ) { - args.status_code = 'success'; - - } - else { - args.status_code = 'error'; - - } - - break; - - case 'domain': - if( current_value == '' ) { - args.status_code = 'blank'; - } - else if( s.helpers.validate_url( current_value, { use_http : false } ) ) { - args.status_code = 'success'; - } - else { - args.status_code = 'error'; - } - - break; - - /** - * Uses Google Maps, if available, to get quality of address. - * - * @todo This is not complete, mostly proof of concept. - potanin@UD - */ - case 'address': - - if( current_value == '' ) { - args.status_code = 'blank'; - break; - } - - /* Make sure Google Maps API is loaded */ - if( typeof google != 'object' || typeof google.maps != 'object' ) { - break; - } - - args.remote_request = true; - - args.geocoder = args.geocoder ? args.geocoder : new google.maps.Geocoder(); - - /* Remove line breaks from GM request */ - args.clean_value = current_value.replace( /(\r\n|\n|\r)/gm, " " ); - - args.geocoder.geocode( { 'address' : args.clean_value }, function( results, status ) { - - if( typeof results == 'object' ) { - - jQuery.each( results, function( i, data ) { - - if( data.geometry.location_type == 'ROOFTOP' ) { - args.messages[ 'success' ] = 'Validated: ' + data.formatted_address; - args.status_code = 'success'; - - } - else if( data.status == 'ZERO_RESULTS' ) { - args.status_code = 'error'; - - } - else { - args.status_code = 'warning'; - } - - } ); - - /* Render, or update, Message via Helpers */ - s.helpers.update_inline_help( args.control_group, args ); - - finalize_field_validation( current_value, result, args ); - - } - - } ); - - break; - - case 'ajax': - - if( !args.validation_ajax ) { - break; - } - - args.remote_request = true; - - /* Load default AJAX arguments */ - var ajax_request = jQuery.extend( {}, { - action : args.validation_ajax, - field_name : args.name, - field_value : current_value, - field_type : args.type - }, s.settings.ajax_url ); - - jQuery.ajax( { - url : s.settings.ajax_url, - data : ajax_request, - success : function( response ) { - args.status_code = ( response.success == 'false' ) ? 'error' : 'success'; - - /* Add new message to Control Group's Messages */ - args.messages[ args.status_code ] = response.message; - - update_control_group_ui( args.control_group, args ); - - result.detail_log.push( args.name + ' - Custom Ajax Validation. Result: ' + args.status_code ); - - finalize_field_validation( current_value, result, args ); - - }, - dataType : "json" - } ); - - break; - - case 'pattern': - - var this_regex = new RegExp( args.attributes.pattern, "g" ); - - if( current_value == '' ) { - args.status_code = 'blank'; - - } - else if( this_regex.test( current_value ) ) { - args.status_code = 'success'; - - } - else { - args.status_code = 'error'; - args.messages[ args.status_code ] = "Please, match the requested format" + ( ( typeof args.title != 'undefined' ) ? ":" + args.title : '' ); - } - - break; - - case 'not_empty': - default: - - if( current_value == '' ) { - args.status_code = 'blank'; - - } - else { - args.status_code = 'success'; - - } - - if( current_value == '' ) { - args.status_code = 'blank'; - } - else { - args.status_code = 'success'; - } - - break; - - } - /* Attribute Validation Complete */ - - if( !args.remote_request ) { - finalize_field_validation( current_value, result, args ); - } - - } - - /** - * Ran after validate_field() has completed processing. - * - * @todo Migrate this into a bound function within validate_field(). - potanin@UD - * @author potanin@UD - */ - var finalize_field_validation = this.finalize_field_validation = function( current_value, result, args ) { - - if( args.status_code == 'blank' && s.settings.error_on_blank ) { - args.status_code = 'error'; - } - - result.detail_log.push( 'new status_code: ' + args.status_code ); - - /* Not used yet, jsut added for reference */ - jQuery( args.input_element ).attr( 'validation_status_code', args.status_code ); - jQuery( args.control_group ).attr( 'validation_status_code', args.status_code ); - - /* Save new Status Code into Form Helper Fields */ - args.form.form_helper_fields[ args.name ].status_code = args.status_code; - - /* Actions for Input Fields that are monitored, e.g. the chang of which can affect the overall Form Status */ - if( args.validation_required ) { - - /* If Validation is Required for submitting, and the result is anything other than success - we stop the form */ - if( args.status_code != 'success' ) { - result.detail_log.push( 'Field validation fail.' ); - } - - /* Class added for quick reference, not markup */ - if( form_status( args.form ).validation_fail ) { - jQuery( args.form ).addClass( 'validation_fail' ); - jQuery( args.form ).data( 'do_not_process', true ); - result.detail_log.push( 'Form validation fail.' ); - - } - else { - jQuery( args.form ).removeClass( 'validation_fail' ); - jQuery( args.form ).removeData( 'do_not_process' ); - result.detail_log.push( 'Form passed validation.' ); - - } - - } - /* End Validation-only Actions */ - - log( result.detail_log, 'dir' ); - - /* If this is not initialization, do the markup */ - if( !args.initial_run || s.settings.validate_on_enable ) { - update_control_group_ui( args.control_group, args ) - } - - } - - /** - * Updates the visual styles of a Control Group and displays helpers. - * - * control_group is passed as first argument for API access as an object - * - * @author potanin@UD - */ - var update_control_group_ui = this.update_control_group_ui = function( control_group, args ) { - log( 'update_control_group_ui()' ); - - /* If this Control Group has a do_not_markup attribute, we let it be */ - if( args.do_not_markup ) { - return; - } - - /* Remove all Status Classes from CG */ - jQuery.each( s.classes.status, function( key, value ) { - jQuery( control_group ).removeClass( value ); - } ); - - /* Render applicable Notices, if they exists */ - if( args.helpers ) { - - /* Hide all immediate children and remove any .active classes */ - jQuery( '> .' + s.classes.helper_item, args.helpers ).removeClass( s.classes.active_helper ).addClass( s.classes.disabled_helper ); - - /* Find the helper by class, if exists, and show it */ - jQuery( '.' + args.status_code, args.helpers ).removeClass( s.classes.disabled_helper ).addClass( s.classes.active_helper ); - - } - - /* If this is a Validated field that has failed validation: */ - jQuery( control_group ).addClass( s.classes.status[ args.status_code ] ); - - } - - /** - * Determine and update that overall status of a form - * - * @author potanin@UD - */ - var form_status = this.form_status = function( form ) { - log( 'form_status()' ); - - /* Ensure Form Helper Fields are set, if not return an empty object */ - if( typeof form.form_helper_fields != 'object' ) { - log( 'form_status() - form.form_helper_fields is not an object, leaving.' ); - return {}; - } - - var response = { - validation_fail : false, - failed_fields : [] - }; - - jQuery.each( form.form_helper_fields, function( name, settings ) { - - if( settings.status_code != 'success' ) { - log( 'form_status() - Input Field failed validation: ' + name ); - response.failed_fields.push( name ); - } - - } ); - - /* If we have Failed Fields, then the form is failed */ - if( response.failed_fields.length ) { - log( 'form_status() - Form failed validation. Invalid fields: ' + response.failed_fields.length ); - form.validation_fail = response.validation_fail = true; - form.failed_fields = response.failed_fields; - } - else { - log( 'form_status() - Form is valid. ' ); - } - - return response; - - }; - - /** - * Updates Inline Help based on available messages in the Control Group Message Handler. - * - * Ran when on enable() and on other events that may result in updates to Control Group - * status message text, such as AJAX returned data. - * - * @todo Not sure at which point this should be ran first. - potanin@UD - * @author odokienko@UD - */ - if( typeof s.helpers.update_inline_help != 'function' ) { - s.helpers.update_inline_help = function( control_group, args ) { - log( 'helpers.update_inline_help()' ); - - /* Try to load exisitng Help Block */ - if( !args.helpers ) { - args.helpers = jQuery( s.class_selector.help_block, control_group ); - } - - /* If no Help Block found, create one by inserting it after the last input type in CG */ - if( !args.helpers.length ) { - jQuery( args.type + ':last', control_group ).after( args.helpers = jQuery( '' ) ); - } - - /* Update Status-based Help Messages by going through all available statuses */ - jQuery.each( args.messages, function( status_key, text ) { - - /* Get Status Class form global settings */ - var status_class = s.classes.status[ status_key ]; - var this_line = jQuery( 'span.' + status_class, args.helpers ); - - if( !this_line.length ) { - jQuery( args.helpers ).append( this_line = jQuery( '' ) ); - } - - /* Always add the main Helper Item class */ - this_line.addClass( s.classes.helper_item ); - - /* Add status-specific class */ - this_line.addClass( status_class ); - - /* If enabled, as on default, the Disabled Helper class is added to all helper items */ - if( s.settings.auto_hide_helpers ) { - this_line.addClass( s.classes.disabled_helper ); - } - - /* Insert text into Line Item */ - jQuery( this_line ).html( text ); - - } ); - - } - } - - /** - * Flexible converter of user-specified classes into a jQuery-friendly query. - * - * Classes may be passed in several ways: - * - 'my_class' - * - 'my_class another_class' - * - ['my_class', 'another_class'] - * - * Purposely ignores associative arrays returning them as they were passed. - * - * @author potanin@UD - */ - if( typeof s.helpers.css_class_query != 'function' ) { - s.helpers.css_class_query = function( css_class ) { - - var css_query = []; - - if( typeof css_class == 'object' || typeof css_class == 'array' ) { - - var associative_array = false; - - jQuery.each( css_class, function( i, single_class ) { - css_query.push( single_class ); - - if( !jQuery.isNumeric( i ) ) { - associative_array = true; - return; - } - - } ); - - if( associative_array ) { - return css_class; - } - - } - else if( typeof css_class == 'string' ) { - css_query = css_class.split( ' ' ); - } - - /* Joing pieces together and replace double-periods with single */ - return ('.' + css_query.join( '.' ) ).replace( /\.\./g, '.' ); - - } - } - - /** - * Helper for properly removing an element from array by value - * - * {Not currently used} - * - * @author potanin@UD - */ - if( typeof s.helpers.remove_from_array != 'function' ) { - s.helpers.remove_from_array = function( value, arr ) { - return jQuery.grep( arr, function( elem, index ) { - return elem !== value; - } ); - } - } - - /** - * Helper for URL Validation - * - * @author potanin@UD - */ - if( typeof s.helpers.validate_url != 'function' ) { - s.helpers.validate_url = function( value, args ) { - log( 'helpers.validate_url(' + value + ')' ); - args = jQuery.extend( { use_http : true }, args ); - if( args.use_http ) return /^(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/i.test( value ); - return /^[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/i.test( value ); - } - } - - /** - * Helper for Email Validation - * - * @author potanin@UD - */ - if( typeof s.helpers.validate_email != 'function' ) { - s.helpers.validate_email = function( value ) { - log( 'helpers.validate_email(' + value + ')' ); - var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; - return re.test( value ); - } - } - - /* Enable functionality on each instance */ - if( s.settings.auto_enable ) { - enable(); - } - - /* Return object for chaining */ - return this; - - }; - -}( jQuery ) ); diff --git a/vendor/udx/lib-utility/scripts/src/jquery.ud.smart-buttons.js b/vendor/udx/lib-utility/scripts/src/jquery.ud.smart-buttons.js deleted file mode 100644 index 8806ef824..000000000 --- a/vendor/udx/lib-utility/scripts/src/jquery.ud.smart-buttons.js +++ /dev/null @@ -1,260 +0,0 @@ -/* ========================================================= - * jquery.ud.smart_buttons.js v0.6 - * http://usabilitydynamics.com - * ========================================================= - * Copyright 2012 Usability Dynamics, Inc. - * - * Copyright (c) 2011 Usability Dynamics, Inc. (usabilitydynamics.com) - * ========================================================= */ - -(function( jQuery ){ - - /** - * Handle AJAX Actions and UI actions - * - * {missing detailed description} - * - * @author potanin@UD - * @version 0.2.2 - */ - jQuery.fn.smart_dom_button = function( settings ) { - - /* Set Settings */ - var s = jQuery.extend({ - debug: false, - action_attribute: 'action_attribute', - response_container: 'response_container', - ajax_action: 'action', - label_attributes: { - process: 'processing_label', - revert_label: 'revert_label', - verify_action: 'verify_action' - } - }, settings); - - /* Internal logging function */ - log = function(something, type) { - - if(!s.debug) { - return; - } - - if(window.console && console.debug) { - - if (type == 'error') { - console.error(something); - } else { - console.log(something); - } - - } - - }; - - - /** - * Gets label for the type of element - * - */ - get_label = function( this_button ) { - - var type = jQuery(this_button).get(0).tagName; - var label = ''; - - switch (type) { - - case 'SPAN': - label = jQuery(this_button).text(); - break; - - case 'INPUT': - label = jQuery(this_button).val(); - break; - - } - - return label; - - } - - - /** - * Sets the label for the type - * - */ - set_label = function( label, a ) { - - switch (a.type) { - - case 'SPAN': - jQuery(a.button).text(label); - break; - - case 'INPUT': - jQuery(a.button).val(label); - break; - - } - - return label; - - } - - - /** - * Execute an action for the button - * - * @todo Improve ajax response handling, to include hiding response element on error. - * - */ - do_execute = function( this_button ) { - - /* Array of all settings specific to the current button */ - var a = { - button: this_button, - type: jQuery(this_button).get(0).tagName, - original_label: jQuery(this_button).attr('original_label') ? jQuery(this_button).attr('original_label') : get_label(this_button) - }; - - /* Get wrapper if used and exists */ - if(s.wrapper && jQuery(a.button).closest(s.wrapper).length) { - a.wrapper = jQuery(a.button).closest(s.wrapper); - a.use_wrapper = true; - } else { - a.wrapper = a.button; - a.use_wrapper = false; - } - - /* Determine action */ - a.the_action = jQuery(a.wrapper).attr(s.action_attribute) ? jQuery(a.wrapper).attr(s.action_attribute) : false; - - /* Get labels */ - if(s.label_attributes.processing && jQuery(a.wrapper).attr(s.label_attributes.processing)) { - a.processing_label = jQuery(a.wrapper).attr(s.label_attributes.processing) ? jQuery(a.wrapper).attr(s.label_attributes.processing) : false; - } - - if(s.label_attributes.verify_action && jQuery(a.wrapper).attr(s.label_attributes.verify_action)) { - a.verify_action = jQuery(a.wrapper).attr(s.label_attributes.verify_action) ? jQuery(a.wrapper).attr(s.label_attributes.verify_action) : false; - } - - /* Set original label only if a revert label exists */ - if(s.label_attributes.revert_label && jQuery(a.wrapper).attr(s.label_attributes.revert_label)) { - a.revert_label = jQuery(a.wrapper).attr(s.label_attributes.revert_label) ? jQuery(a.wrapper).attr(s.label_attributes.revert_label) : false; - - /* Set original label if not already set */ - if(!jQuery(a.wrapper).attr('original_label')) { - a.original_label = get_label(a.button); - jQuery(a.wrapper).attr('original_label', a.original_label); - } - - } - - /* If no action found, we leave */ - if(!a.the_action) { - return; - } - - if(a.verify_action) { - if(!confirm(a.verify_action)) { - return; - } - } - - /* Create a response container if we are using a wrapper */ - if(a.use_wrapper) { - - if(!jQuery(s.response_container, a.wrapper).length) { - jQuery(a.wrapper).append(''); - } - - a.response_container = jQuery('.response_container', a.wrapper); - - /* Unset all classes */ - jQuery(a.response_container).removeClass(); - jQuery(a.response_container).addClass('response_container'); - - if(a.processing_label) { - jQuery(a.response_container).html(a.processing_label); - } - - } - - /* Check if this is a UI action first, otherwise use AJAX */ - if(a.the_action == 'ui') { - - /* If a revert label exists, we toggle them */ - if(a.revert_label) { - - if(get_label(a.button) == a.revert_label) { - set_label(a.original_label, a); - - } else { - set_label(a.revert_label, a); - - } - - } - - if(jQuery(a.wrapper).attr('toggle')) { - jQuery(jQuery(a.wrapper).attr('toggle')).toggle(); - } - - if(jQuery(a.wrapper).attr('show')) { - jQuery(jQuery(a.wrapper).attr('show')).show(); - } - - if(jQuery(a.wrapper).attr('hide')) { - jQuery(jQuery(a.wrapper).attr('hide')).hide(); - } - - } else { - - jQuery.post(ajaxurl, { - action: s.ajax_action, - the_action: a.the_action - }, function (result) { - - if(result && result.success) { - jQuery(a.response_container).show(); - - if(result.css_class) { - jQuery(a.response_container).addClass(result.css_class); - } - - if(result.remove_element && jQuery(result.remove_element).length) { - jQuery(result.remove_element).remove(); - } - - jQuery(a.response_container).html(result.message); - - var this_timeout; - - jQuery(a.response_container).mouseover( function() { - this_timeout = setTimeout(function() { - jQuery(a.response_container).fadeOut('slow', function() { - jQuery(a.response_container).remove(); - }); - }, 10000); - - }).mouseout(function() { - clearTimeout( this_timeout ); - }); - - } - - }, 'json'); - - } - - } - - jQuery( this ).click(function() { - log("Button triggered."); - do_execute( this ); - }); - - - return this; - - }; -}) ( jQuery ); \ No newline at end of file diff --git a/vendor/udx/lib-utility/scripts/src/jquery.ud.social.js b/vendor/udx/lib-utility/scripts/src/jquery.ud.social.js deleted file mode 100644 index 73d7ff22c..000000000 --- a/vendor/udx/lib-utility/scripts/src/jquery.ud.social.js +++ /dev/null @@ -1,193 +0,0 @@ -/* ========================================================= - * jquery.ud.social.js v1.0.0 - * http://usabilitydynamics.com - * ========================================================= - * - * Handle interaction with social sites. - * - * Validation: http://www.jslint.com/ - * - * Copyright ( c ) 2012 Usability Dynamics, Inc. ( usabilitydynamics.com ) - * ========================================================= */ - -( function ( jQuery ) { - "use strict"; - - jQuery.fn.social = function ( s ) { - - /* Set Settings */ - s = jQuery.extend( { - element: this, - networks: { - linkedin: { - profile_fields: { - id: 'network_id', - firstName: 'first_name', - lastName: 'last_name', - pictureUrl: 'user_image', - headline: 'headline', - industry: 'industry', - summary: 'summary', - specialties: 'specialties', - location: 'location', - associations: 'associations', - certifications: 'certifications', - educations: 'educations', - skills: 'skills', - patents: 'patents', - honors: 'honors', - proposalComments: 'proposal_comments', - 'three-current-positions': 'current_positions', - 'recommendations-received': 'recommendations', - 'main-address': 'primary_address', - 'member-url-resources': 'url_resources', - 'phone-numbers': 'phone_number', - 'public-profile-url': 'profile_url', - 'im-accounts': 'im_accounts' - } - } - }, - user_data: {}, - debug: true - }, s ); - - /* Internal logging function */ - var log = this.log = function ( something, type ) { - - if ( !s.debug ) { - return; - } - - if ( window.console && console.debug ) { - - if ( type === 'error' ) { - console.error( something ); - } else { - console.log( something ); - } - - } - - }; - - - /** - * The main function ran when the script is executed. - * - * Profile Fields: https://developer.linkedin.com/documents/profile-fields - * - * @called onLoad - * @author potanin@UD - */ - var handle_linkedin = this.handle_linkedin = function ( ) { - log( 'handle_linkedin()' ); - - s.networks.linkedin.active = true; - - if( typeof IN.Event == 'undefined') { - return; - } - - jQuery( '.linkedin_asset' ).show(); - - /* Executed after the current user has been authenticated */ - IN.Event.on( IN, "auth", function() { - log( 'IN.Event::auth ' ); - - var these_fields = []; - - /* Create a simple array of LinkedIn-friendly fields */ - jQuery.each( s.networks.linkedin.profile_fields, function( network_key , global_key) { - these_fields.push( network_key ); - }); - - IN.API.Profile( 'me' ).fields( these_fields ).result( function( profile ) { - log( 'IN.API.Profile()' ); - - /* Cycle through returnes values and match the values up with global user meta keys */ - jQuery.each( profile.values[0], function( network_key, value ) { - - var global_key = s.networks.linkedin.profile_fields[ network_key ]; - - if( typeof global_key == 'undefined' || value == '' ) { - return; - } - - switch( network_key ) { - - case 'location': - value = value.name; - break; - - } - - s.user_data[global_key] = value; - - }); - - s.user_data.display_name = s.user_data.first_name + ' ' + s.user_data.last_name; - - if( s.user_data ) { - jQuery( '.linked_in_login' ).html( - '

                    ' - + ( typeof s.user_data.user_image == 'string' ? '' : '' ) - + 'Hello, ' + s.user_data.first_name + '! ' - + ( typeof s.user_data.headline == 'string' ? '' + s.user_data.headline + '' : '' ) - + ( typeof s.user_data.industry == 'string' ? '' + s.user_data.industry + '' : '' ) - + '

                    '); - } - - jQuery( document ).trigger( 'social::user_data_update' , s.user_data ); - - }); - - jQuery( document ).bind( 'social::user_logout', function() { - - if( typeof IN == 'object' && typeof IN.User != 'undefined' ) { - IN.User.logout(); - } - - }); - - - - }); - - } - - - /** - * The main function ran when the script is executed. - * - */ - var user_logout = this.user_logout = function() { - - jQuery( document ).trigger( 'social::user_logout' ); - - } - - - /** - * The main function ran when the script is executed. - * - */ - var enable = this.enable = function ( ) { - log( 'social::enable()' ); - - /* Detect Social Networks */ - if( typeof (IN) == 'object' ) { - handle_linkedin(); - } - - }; - - - /* Authormatically enable */ - this.enable( ); - - /* Return object for chaining */ - return this; - - }; - -} ( jQuery ) ); diff --git a/vendor/udx/lib-utility/scripts/src/jquery.ud.super-search.js b/vendor/udx/lib-utility/scripts/src/jquery.ud.super-search.js deleted file mode 100644 index 7e5625a08..000000000 --- a/vendor/udx/lib-utility/scripts/src/jquery.ud.super-search.js +++ /dev/null @@ -1,363 +0,0 @@ -/* ========================================================= - * jquery.ud.super_search.js v1.0.1 - * http://usabilitydynamics.com - * ========================================================= - * Copyright 2012 Usability Dynamics, Inc. - * - * Validation: http://www.jslint.com/ - * - * Copyright (c) 2012 Usability Dynamics, Inc. ( usabilitydynamics.com ) - * ========================================================= */ - -(function( jQuery ){ - jQuery.fn.super_search = function( ss_settings ) { - - var element = this; - var abandoned_timer; - var ui= {}; - var ux = {}; - var typing_timer; - var query = { - current: '', - previous: '' - }; - - /* Add ss_eleemnt attribute to this element so it can be IDied later */ - this.attr('ss_element', 'search_input'); - - /* Default Settings */ - var ss = jQuery.extend({ - action : 'super_search', - ajax_url : ajaxurl, - input_classes : { - no_results: 'ss_no_results', - processing: 'ss_processing', - error: 'ss_error' - }, - response_classes: { - response_wrapper: 'ss_response_container', - show_scroll: 'ss_show_scroll', - item_class: '' - }, - append_to: jQuery( element ).parent(), - search_trigger: false, - search_result_gap : 200, - limit : 5, - timers: { - abandonment: 1000, - search_entry : 2000 - }, - async : false, - debug : true, - success : false, - beforeSend : false, - ui: {} - }, ss_settings); - - /* Internal logging function */ - - if( typeof ss.log !== 'function' ) { - ss.log = function( something, type ) { - - if(!ss.debug) { - return; - } - - console.log(something); - - }; - } - - /* Do some QC early on - make sure append to element exist */ - if(!jQuery(ss.append_to).length) { - ss.log('The (' + ss.append_to + ') element does not exist.', 'warning'); - } - - if( ss.search_trigger && typeof ss.search_trigger === 'object' ) { - jQuery( ss.search_trigger ).click( function() { - - /* If current search is same as old, we do nothing */ - if(query.current == query.previous) { - return; - } - - jQuery.fn.super_search.do_search(); - - }); - } - - this.keyup(function() { - - query.current = element.val(); - - /* If no query, we stop scheduld search, if it scheduled */ - if(typing_timer && !query.current) { - clearTimeout(typing_timer); - return; - } - - /* If current search is same as old, we do nothing */ - if(query.current == query.previous) { - return; - } - - /* Clear timer because something was changed, and reset */ - if(typing_timer) { - clearTimeout(typing_timer); - } - - /* All is good, schedule search to happen in few seconds */ - typing_timer = setTimeout(jQuery.fn.super_search.do_search, ss.timers.search_entry); - - }); - - /* Watch for when user enteres input area */ - this.focus(function() { - jQuery.fn.super_search.ux_change(); - }); - - /* Watch for when user leaves input area */ - this.blur(function() { - jQuery.fn.super_search.ux_change(); - }); - - - /** - * Search function, fired when user is done typing - * - * @todo Need error handling. - * @todo Before send should probably accept data returned from callback function to manipulate what happens. - */ - jQuery.fn.super_search.do_search = function() { - ss.log('do_search()'); - - //** Update to latest value */ - query.current = element.val(); - - /* Build ajax post array */ - var post_data = { - action: ss.action, - limit: ss.limit, - query: query.current - } - - /* Build object for callback functions */ - cb_data = { - post_data: post_data, - settings: ss - } - - /* Remove all status-related classes */ - jQuery.each(ss.input_classes, function(slug, css_class) { - jQuery(element).removeClass(css_class); - }); - - jQuery(element).addClass(ss.input_classes.processing); - - jQuery.ajax({ - url: ss.ajax_url, - async: ss.async, - data: post_data, - beforeSend: function(jqXHR, settings) { - ss.log('do_search.beforeSend() - have callback, executing'); - - /* Load current settings into CB data */ - cb_data.settings = settings; - - if(typeof ss.beforeSend == 'function'){ - if(ss.beforeSend.call(this, cb_data)) { - return; - } - } - - }, - complete: function(jqXHR, textStatus) { - ss.log('do_search.complete( jqXHR, ' + textStatus + ' )'); - - /* Clear out processing class, regardless of success */ - jQuery(element).removeClass(ss.input_classes.processing); - - ss.log('Ajax response received.'); - - }, - success: function(data, textStatus, jqXHR) { - ss.log('do_search.success()'); - - if(typeof ss.success == 'function') { - ss.log('do_search.success() - have callback, executing'); - if(ss.success.call(data, textStatus, jqXHR)) { - return; - } - } - - /* Update "Last Searched" query */ - query.previous = query.current; - - //** Delete existing results, regardless of result to avoid confusion. */ - jQuery.fn.super_search.remove_rendered_results(); - - if(data.results) { - ss.last_results = data.results; - jQuery.fn.super_search.render_results(data.results) - } else { - jQuery(element).addClass(ss.input_classes.no_results); - } - - if(data.other) { - ss.log("Search Debug Data:" . data.debug_response); - } - - }, - error: function(jqXHR, textStatus, errorThrown) { - ss.log('do_search.error()'); - jQuery(element).addClass(ss.input_classes.error); - - }, - dataType: "json" - }); - - } - - - /** - * Remove search results. - * - */ - jQuery.fn.super_search.remove_rendered_results = function() { - ss.log('remove_rendered_results()'); - - if(ss.rendered_element && ss.rendered_element.length) { - jQuery(ss.rendered_element).fadeOut(300, function() { - /* jQuery(this).remove();*/ - }); - } - - jQuery.fn.super_search.update_dom_triggers(); - - } - - - /** - * Monitors visual changes to the DOM - * - */ - jQuery.fn.super_search.update_dom_triggers = function() { - ss.log('update_dom_triggers()'); - - /* Remove to avoid multiple triggers */ - jQuery(ss.rendered_element).off('mouseenter'); - jQuery(ss.rendered_element).off('mouseleave'); - - /* Create event to hide rearch result if user's mouse leaves the area, and update UX status */ - jQuery(ss.rendered_element).mouseenter(function() { - ux.results_over = true; - jQuery.fn.super_search.ux_change(); - }).mouseleave(function() { - ux.results_over = false; - jQuery.fn.super_search.ux_change(); - }); - - } - - /** - * Monitors user interactions with the interface, and updates any trigger events. - * - * Called on various events such as user working with input box, or leaving the input box - * - */ - jQuery.fn.super_search.ux_change = function() { - ss.log('ux_change()'); - - /* Check if user is focused on input element */ - if(jQuery(element).is(":focus")) { - ux.input_focus = true; - - /* If search box is clicked, the query has not changed, and search result exists, we show them again */ - if(query.current == query.previous && ss.rendered_element) { - ss.rendered_element.show(); - } - - } else { - ux.input_focus = false; - } - - /* If user is not focused on input, and HAS moused over results, and left, we started a timer to hide the results */ - if(ss.rendered_element && !ux.input_focus && ux.results_over === false) { - abandoned_timer = setTimeout(jQuery.fn.super_search.remove_rendered_results, ss.timers.abandonment); - } else if(abandoned_timer) { - clearTimeout(abandoned_timer); - } - - } - - - /** - * Render search results from query - * - */ - jQuery.fn.super_search.render_results = function(results) { - ss.log('render_results()'); - - /* Account for zero based keys */ - var total_results = (results.length - 1); - - html = []; - - html.push( ss.ui.response_container = '
                      ' ); - - console.log(ss.ui.response_container); - - jQuery.each(results, function(i, data) { - - var classes = []; - - if(ss.response_classes.item_class) { - classes.push(ss.response_classes.item_class); - } - - if(data.item_class) { - classes.push(data.item_class); - } - - if(i == total_results) { - classes.push('last_item'); - } - - html.push('
                    • '); - - if(data.url) { - html.push(''); - } - - html.push(data.title); - - if(data.url) { - html.push(''); - } - - - html.push('
                    • '); - }); - - html.push('
                    '); - - ss.rendered_element = jQuery(html.join('')); - - jQuery(ss.append_to).append(ss.rendered_element); - - ui.window_height = jQuery(window).height(); - ui.rendered_element = jQuery(ss.rendered_element).height(); - - if((ui.rendered_element + ss.search_result_gap) > ui.window_height) { - jQuery(ss.rendered_element).css('max-height', (ui.window_height - ss.search_result_gap) + 'px'); - jQuery(ss.rendered_element).addClass(ss.response_classes.show_scroll); - ui.rendered_element = jQuery(ss.rendered_element).height(); - } - - jQuery.fn.super_search.update_dom_triggers(); - - } - - - }; -})( jQuery ); diff --git a/vendor/udx/lib-utility/scripts/src/jquery.ui.progressbar.js b/vendor/udx/lib-utility/scripts/src/jquery.ui.progressbar.js deleted file mode 100644 index d54e583f5..000000000 --- a/vendor/udx/lib-utility/scripts/src/jquery.ui.progressbar.js +++ /dev/null @@ -1,108 +0,0 @@ -/* - * jQuery UI Progressbar 1.8.10 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Progressbar - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - */ -(function( $, undefined ) { - -$.widget( "ui.progressbar", { - options: { - value: 0, - max: 100 - }, - - min: 0, - - _create: function() { - this.element - .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) - .attr({ - role: "progressbar", - "aria-valuemin": this.min, - "aria-valuemax": this.options.max, - "aria-valuenow": this._value() - }); - - this.valueDiv = $( "
                    " ) - .appendTo( this.element ); - - this.oldValue = this._value(); - this._refreshValue(); - }, - - destroy: function() { - this.element - .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) - .removeAttr( "role" ) - .removeAttr( "aria-valuemin" ) - .removeAttr( "aria-valuemax" ) - .removeAttr( "aria-valuenow" ); - - this.valueDiv.remove(); - - $.Widget.prototype.destroy.apply( this, arguments ); - }, - - value: function( newValue ) { - if ( newValue === undefined ) { - return this._value(); - } - - this._setOption( "value", newValue ); - return this; - }, - - _setOption: function( key, value ) { - if ( key === "value" ) { - this.options.value = value; - this._refreshValue(); - if ( this._value() === this.options.max ) { - this._trigger( "complete" ); - } - } - - $.Widget.prototype._setOption.apply( this, arguments ); - }, - - _value: function() { - var val = this.options.value; - // normalize invalid value - if ( typeof val !== "number" ) { - val = 0; - } - return Math.min( this.options.max, Math.max( this.min, val ) ); - }, - - _percentage: function() { - return 100 * this._value() / this.options.max; - }, - - _refreshValue: function() { - var value = this.value(); - var percentage = this._percentage(); - - if ( this.oldValue !== value ) { - this.oldValue = value; - this._trigger( "change" ); - } - - this.valueDiv - .toggleClass( "ui-corner-right", value === this.options.max ) - .width( percentage.toFixed(0) + "%" ); - this.element.attr( "aria-valuenow", value ); - } -}); - -$.extend( $.ui.progressbar, { - version: "1.8.10" -}); - -})( jQuery ); diff --git a/vendor/udx/lib-utility/scripts/src/udx.analytics.js b/vendor/udx/lib-utility/scripts/src/udx.analytics.js deleted file mode 100644 index bf1e70a3e..000000000 --- a/vendor/udx/lib-utility/scripts/src/udx.analytics.js +++ /dev/null @@ -1,233 +0,0 @@ -/** - * Event Analytics - * - * data-event="category/action" - * data-track - * - * http://www.google-analytics.com/analytics.js - * - * @version 0.1.0 - * @returns {Object} - */ -define( 'udx.analytics', [ '//www.google-analytics.com/analytics.js' ], function analyticsModule() { - // console.debug( 'udx.analytics', 'analyticsModule' ); - - function Analytics( settings ) { - // console.debug( 'udx.analytics', 'Analytics()', settings ); - - if( 'string' === typeof settings ) { - settings = { id: settings } - } - - if( 'function' !== typeof ga ) { - return console.error( 'udx.analytics', 'The ga variable is not a function.' ) - } - - if( !settings.id ) { - return console.error( 'udx.analytics', 'No id provided.' ) - } - - ga( 'create', settings.id, { - // name: undefined, - // alwaysSendReferrer: true, - // cookieName: '_ga', - // cookieExpires: 63072000 - // clientId: undefined, - userId: settings.userId || undefined, - cookieDomain: window.location.hostname - }); - - this.setView(); - - return this; - - } - - /** - * Prototype Properties. - * - */ - Object.defineProperties( Analytics.prototype, { - ga: { - value: ga, - enumerable: true, - configurable: true, - writable: true - }, - autoLink: { - value: function autoLink() { - - ga(function( tracker ) { - - var page = tracker.get('name'); - - //var linker = new window.gaplugins.Linker( tracker ); - // var output = linker.decorate('//www.eventbrite.com'); - // ga('require', 'linker'); - // ga('linker:autoLink', ['eventbrite.com', 'www.eventbrite.com']); - // var clientId = tracker.get('clientId'); - // console.log( 'clientId', clientId ); - - }); - - return this; - - }, - enumerable: true, - configurable: true, - writable: true - }, - emit: { - /** - * Sent Event - * - * category - * - * @param eventCategory - * @param eventAction - * @param eventLabel - * @param eventValue - */ - value: function emitEvent( eventCategory, eventAction, eventLabel, eventValue ) { - // console.debug( 'udx.analytics', 'emitEvent' ); - - ga( 'send', 'event', { - eventCategory: eventCategory, - eventAction: eventAction, - eventLabel: eventLabel, - eventValue: eventValue - }); - - return this; - - }, - enumerable: true, - configurable: true, - writable: true - }, - set: { - /** - * Set Something - * - * referrer - * campaignName - * campaignId - * campaignSource - * campaignMedium - * campaignKeyword - * campaignContent - * screenResolution - * viewportSize - * - * screenName - * hostname - * title - * page - * - * - * appName - * appId - * appVersion - * - * @param key - * @param value - */ - value: function set( key, value ) { - // console.debug( 'udx.analytics', 'set' ); - - ga('set', key, value ); - - return this; - - }, - enumerable: true, - configurable: true, - writable: true - }, - sendHit: { - /** - * Send Hit - * - * Hit Types - * * pageview - * * screenview - * * event - * * transaction - * * item - * * social - * * exception - * * timing - * - */ - value: function sendHit( hitType, page ) { - // console.debug( 'udx.analytics', 'sendHit' ); - - ga( 'send', { - hitType: hitType || 'pageview', - page: page || document.location.pathname - }); - - return this; - - }, - enumerable: true, - configurable: true, - writable: true - }, - setView: { - /** - * Determine and set view type. - * - * screenview - * - * @param page - * @param title - */ - value: function setView( page, title ) { - // console.debug( 'udx.analytics', 'setView' ); - ga( 'send', 'pageview' ); - return this; - - }, - enumerable: true, - configurable: true, - writable: true - }, - setClient: { - value: function setClient() {}, - enumerable: true, - configurable: true, - writable: true - }, - setSocial: { - value: function setSocial() {}, - enumerable: true, - configurable: true, - writable: true - } - }); - - /** - * Constructor Properties. - * - */ - Object.defineProperties( Analytics, { - create: { - /** - * Create Analytics Session - * - * @param settings - */ - value: function create( settings ) { - return new Analytics( settings ); - }, - enumerable: true, - configurable: true, - writable: true - } - }) - - return Analytics; - -}); - diff --git a/vendor/udx/lib-utility/scripts/src/udx.event.js b/vendor/udx/lib-utility/scripts/src/udx.event.js deleted file mode 100644 index dee120693..000000000 --- a/vendor/udx/lib-utility/scripts/src/udx.event.js +++ /dev/null @@ -1,561 +0,0 @@ -/** - * UD Event - * - * Event Emitter handler. - * - * @original https://github.com/hij1nx/EventEmitter2/ - * @version 0.4 - * @author team@UD - */ - -define( 'udx.event', function() { - - var ud = ( typeof ud === 'object' ) ? ud : {}; - - var isArray = Array.isArray ? Array.isArray : function _isArray( obj ) { - return Object.prototype.toString.call( obj ) === "[object Array]"; - }; - - function init() { - this._events = {}; - - if( this._conf ) { - configure.call( this, this._conf ); - } - - } - - function configure( conf ) { - - this._conf = conf || ud.event.prototype.defaults; - - console.log( 'configure', this._conf ); - if( this._conf.wildcard ) { - this.listenerTree = {}; - } - - } - - // - // Attention, function return type now is array, always ! - // It has zero elements if no any matches found and one or more - // elements (leafs) if there are matches - // - function searchListenerTree( handlers, type, tree, i ) { - if( !tree ) { - return []; - } - var listeners = [], leaf, len, branch, xTree, xxTree, isolatedBranch, endReached, typeLength = type.length, currentType = type[i], nextType = type[i + 1]; - if( i === typeLength && tree._listeners ) { - // - // If at the end of the event(s) list and the tree has listeners - // invoke those listeners. - // - if( typeof tree._listeners === 'function' ) { - handlers && handlers.push( tree._listeners ); - return [tree]; - } else { - for( leaf = 0, len = tree._listeners.length; leaf < len; leaf++ ) { - handlers && handlers.push( tree._listeners[leaf] ); - } - return [tree]; - } - } - - if( (currentType === '*' || currentType === '**') || tree[currentType] ) { - // - // If the event emitted is '*' at this part - // or there is a concrete match at this patch - // - if( currentType === '*' ) { - for( branch in tree ) { - if( branch !== '_listeners' && tree.hasOwnProperty( branch ) ) { - listeners = listeners.concat( searchListenerTree( handlers, type, tree[branch], i + 1 ) ); - } - } - return listeners; - } else if( currentType === '**' ) { - endReached = (i + 1 === typeLength || (i + 2 === typeLength && nextType === '*')); - if( endReached && tree._listeners ) { - // The next element has a _listeners, add it to the handlers. - listeners = listeners.concat( searchListenerTree( handlers, type, tree, typeLength ) ); - } - - for( branch in tree ) { - if( branch !== '_listeners' && tree.hasOwnProperty( branch ) ) { - if( branch === '*' || branch === '**' ) { - if( tree[branch]._listeners && !endReached ) { - listeners = listeners.concat( searchListenerTree( handlers, type, tree[branch], typeLength ) ); - } - listeners = listeners.concat( searchListenerTree( handlers, type, tree[branch], i ) ); - } else if( branch === nextType ) { - listeners = listeners.concat( searchListenerTree( handlers, type, tree[branch], i + 2 ) ); - } else { - // No match on this one, shift into the tree but not in the type array. - listeners = listeners.concat( searchListenerTree( handlers, type, tree[branch], i ) ); - } - } - } - return listeners; - } - - listeners = listeners.concat( searchListenerTree( handlers, type, tree[currentType], i + 1 ) ); - } - - xTree = tree['*']; - if( xTree ) { - // - // If the listener tree will allow any match for this part, - // then recursively explore all branches of the tree - // - searchListenerTree( handlers, type, xTree, i + 1 ); - } - - xxTree = tree['**']; - if( xxTree ) { - if( i < typeLength ) { - if( xxTree._listeners ) { - // If we have a listener on a '**', it will catch all, so add its handler. - searchListenerTree( handlers, type, xxTree, typeLength ); - } - - // Build arrays of matching next branches and others. - for( branch in xxTree ) { - if( branch !== '_listeners' && xxTree.hasOwnProperty( branch ) ) { - if( branch === nextType ) { - // We know the next element will match, so jump twice. - searchListenerTree( handlers, type, xxTree[branch], i + 2 ); - } else if( branch === currentType ) { - // Current node matches, move into the tree. - searchListenerTree( handlers, type, xxTree[branch], i + 1 ); - } else { - isolatedBranch = {}; - isolatedBranch[branch] = xxTree[branch]; - searchListenerTree( handlers, type, { '**': isolatedBranch }, i + 1 ); - } - } - } - } else if( xxTree._listeners ) { - // We have reached the end and still on a '**' - searchListenerTree( handlers, type, xxTree, typeLength ); - } else if( xxTree['*'] && xxTree['*']._listeners ) { - searchListenerTree( handlers, type, xxTree['*'], typeLength ); - } - } - - return listeners; - } - - function growListenerTree( type, listener ) { - - type = typeof type === 'string' ? type.split( this._conf.delimiter ) : type.slice(); - - // - // Looks for two consecutive '**', if so, don't add the event at all. - // - for( var i = 0, len = type.length; i + 1 < len; i++ ) { - if( type[i] === '**' && type[i + 1] === '**' ) { - return; - } - } - - var tree = this.listenerTree; - var name = type.shift(); - - while( name ) { - - if( !tree[name] ) { - tree[name] = {}; - } - - tree = tree[name]; - - if( type.length === 0 ) { - - if( !tree._listeners ) { - tree._listeners = listener; - } - - else if( typeof tree._listeners === 'function' ) { - tree._listeners = [tree._listeners, listener]; - } - - else if( isArray( tree._listeners ) ) { - - tree._listeners.push( listener ); - - if( !tree._listeners.warned ) { - - var m = this.defaultMaxListeners; - - if( typeof this._events.maxListeners !== 'undefined' ) { - m = this._events.maxListeners; - } - - if( m > 0 && tree._listeners.length > m ) { - - tree._listeners.warned = true; - console.error( '(node) warning: possible ud.event memory ' + 'leak detected. %d listeners added. ' + 'Use emitter.setMaxListeners() to increase limit.', tree._listeners.length ); - console.trace(); - } - } - } - return true; - } - name = type.shift(); - } - return true; - }; - - /** - * Constructor - * - */ - ud.event = function( conf ) { - this._events = {}; - configure.call( this, conf ); - } - - /** - * Bestow Event functionality into another object - * - * @method bestow - */ - ud.event.bestow = function bestow( target, config ) { - - // Create new instance - var _event = new ud.event( config ); - - // Ensure Target is an Object - target = target && 'object' === typeof target ? target : {}; - - for( var key in _event ) { - - if( 'function' === typeof Object.defineProperty ) { - - Object.defineProperty( target, key, { - 'value': _event[ key ], - 'enumerable': 'function' === typeof _event[ key ] ? false : true, - 'writable': 'function' === typeof _event[ key ] ? false : true - } ); - - } else { - target[ key ] = _event[ key ]; - } - - } - - return target; - - } - - ud.event.prototype.defaults = { - wildcard: true, - defaultMaxListeners: 20, - delimiter: '.' - } - - ud.event.prototype.setMaxListeners = function( n ) { - this._events || init.call( this ); - this._events.maxListeners = n; - if( !this._conf ) this._conf = {}; - this._conf.maxListeners = n; - }; - - ud.event.prototype.event = ''; - - ud.event.prototype.once = function once( event, fn ) { - this.many( event, 1, fn ); - return this; - }; - - ud.event.prototype.many = function many( event, ttl, fn ) { - var self = this; - - if( typeof fn !== 'function' ) { - throw new Error( 'many only accepts instances of Function' ); - } - - function listener() { - if( --ttl === 0 ) { - self.off( event, listener ); - } - fn.apply( this, arguments ); - }; - - listener._origin = fn; - - this.on( event, listener ); - - return self; - }; - - ud.event.prototype.emit = function() { - - this._events || init.call( this ); - - var type = arguments[0]; - - // Loop through the *_all* functions and invoke them. - if( this._all ) { - var l = arguments.length; - var args = new Array( l - 1 ); - for( var i = 1; i < l; i++ ) args[i - 1] = arguments[i]; - for( i = 0, l = this._all.length; i < l; i++ ) { - this.event = type; - this._all[i].apply( this, args ); - } - } - - // If there is no 'error' event listener then throw. - if( type === 'error' ) { - - if( !this._all && !this._events.error && !(this._conf.wildcard && this.listenerTree.error) ) { - - if( arguments[1] instanceof Error ) { - throw arguments[1]; // Unhandled 'error' event - } else { - throw new Error( "Uncaught, unspecified 'error' event." ); - } - return false; - } - } - - var handler; - - if( this._conf.wildcard ) { - handler = []; - var ns = typeof type === 'string' ? type.split( this._conf.delimiter ) : type.slice(); - searchListenerTree.call( this, handler, ns, this.listenerTree, 0 ); - } else { - handler = this._events[type]; - } - - if( typeof handler === 'function' ) { - this.event = type; - if( arguments.length === 1 ) { - handler.call( this ); - } else if( arguments.length > 1 ) - switch( arguments.length ) { - case 2: - handler.call( this, arguments[1] ); - break; - case 3: - handler.call( this, arguments[1], arguments[2] ); - break; - // slower - default: - var l = arguments.length; - var args = new Array( l - 1 ); - for( var i = 1; i < l; i++ ) args[i - 1] = arguments[i]; - handler.apply( this, args ); - } - return true; - } else if( handler ) { - var l = arguments.length; - var args = new Array( l - 1 ); - for( var i = 1; i < l; i++ ) args[i - 1] = arguments[i]; - - var listeners = handler.slice(); - for( var i = 0, l = listeners.length; i < l; i++ ) { - this.event = type; - listeners[i].apply( this, args ); - } - return (listeners.length > 0) || this._all; - } else { - return this._all; - } - - }; - - ud.event.prototype.on = function( type, listener ) { - - if( typeof type === 'function' ) { - this.onAny( type ); - return this; - } - - if( typeof listener !== 'function' ) { - throw new Error( 'on only accepts instances of Function' ); - } - this._events || init.call( this ); - - if( this._conf.wildcard ) { - growListenerTree.call( this, type, listener ); - return this; - } - - if( !this._events[type] ) { - // Optimize the case of one listener. Don't need the extra array object. - this._events[type] = listener; - } else if( typeof this._events[type] === 'function' ) { - // Adding the second element, need to change to array. - this._events[type] = [this._events[type], listener]; - } else if( isArray( this._events[type] ) ) { - // If we've already got an array, just append. - this._events[type].push( listener ); - - // Check for listener leak - if( !this._events[type].warned ) { - - var m = this.defaultMaxListeners; - - if( typeof this._events.maxListeners !== 'undefined' ) { - m = this._events.maxListeners; - } - - if( m > 0 && this._events[type].length > m ) { - - this._events[type].warned = true; - console.error( '(node) warning: possible ud.event memory ' + 'leak detected. %d listeners added. ' + 'Use emitter.setMaxListeners() to increase limit.', this._events[type].length ); - console.trace(); - } - } - } - return this; - }; - - ud.event.prototype.onAny = function( fn ) { - - if( !this._all ) { - this._all = []; - } - - if( typeof fn !== 'function' ) { - throw new Error( 'onAny only accepts instances of Function' ); - } - - // Add the function to the event listener collection. - this._all.push( fn ); - return this; - }; - - ud.event.prototype.addListener = ud.event.prototype.on; - - ud.event.prototype.off = function( type, listener ) { - if( typeof listener !== 'function' ) { - throw new Error( 'removeListener only takes instances of Function' ); - } - - var handlers, leafs = []; - - if( this._conf.wildcard ) { - var ns = typeof type === 'string' ? type.split( this._conf.delimiter ) : type.slice(); - leafs = searchListenerTree.call( this, null, ns, this.listenerTree, 0 ); - } else { - // does not use listeners(), so no side effect of creating _events[type] - if( !this._events[type] ) return this; - handlers = this._events[type]; - leafs.push( {_listeners: handlers} ); - } - - for( var iLeaf = 0; iLeaf < leafs.length; iLeaf++ ) { - var leaf = leafs[iLeaf]; - handlers = leaf._listeners; - if( isArray( handlers ) ) { - - var position = -1; - - for( var i = 0, length = handlers.length; i < length; i++ ) { - if( handlers[i] === listener || (handlers[i].listener && handlers[i].listener === listener) || (handlers[i]._origin && handlers[i]._origin === listener) ) { - position = i; - break; - } - } - - if( position < 0 ) { - return this; - } - - if( this._conf.wildcard ) { - leaf._listeners.splice( position, 1 ) - } else { - this._events[type].splice( position, 1 ); - } - - if( handlers.length === 0 ) { - if( this._conf.wildcard ) { - delete leaf._listeners; - } else { - delete this._events[type]; - } - } - } else if( handlers === listener || (handlers.listener && handlers.listener === listener) || (handlers._origin && handlers._origin === listener) ) { - if( this._conf.wildcard ) { - delete leaf._listeners; - } else { - delete this._events[type]; - } - } - } - - return this; - }; - - ud.event.prototype.offAny = function( fn ) { - var i = 0, l = 0, fns; - if( fn && this._all && this._all.length > 0 ) { - fns = this._all; - for( i = 0, l = fns.length; i < l; i++ ) { - if( fn === fns[i] ) { - fns.splice( i, 1 ); - return this; - } - } - } else { - this._all = []; - } - return this; - }; - - ud.event.prototype.removeListener = ud.event.prototype.off; - - ud.event.prototype.removeAllListeners = function( type ) { - if( arguments.length === 0 ) { - !this._events || init.call( this ); - return this; - } - - if( this._conf.wildcard ) { - var ns = typeof type === 'string' ? type.split( this._conf.delimiter ) : type.slice(); - var leafs = searchListenerTree.call( this, null, ns, this.listenerTree, 0 ); - - for( var iLeaf = 0; iLeaf < leafs.length; iLeaf++ ) { - var leaf = leafs[iLeaf]; - leaf._listeners = null; - } - } else { - if( !this._events[type] ) return this; - this._events[type] = null; - } - return this; - }; - - ud.event.prototype.listeners = function( type ) { - if( this._conf.wildcard ) { - var handlers = []; - var ns = typeof type === 'string' ? type.split( this._conf.delimiter ) : type.slice(); - searchListenerTree.call( this, handlers, ns, this.listenerTree, 0 ); - return handlers; - } - - this._events || init.call( this ); - - if( !this._events[type] ) this._events[type] = []; - if( !isArray( this._events[type] ) ) { - this._events[type] = [this._events[type]]; - } - return this._events[type]; - }; - - ud.event.prototype.listenersAny = function() { - - if( this._all ) { - return this._all; - } else { - return []; - } - - }; - -}); diff --git a/vendor/udx/lib-utility/scripts/src/udx.filter.js b/vendor/udx/lib-utility/scripts/src/udx.filter.js deleted file mode 100644 index e439010a4..000000000 --- a/vendor/udx/lib-utility/scripts/src/udx.filter.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Migrated from ud.global.js - * - */ -define( 'udx.filter', function() { - - return { - - /** - * Applies filter for the passed object - * - * @param name. string. required. Name of filter - * @param obj. object. required. Object which will go through called filter - * @author peshkov@UD - */ - apply_filter: function( name, obj ) { - - /* Filter's name and callback are required */ - if( typeof obj === 'undefined' || typeof name === 'undefined' || typeof name !== 'string' ) return obj; - /* jQuery must be inititialized */ - if( typeof jQuery === 'undefined' ) return obj; - /* Called filter must exist */ - if( typeof window.__ud_filters === 'undefined' || typeof window.__ud_filters[ name ] === 'undefined' ) return obj; - - jQuery.each( window.__ud_filters[ name ], function( i, e ) { - if( typeof e === 'function' ) { - obj = e( obj ); - } else if( typeof e === 'object' ) { - if( typeof obj !== 'object' ) return false; - obj = jQuery.extend( true, obj, e ); - } - } ); - return obj; - }, - - /** - * Adds filter to filters array. - * - * @param name. string. required. Name of filter. - * @param calback. object|function. required. Filter which will be used on filter applying - * @author peshkov@UD - */ - add_filter: function( name, callback ) { - /* Filter's name and callback are required */ - if( typeof callback === 'undefined' || typeof name === 'undefined' || typeof name !== 'string' ) return; - /* Add object to filter */ - if( typeof window.__ud_filters === 'undefined' ) window.__ud_filters = {}; - if( typeof window.__ud_filters[ name ] === 'undefined' ) window.__ud_filters[ name ] = []; - window.__ud_filters[ name ].push( callback ); - } - } - -} ); - diff --git a/vendor/udx/lib-utility/scripts/src/udx.fleck.js b/vendor/udx/lib-utility/scripts/src/udx.fleck.js deleted file mode 100644 index 26dcfdc00..000000000 --- a/vendor/udx/lib-utility/scripts/src/udx.fleck.js +++ /dev/null @@ -1,214 +0,0 @@ -/** - * fleck - functional style string inflections - * https://github.com/trek/fleck - * copyright Trek Glowacki - * MIT License - * - * @version 1.0 - * @description functional style string inflections - * @package fleck - * @author Trek Glowacki - */ - -!function (name, definition) { - if (typeof module != 'undefined') module.exports = definition() - else if (typeof define == 'function' && typeof define.amd == 'object') define(definition) - else this[name] = definition() -}('fleck', function () { - - var lib = { - // plural rules, singular rules, and starting uncountables - // from http://code.google.com/p/inflection-js/ - // with corrections for ordering and spelling - pluralRules: [ - [new RegExp('(m)an$', 'gi'), '$1en'], - [new RegExp('(pe)rson$', 'gi'), '$1ople'], - [new RegExp('(child)$', 'gi'), '$1ren'], - [new RegExp('^(ox)$', 'gi'), '$1en'], - [new RegExp('(ax|test)is$', 'gi'), '$1es'], - [new RegExp('(octop|vir)us$', 'gi'), '$1i'], - [new RegExp('(alias|status)$', 'gi'), '$1es'], - [new RegExp('(bu)s$', 'gi'), '$1ses'], - [new RegExp('(buffal|tomat|potat)o$', 'gi'), '$1oes'], - [new RegExp('([ti])um$', 'gi'), '$1a'], - [new RegExp('sis$', 'gi'), 'ses'], - [new RegExp('(?:([^f])fe|([lr])f)$', 'gi'), '$1$2ves'], - [new RegExp('(hive)$', 'gi'), '$1s'], - [new RegExp('([^aeiouy]|qu)y$', 'gi'), '$1ies'], - [new RegExp('(matr|vert|ind)ix|ex$', 'gi'), '$1ices'], - [new RegExp('(x|ch|ss|sh)$', 'gi'), '$1es'], - [new RegExp('([m|l])ouse$', 'gi'), '$1ice'], - [new RegExp('(quiz)$', 'gi'), '$1zes'], - [new RegExp('s$', 'gi'), 's'], - [new RegExp('$', 'gi'), 's'] - ], - singularRules: [ - [new RegExp('(m)en$', 'gi'), '$1an'], - [new RegExp('(pe)ople$', 'gi'), '$1rson'], - [new RegExp('(child)ren$', 'gi'), '$1'], - [new RegExp('([ti])a$', 'gi'), '$1um'], - [new RegExp('((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$','gi'), '$1$2sis'], - [new RegExp('(hive)s$', 'gi'), '$1'], - [new RegExp('(tive)s$', 'gi'), '$1'], - [new RegExp('(curve)s$', 'gi'), '$1'], - [new RegExp('([lr])ves$', 'gi'), '$1f'], - [new RegExp('([^fo])ves$', 'gi'), '$1fe'], - [new RegExp('([^aeiouy]|qu)ies$', 'gi'), '$1y'], - [new RegExp('(s)eries$', 'gi'), '$1eries'], - [new RegExp('(m)ovies$', 'gi'), '$1ovie'], - [new RegExp('(x|ch|ss|sh)es$', 'gi'), '$1'], - [new RegExp('([m|l])ice$', 'gi'), '$1ouse'], - [new RegExp('(bus)es$', 'gi'), '$1'], - [new RegExp('(o)es$', 'gi'), '$1'], - [new RegExp('(shoe)s$', 'gi'), '$1'], - [new RegExp('(cris|ax|test)es$', 'gi'), '$1is'], - [new RegExp('(octop|vir)i$', 'gi'), '$1us'], - [new RegExp('(alias|status)es$', 'gi'), '$1'], - [new RegExp('^(ox)en', 'gi'), '$1'], - [new RegExp('(vert|ind)ices$', 'gi'), '$1ex'], - [new RegExp('(matr)ices$', 'gi'), '$1ix'], - [new RegExp('(quiz)zes$', 'gi'), '$1'], - [new RegExp('s$', 'gi'), ''] - ], - uncountableWords: { - 'equipment': true, - 'information': true, - 'rice': true, - 'money': true, - 'species': true, - 'series':true, - 'fish':true, - 'sheep':true, - 'moose':true, - 'deer':true, - 'news':true - }, - // Chain multiple inflections into a signle call - // Examples: - // lib.inflect(' posts', 'strip', 'singularize', 'capitalize') == 'Post' - inflect: function(str){ - for (var i = 1, l = arguments.length; i < l; i++) { - str = lib[arguments[i]](str); - }; - - return str; - }, - // Uppercases the first letter and lowercases all other letters - // Examples: - // lib.capitalize("message_properties") == "Message_properties" - // lib.capitalize("message properties") == "Message properties" - capitalize: function(str) { - return str.charAt(0).toUpperCase() + str.substring(1).toLowerCase(); - }, - // lib.camelize("message_properties") == "messageProperties" - // lib.camelize('-moz-border-radius') == 'mozBorderRadius' - // lib.camelize("message_properties", true) == "MessageProperties" - camelize: function(str, upper){ - if (upper) { return lib.upperCamelize(str) }; - return str.replace(/[-_]+(.)?/g, function(match, chr) { - return chr ? chr.toUpperCase() : ''; - }); - }, - // lib.upperCamelize("message_properties") == "MessageProperties" - upperCamelize: function(str){ - return lib.camelize(lib.capitalize(str)); - }, - // Replaces all spaces or underscores with dashes - // Examples: - // lib.dasherize("message_properties") == "message-properties" - // lib.dasherize("Message properties") == "Message-properties" - dasherize: function(str){ - return str.replace(/\s|_/g, '-'); - }, - // turns number or string formatted number into ordinalize version - // Examples: - // lib.ordinalize(4) == "4th" - // lib.ordinalize("13") == "13th" - // lib.ordinalize("122") == "122nd" - ordinalize: function(str){ - var isTeen, r, n; - n = parseInt(str, 10) % 100; - isTeen = { 11: true, 12: true, 13: true}[n]; - if(isTeen) {return str + 'th'}; - n = parseInt(str, 10) % 10 - switch(n) { - case 1: - r = str + 'st'; - break; - case 2: - r = str + 'nd'; - break; - case 3: - r = str + 'rd'; - break; - default: - r = str + 'th'; - } - return r; - }, - pluralize: function(str){ - var uncountable = lib.uncountableWords[str.toLowerCase()]; - if (uncountable) { - return str; - }; - var rules = lib.pluralRules; - for(var i = 0, l = rules.length; i < l; i++){ - if (str.match(rules[i][0])) { - str = str.replace(rules[i][0], rules[i][1]); - break; - }; - } - - return str; - }, - singularize: function(str){ - var uncountable = lib.uncountableWords[str.toLowerCase()]; - if (uncountable) { - return str; - }; - var rules = lib.singularRules; - for(var i = 0, l = rules.length; i < l; i++){ - if (str.match(rules[i][0])) { - str = str.replace(rules[i][0], rules[i][1]); - break; - }; - } - - return str; - }, - // Removes leading and trailing whitespace - // Examples: - // lib.strip(" hello world! ") == "hello world!" - strip: function(str){ - // implementation from Prototype.js - return str.replace(/^\s+/, '').replace(/\s+$/, ''); - }, - // Converts a camelized string into a series of words separated by an - // underscore (`_`). - // Examples - // lib.underscore('borderBottomWidth') == "border_bottom_width" - // lib.underscore('border-bottom-width') == "border_bottom_width" - // lib.underscore('Foo::Bar') == "foo_bar" - // lib.underscore('Foo.Bar') == "foo_bar" - underscore: function(str){ - // implementation from Prototype.js - return str.replace(/::/g, '_') - .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') - .replace(/([a-z\d])([A-Z])/g, '$1_$2') - .replace(/[-\.]/g, '_') - .toLowerCase(); - }, - - // add an uncountable word - // fleck.uncountable('ninja', 'tsumani'); - uncountable: function(){ - for(var i=0,l=arguments.length; i 0 && !jQuery( '#' + self.modules[i].id ).length > 0 ) { - var content_wrapper = '
                    '; - try { content = self.listeners.add_content_wrapper( content_wrapper, self.modules[i], self ) } - catch( e ) { self.show_error( 'add_content_wrapper', e ) } - if( typeof content_wrapper === 'string' ) { - jQuery( self.ui.content ).append( content_wrapper ); - } - } - break; - - case 'link': - - break; - - } - - /* Add menu item to HTML */ - if( jQuery( self.modules[i].menu ).length > 0 ) { - var href = self.is_url( self.modules[i].href ) ? self.modules[i].href : '#' + self.modules[i].id; - var menu_item = '' + self.modules[i].name + ''; - try { menu_item = self.listeners.add_menu_item( menu_item, self.modules[i], self ) } - catch( e ) { self.show_error( 'add_menu_item', e ) } - if( typeof menu_item === 'string' ) { - menu_item = jQuery( menu_item ); - menu_item.each( function( index, e ) { - var a = typeof jQuery( e ).attr( 'href' ) !== 'undefined' ? jQuery( e ) : jQuery( 'a', e ); - if( a.length > 0 ) { - a.attr( 'module', i ).attr( 'type', self.modules[i].type ); - } - } ); - jQuery( self.modules[i].menu ).append( menu_item ); - } - } - - } - - /* Loads required CSS */ - if( typeof self._required.css === 'object' ) { - jQuery.each( self._required.css, function( style, url ) { - ud.load.css( url ); - } ); - } - - /* Load all required files before continue */ - ud.load.js( self._required.js, function() { - - /* Initialize Router */ - self.router = self.router(); - - /** - * Determine if we need to load addtional javascript/css files. - * Specific module javascript/css files must be loaded before continue! - */ - var _required = {}; - - jQuery.each( self.models, function( i, m ) { - if( typeof m === 'object' && typeof m._required === 'object' ) { - if( typeof m._required.js === 'object' ) { - jQuery.each( m._required.js, function( script, url ) { - _required[ script ] = url; - } ); - } - if( typeof m._required.css === 'object' ) { - jQuery.each( m._required.css, function( style, url ) { - /* Load module's CSS */ - ud.load.css( url ); - } ); - } - } - } ); - - Object.size = function( obj ) { - var size = 0, key; - for( key in obj ) { if( obj.hasOwnProperty( key ) ) size++; } - return size; - }; - - if( Object.size( _required ) > 0 ) { - ud.load.js( _required, self._run ); - } else { - self._run(); - } - - } ); - - } - - /** - * Runs application. - * - * It does the following steps: - * 1. tries connecting to socket; - * 2. runs router. - * - * Must be called after init. - * - * @author peshkov@UD - */ - self._run = function() { - - if( self.rendered ) return null; - - /* Determine is socket arguments are set */ - if( self.socket && typeof self.socket === 'object' ) { - - self.core.socket( self.socket, function( socket ) { - self.socket = socket; - try { self.listeners.socket_connected( self ) } - catch( e ) { self.show_error( 'socket_connected', e ) } - /* Run App */ - self.router.run(); - } ); - - } else { - - /* Run App */ - self.router.run(); - - // console.log( self ); - - } - - } - - /** - * Sets ( inits ) Router - * - * @author peshkov@UD - */ - self.router = function() { - - /* Pagination. History implementation. */ - return new Sammy( function() { - - this.home = self.url; - - this.loading = false; - - this.get( /\#(.*)/, function( router ) { - - /* Looks like router did not finish previous process. */ - if( router.app.loading ) { - return null; - } - router.app.loading = true; - - /* Parse query hash and set params */ - var params = { - 'section' : false, - 'args' : [] - }; - jQuery.each( router.params[ 'splat' ][0].split( '/' ), function( i,e ) { - if( e.length == 0 ) return null; - else if ( !params.section ) params.section = e; - else params.args.push( e ); - } ); - - /* Initialize Knockout View Model if it's undefined */ - var module = typeof self.sections[ params.section ] !== 'undefined' ? self.sections[ params.section ] : false; - - /* Get the default ( home ) section if the called one doesn't exist */ - if( !module || typeof self.modules[ module ] === 'undefined' ) { - self.show_error( 'Module with the hash \'' + params.section + '\' doesn\'t exist.', - 'Sammy.get( \'#:module\' )' ); - router.app.loading = false; - if( typeof self.modules[ self.default_module ] !== 'undefined' && typeof self.sections[ self.modules[ self.default_module ].id ] !== 'undefined' ) { - router.app.runRoute( 'get', '#' + self.modules[ self.default_module ].id ); - } - return null; - } - - if( self.modules[ module ].view_model === null || typeof self.modules[ module ].view_model !== 'object' ) { - self.modules[ module ].view_model = self.core.view_model( { - 'scope': self, - 'model': typeof self.models[ module ] === 'object' ? self.models[ module ] : {}, - 'view': self.modules[ module ].view, - 'args': jQuery.extend( self.modules[ module ].args, { 'module': module } ), - 'container': '#' + params.section - } ); - /** - * Timeout is used to prevent the issues with socket requests. Hope, that 300msec is always enought. - * I have no idea why it happens, but when page loads on specific section which is using socket request on init, - * socket doesn't send response. Probably the issue is related to socket object links ( scope ). - * peshkov@UD - */ - setTimeout( function() { - self.modules[ module ].view_model.apply( params.args ); - }, 300 ); - } else { - self.modules[ module ].view_model.update( params.args ); - } - - /* Determine if the module is already selected we stop process here. */ - var selected_section = self.sections[ params.section ]; - if( typeof self.selected_section !== 'undefined' && selected_section === self.selected_section ) { - // Finish process - router.app.loading = false; - return null; - } - - self.selected_section = selected_section; - - for( var a in self.sections ) { - if( typeof self.sections[a] !== 'function' ) { - jQuery( 'a[href="#' + a + '"]' ).removeClass( 'selected' ); - } - } - - for( var a in self.sections ) { - if( typeof self.sections[a] !== 'function' ) { - var section = jQuery( '#' + a ).get( 0 ); - jQuery( section ).hide(); - if( jQuery( section ).attr( 'id' ) === params.section ) { - if( self.modules[ module ].parent && typeof self.modules[ self.modules[ module ].parent ] === 'object' ) { - jQuery( 'a[href="#' + self.modules[ self.modules[ module ].parent ].id + '"][type="module"]' ).addClass( 'selected' ); - } - jQuery( 'a[href="#' + params.section + '"]' ).addClass( 'selected' ); - jQuery( section ).fadeIn( 500, function() { - jQuery( this ).show( 500, function() { - // Finish process - router.app.loading = false; - } ); - } ); - } - } - } - - try { self.listeners.section_selected( params.section, self ) } - catch( e ) { self.show_error( 'section_selected', e ) } - - if( !self.rendered ) { - try { self.listeners.rendered( self ) } - catch( e ) { self.show_error( 'rendered', e ) } - self.rendered = true; - } - - }); - - this.get( '', function( router ) { - var reg = new RegExp( "(https?|ftp):", 'g' ); - if( router.app.home.replace( reg, '' ) !== location.href.replace( reg, '' ) ) { - window.location = location.href; - } else { - if( self.default_module && jQuery( '#' + self.default_module ).length > 0 ) { - router.app.runRoute( 'get', '#' + self.default_module ); - } else { - //Ignore. - } - } - } ); - - }); - - } - - this.__ = self; - - self._init(); - - return this.__; - -} \ No newline at end of file diff --git a/vendor/udx/lib-utility/scripts/src/udx.happ.json_editor.js b/vendor/udx/lib-utility/scripts/src/udx.happ.json_editor.js deleted file mode 100644 index 2a0ff4fe1..000000000 --- a/vendor/udx/lib-utility/scripts/src/udx.happ.json_editor.js +++ /dev/null @@ -1,196 +0,0 @@ -/** - * JSON Editor - * It's just a wrapper for ud.json.editor - * - loads ud.json.editor library and styles - * - adds schema and validation functionality. - * - * @required ud.loader, ud.async - * @author peshkov@UD - */ - -Application.define( 'core.json_editor', function( args ) { - - /* Set arguments */ - args = jQuery.extend( true, { - 'container' : false, // ID of DOM element where editor/formatter will be initialized - 'instance' : 'editor', // Available value: 'editor', 'formatter' - 'options' : {}, - 'json' : null, - 'callback' : function( editor ) { return editor; }, // Object can be got only using callback! - // Set of actions listeners which are fired on json editor events - 'actions' : { - /** - * Called on Save event. - * @param object json - */ - 'save': function( json ) { - return null; - }, - /** - * Called after validation process - * @param object result Validation's response - */ - 'validate': function( result ) { - return null; - } - } - }, typeof args === 'object' ? args : {} ); - - /* Check container argument */ - var container = typeof args.container === 'object' ? args.container.get(0) : document.getElementById( args.container.replace( '#', '' ) ); - - /** - * - */ - var editor = function( container, args ) { - - var self = this; - - self._args = typeof args.options == 'object' ? args.options : {}; - - /* */ - self.options = jQuery.extend( true, { - 'change' : function() { return null }, // Set a callback method triggered when the contents of the JSONEditor change. Called without parameters. - 'history' : true, // Enables history, adds a button Undo and Redo to the menu of the JSONEditor. Only applicable when mode is 'editor'. - 'mode' : 'editor', // Set the editor mode. Available values: 'editor', 'viewer', or 'form'. In 'viewer' mode, the data and datastructure is read-only. In 'form' mode, only the value can be changed, the datastructure is read-only. - //'name' : 'name_' + ( Math.ceil( Math.random() * 10000 ) ), // Initial field name for the root node. Can also be set using JSONEditor.setName(name) - 'search' : true // Enables a search box in the upper right corner of the JSONEditor. True by default. - }, typeof args.options == 'object' ? args.options : {} ); - - /* */ - self.__ = new JSONEditor (container, self.options, typeof self._args.json != 'undefined' ? self._args.json : null ); - - /* */ - self.schema = false; - - /** - * - */ - self.save = function() { - if( self.schema && !self.validate() ) { - return false; - } - /* Special Handlers can be added here */ - try { self._args.actions.save( schema.get() ); } catch( error ) { return false; } - return true; - } - - - /** - * - */ - self.set = function ( json, options ) { - - options = jQuery.extend( true, { - 'name' : null, - 'schema' : null - }, typeof options === 'object' ? options : {} ); - - self.schema = typeof options.schema === 'object' && options.schema != null ? options.schema : false; - if( self.schema ) { - jQuery( 'button.jsoneditor-validate-object', container ).show(); - } else { - jQuery( 'button.jsoneditor-validate-object', container ).hide(); - } - - if( typeof options.name === 'string' ) { - return self.__.set( json, options.name ); - } else { - return self.__.set( json ); - } - - } - - /** - * - */ - self.get = function () { - console.log( 'JSON EDITOR: GET' ); - return self.__.get(); - } - - - /** - * Validates the current object if schema is set and returns boolean - * - * @uses ud.json.validate - */ - self.validate = function () { - if( typeof self.schema !== 'object' || typeof validate === 'undefined' ) { - return true; - } - self.last_validation = validate( self.get(), self.schema ); - /* Special Handlers can be added here */ - try { self._args.actions.validate( self.last_validation ); } catch( error ) { return false; } - return self.last_validation.valid; - } - - /** - * - */ - self._update_menu = function( enable ) { - var save_button = jQuery( 'button.jsoneditor-save-object', container ); - - var validate_button = document.createElement( 'button' ); - validate_button.title = 'Validate'; - validate_button.className = 'jsoneditor-menu jsoneditor-validate-object'; - validate_button.appendChild( document.createTextNode( "Validate" ) ); - validate_button.style.display = 'none'; - validate_button.onclick = function(){ self.validate(); } - - save_button.click( function() { self.save(); } ).after( validate_button ); - } - - - /* Add default scope's properties to our wrapper */ - jQuery.each( self.__, function( i, e ) { - if( typeof self[ i ] === 'undefined' ) { - self[ i ] = e; - } - } ); - - self._update_menu(); - - }; - - /* */ - async.parallel( { - // Load required scripts - 'js' : function( callback ) { - - ud.load.js( { - 'JSONEditor' : '//ud-cdn.com/js/ud.json.editor/latest/ud.json.editor.js', - 'validate' : '//ud-cdn.com/js/ud.json.validate/1.0/ud.json.validate.js' - }, function() { - callback( null, true ); - }); - }, - // Loads required CSS if needed - 'css' : function( callback ) { - window._flags = typeof window._flags !== 'undefined' ? window._flags : {}; - if( typeof window._flags.json_editor_css === 'undefined' || !window._flags.json_editor_css ) { - ud.load.css( '//ud-cdn.com/js/ud.json.editor/latest/assets/ud.json.editor.css' ); - window._flags.json_editor_css = true; - } - callback( null, true ); - } - }, function( err ) { - - if ( typeof args.callback === 'function' ) { - /* */ - var instance = null; - switch( args.instance ) { - case 'editor': - instance = new editor( container, args ); - break; - - case 'formatter': - instance = new JSONformatter ( container, args.options ); - break; - } - args.callback( instance ); - } - - } ); - -} ); \ No newline at end of file diff --git a/vendor/udx/lib-utility/scripts/src/udx.happ.socket.js b/vendor/udx/lib-utility/scripts/src/udx.happ.socket.js deleted file mode 100644 index 39ad1171f..000000000 --- a/vendor/udx/lib-utility/scripts/src/udx.happ.socket.js +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Socket - * - * @required ud.socket - * @author peshkov@UD - */ - -Application.define( 'core.socket', function( args, callback ) { - - /* Set arguments */ - args = jQuery.extend( true, { - 'port': 443, - 'url': false, - 'resource': 'websocket.api/v1.5', - 'secure': true, - 'account-id': false, - 'access-key': false - }, typeof args === 'object' ? args : {} ); - - if( typeof callback === 'undefined' ) { - callback = function() { - return null; - } - } - - return new ud.socket.connect( args.url, args, function( error, socket ) { - if( error ) { - console.error( 'Socket Callback', 'Connection Failed', error ); - return null; - } - try { callback( socket ); } - catch( e ) { console.error( 'Socket Callback', 'Custom callback failed', e ); } - } ); - -} ); \ No newline at end of file diff --git a/vendor/udx/lib-utility/scripts/src/udx.happ.view_model.js b/vendor/udx/lib-utility/scripts/src/udx.happ.view_model.js deleted file mode 100644 index f307d11eb..000000000 --- a/vendor/udx/lib-utility/scripts/src/udx.happ.view_model.js +++ /dev/null @@ -1,278 +0,0 @@ -/** - * View Model - * - * @required jQuery, knockout, knockout.mapping, knockout.ud - * @author peshkov@UD - */ - -Application.define( 'core.view_model', function( args ) { - - /* Set arguments */ - args = jQuery.extend( true, { - '_required': {}, - 'scope': false, // Application's object - 'model': {}, // - 'view': false, // HTML data or template's url - 'container': false, // HTML container - 'args': { - // Localization strings - 'l10n': { - 'remove_confirmation': 'Are you sure you want to remove it?' - } - }, - // Set of actions listeners which are fired on view model 'triggers' - 'actions': { - // Called on view_model update. view_model is updated on every selection ( see app.js -> Sammy implementation ) - 'update': function() { - return null; - }, - // Called before ko.applyBindings() function - 'pre_apply': function( self, callback ) { - callback( null, true ); - }, - // Child Constructor. Called after ko.applyBindings() function - 'init': function( self, callback ) { - callback( null, true ); - }, - // Called after data adding - 'add_data': function() { - return null; - }, - // Called after data removing - 'remove_data': function() { - return null; - }, - // Additional callback - 'callback': false - }, - // Callback should not be overwritten! If you want to add your callback use actions.callback - 'callback': function( error, data ) { - var self = this; - if( typeof self.actions === 'object' && typeof self.actions.callback === 'function' ) { - return self.actions.callback( error, data ); - } else { - - if( error && error instanceof Error ) { - console.error( error.message, data ); - } - - return data; - - } - } - }, typeof args === 'object' ? args : {} ); - - /* Check container argument */ - var container = ( args.container && typeof args.container !== 'object' ) ? jQuery( args.container ) : args.container; - - if( !container || typeof container.length === 'undefined' || !container.length > 0 ) { - return args.callback( new Error( 'ko.view_model. Container is missing, or incorrect.' ), false ); - } - - /* Appends View if it exists */ - if( args.view ) { - - /* Determine if view is link we try to get template using ajax. */ - if( /^((https?|ftp):)?\/\/([\-A-Z0-9.]+)(\/[\-A-Z0-9+&@#\/%=~_|!:,.;]*)?(\?[A-Z0-9+&@#\/%=~_|!:,.;]*)?/i.test( args.view ) ) { - jQuery.ajax( { - url: args.view, - async: false, - dataType: 'html', - complete: function( r, status ) { - args.view = r.responseText; - } - } ); - } - container.html( args.view ); - } - - var html = container.html(); - - container.html( '' ).addClass( 'ud_view_model ud_ui_loading' ).append( '
                    ' ).append( '
                    ' ).find( '.ud_ui_prepared_interface' ).html( html ); - - /** - * Creates View_Model - */ - var vm = function( args, container ) { - - var self = this; - - /* Determines if view_model already applied Bindings ( ko.applyBinding ) */ - self._applied = false; - - /* Arguments */ - self._args = args; - - /* Application's object */ - self.scope = args.scope; - - /* Application core functions */ - self.core = args.scope.core; - - /* Socket connection */ - self.socket = typeof args.scope.socket === 'object' ? args.scope.socket : false; - - /* DOM */ - self.container = container; - - /** - * Pushes new element to array. - * - * Example of usage: - * data-bind="click: $root.add_data.bind( $data, $root.some_array, $root.vhandler )" - * where $root.vhandler is a function, which creates data. - * - * $root.vhandler example: - * self.handler = function() { - * var self = this; - * self.arg1 = ko.observable( 'value1' ); - * self.arg2 = 'value2'; - * } - * - * @param observableArray item. Where we want to add new data - * @param mixed vhandler. Name of function or function which inits new data - * @param object view_model. The current view_model object - * @param object event. - * @author peshkov@UD - */ - self.add_data = function( item, vhanlder, view_model, event ) { - if( typeof vhanlder == 'function' ) { - item.push( new vhanlder ); - } else if( typeof view_model[ vhanlder ] === 'function' ) { - item.push( new view_model[ vhanlder ]() ); - } - try { self._args.actions.add_data( self, event, item, vhanlder ) } - catch( e ) { self._args.callback( e, view_model ); } - }; - - /** - * Adds message (success/warning/error) - * - * @author peshkov@UD - */ - self.alert = function( message, type ) { - var c = 'alert-success'; - if( typeof type !== 'undefined' ) { - switch( type ) { - case 'error': - c = 'alert-error'; - break; - case 'warning': - c = ''; - break; - } - } - var html = '
                    ' + message + '
                    '; - self.container.prepend( html ); - }; - - /** - * Removes data from array. - * - * Example of usage: - * data-bind="click: $root.remove_data.bind( $data, $root.some_array )" - * - * @param observableArray item. Where we want to remove data - * @param mixed data. Data which should be removed from array. - * @param object event. - * @author peshkov@UD - */ - self.remove_data = function( item, data, event ) { - - if( confirm( self.l10n.remove_confirmation ) ) { - item.remove( data ); - } - - try { - self._args.actions.remove_data( self, event, item, data ) - } catch( e ) { self._args.callback( e, self ); } - }; - - /** - * Wrapper for ko.applyBindings() - * - * Calls before ko.applyBindings() - self.pre_apply() - * Calls after ko.applyBindings() - init() - * - * @TODO: NEED TO IMPLEMENT ASYNC HERE TO HAVE ABILITY TO LOAD ALL DATA FROM SOCKET BEFORE APPLYBINDING. peshkov@UD - * @param array args. Optional - * @author peshkov@UD - */ - self.apply = function( args ) { - var self = this; - - var element = self.container.get( 0 ); - - if( self._applied ) { - return self._args.callback( null, self, element ); - } - - async.series({ - 'pre_apply': function( callback ){ - /* Special Handlers can be added here */ - try { - self._args.actions.pre_apply( self, callback ); - } catch( error ) { - callback( 'Error occured on VM pre_apply event' ); - } - }, - 'apply_bindings': function( callback ){ - ko.applyBindings( self, self.container.get( 0 ) ); - self._applied = true; - callback( null, true ); - }, - 'init': function ( callback ) { - self.container.removeClass( 'ud_ui_loading' ).addClass( 'ud_ui_applied' ); - /* Special Handlers can be added here */ - try { - self._args.actions.init( self, callback ); - } catch( error ) { - callback( 'Error occured on VM init event' ); - } - } - }, - function(err, results) { - self.update( typeof args !== 'undefined' ? args : [] ); - return self._args.callback( null, self ); - }); - - return null; - - }; - - /** - * It's just a wrapper. - * It should be called if view_model should be updated - * - * @param array args. Optional - * @author peshkov@UD - */ - self.update = function( args ) { - var self = this; - /* Special Handlers can be added here */ - try { self._args.actions.update( self, typeof args !== 'undefined' ? args : [] ); } catch( error ) { self._args.callback( error, self ); } - }; - - /* Add view_model data which is not related to args from model. */ - var m = {}; - var args = {}; - - if( typeof self._args.model === 'object' ? self._args.model : {} ) { - jQuery.each( self._args.model, function( i, e ) { - if( typeof self._args[ i ] === 'undefined' ) { m[ i ] = e; } else { args[ i ] = e; } - }); - } - - /* Combine arguments */ - self._args = jQuery.extend( true, self._args, args ); - - /* All additional methods and elements for the current model are added here */ - self = jQuery.extend( true, self, typeof self._args.args === 'object' ? self._args.args : args, m ); - - }; - - /* Bind Knockout */ - return new vm( args, container ); - -}); - diff --git a/vendor/udx/lib-utility/scripts/src/udx.loader.js b/vendor/udx/lib-utility/scripts/src/udx.loader.js deleted file mode 100644 index 8aba064d9..000000000 --- a/vendor/udx/lib-utility/scripts/src/udx.loader.js +++ /dev/null @@ -1,360 +0,0 @@ -/** - * UD Loader - * Initial global object extended by product-specific globals. - * - * @version 1.0 - * @description UD Loader. Initial global object extended by product-specific globals - * @package UD - * @author team@UD - */ -var ud = { - 'load': ( function (doc) { - - var env, - - head, - - pending = {}, - - pollCount = 0, - - // Queued requests. - queue = {css: [], js: []}, - - // Reference to the browser's list of stylesheets. - styleSheets = doc.styleSheets; - - /** - * Creates and returns an HTML element with the specified name and attributes. - * - */ - function createNode(name, attrs) { - var node = doc.createElement(name), attr; - - for (attr in attrs) { - if (attrs.hasOwnProperty(attr)) { - node.setAttribute(attr, attrs[attr]); - } - } - - return node; - } - - /** - Called when the current pending resource of the specified type has finished - loading. Executes the associated callback (if any) and loads the next - resource in the queue. - - @method finish - @param {String} type resource type ('css' or 'js') - @private - */ - function finish(type) { - var p = pending[type], - callback, - urls; - - if (p) { - callback = p.callback; - urls = p.urls; - - urls.shift(); - pollCount = 0; - - // If this is the last of the pending URLs, execute the callback and - // start the next request in the queue (if any). - if (!urls.length) { - callback && callback.call(p.context, p.obj); - pending[type] = null; - queue[type].length && load(type); - } - } - } - - /** - Populates the env variable with user agent and feature test - information. - - @method getEnv - @private - */ - function getEnv() { - var ua = navigator.userAgent; - - env = { - // True if this browser supports disabling async mode on dynamically - // created script nodes. See - // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order - async: doc.createElement('script').async === true - }; - - (env.webkit = /AppleWebKit\//.test(ua)) - || (env.ie = /MSIE/.test(ua)) - || (env.opera = /Opera/.test(ua)) - || (env.gecko = /Gecko\//.test(ua)) - || (env.unknown = true); - } - - /** - Loads the specified resources, or the next resource of the specified type - in the queue if no resources are specified. If a resource of the specified - type is already being loaded, the new request will be queued until the - first request has been finished. - - When an array of resource URLs is specified, those URLs will be loaded in - parallel if it is possible to do so while preserving execution order. All - browsers support parallel loading of CSS, but only Firefox and Opera - support parallel loading of scripts. In other browsers, scripts will be - queued and loaded one at a time to ensure correct execution order. - - @method load - @param {String} type resource type ('css' or 'js') - @param {String|Array} urls (optional) URL or array of URLs to load - @param {Function} callback (optional) callback function to execute when the - resource is loaded - @param {Object} obj (optional) object to pass to the callback function - @param {Object} context (optional) if provided, the callback function will - be executed in this object's context - @private - */ - function load(type, urls, callback, obj, context) { - var _finish = function () { finish(type); }, - isCSS = type === 'css', - nodes = [], - i, len, node, p, pendingUrls, url; - - env || getEnv(); - - if (urls) { - // If urls is a string, wrap it in an array. Otherwise assume it's an - // array and create a copy of it so modifications won't be made to the - // original. - urls = typeof urls === 'string' ? [urls] : urls.concat(); - - // Create a request object for each URL. If multiple URLs are specified, - // the callback will only be executed after all URLs have been loaded. - // - // Sadly, Firefox and Opera are the only browsers capable of loading - // scripts in parallel while preserving execution order. In all other - // browsers, scripts must be loaded sequentially. - // - // All browsers respect CSS specificity based on the order of the link - // elements in the DOM, regardless of the order in which the stylesheets - // are actually downloaded. - if (isCSS || env.async || env.gecko || env.opera) { - // Load in parallel. - queue[type].push({ - urls : urls, - callback: callback, - obj : obj, - context : context - }); - } else { - // Load sequentially. - for (i = 0, len = urls.length; i < len; ++i) { - queue[type].push({ - urls : [urls[i]], - callback: i === len - 1 ? callback : null, // callback is only added to the last URL - obj : obj, - context : context - }); - } - } - } - - // If a previous load request of this type is currently in progress, we'll - // wait our turn. Otherwise, grab the next item in the queue. - if (pending[type] || !(p = pending[type] = queue[type].shift())) { - return; - } - - head || (head = doc.head || doc.getElementsByTagName('head')[0]); - pendingUrls = p.urls; - - for (i = 0, len = pendingUrls.length; i < len; ++i) { - url = pendingUrls[i]; - - if (isCSS) { - node = env.gecko ? createNode('style') : createNode('link', { - href: url, - rel : 'stylesheet' - }); - } else { - node = createNode('script', {src: url}); - node.async = false; - } - - node.className = 'lazyload'; - node.setAttribute('charset', 'utf-8'); - - if (env.ie && !isCSS) { - node.onreadystatechange = function () { - if (/loaded|complete/.test(node.readyState)) { - node.onreadystatechange = null; - _finish(); - } - }; - } else if (isCSS && (env.gecko || env.webkit)) { - // Gecko and WebKit don't support the onload event on link nodes. - if (env.webkit) { - // In WebKit, we can poll for changes to document.styleSheets to - // figure out when stylesheets have loaded. - p.urls[i] = node.href; // resolve relative URLs (or polling won't work) - pollWebKit(); - } else { - // In Gecko, we can import the requested URL into a - - -

                    Classes

                    -
                      -
                    • Utility: General utility methods.
                    • -
                    • Job: Job and processing handling.
                    • -
                    • Loader: PSR class loader.
                    • -
                    -

                    Utility Methods

                    -
                      -
                    • extend()
                    • -
                    • defaults()
                    • -
                    • pluralize()
                    • -
                    • singularize()
                    • -
                    • ordinalize()
                    • -
                    • hashify_file_name()
                    • -
                    • can_get_image()
                    • -
                    • ...
                    • -
                    -

                    Changelog

                    -

                    0.2.4

                    -
                      -
                    • Added Utility::hashify_file_name() method;
                    • -
                    • Added seperator options to Utility:;create_slug() to support things such as "::"
                    • -
                    -

                    Usage

                    -
                    // Extend an Array or Object with another for easily setting of defaults. This is similar to extend() but in reverse.
                    -$settings = UsabilityDynamics\Utility::defaults( $configurationObject, $defaultsObject );
                    -
                    -// Find composer.json file and return as Object.
                    -$composer = UsabilityDynamics\Utility::findUp( 'composer.json', __DIR__ );
                    -echo "Versio is {$composer->version}."
                    -

                    License

                    -

                    (The MIT License)

                    -

                    Copyright (c) 2013 Usability Dynamics, Inc. <info@usabilitydynamics.com>

                    -

                    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/vendor/udx/lib-utility/static/yuidoc.json b/vendor/udx/lib-utility/static/yuidoc.json deleted file mode 100644 index 5317288b6..000000000 --- a/vendor/udx/lib-utility/static/yuidoc.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "utility", - "version": "0.0.1", - "url": "https://github.com/udx/lib-utility/", - "logo": "http://a3d72a45d111006ec192-ec5b80a12b0b09b4d52373336afb4254.r80.cf1.rackcdn.com/usability-dynamics.png", - "options": { - "norecurse": false, - "no-code": false, - "extension": ".js,.php", - "tabtospace": 2, - "outdir": "./static/codex", - "paths": [ - "./lib", "./scripts" - ] - } -} \ No newline at end of file diff --git a/vendor/udx/lib-utility/test/fixtures/sample.json b/vendor/udx/lib-utility/test/fixtures/sample.json deleted file mode 100644 index b71323e7f..000000000 --- a/vendor/udx/lib-utility/test/fixtures/sample.json +++ /dev/null @@ -1,124 +0,0 @@ -{ - "anagrafica": { - "@version" : 1.1, - "testata": { - "nomemercato": { - "-id": "007", - "#text": "Mercato di test" - }, - "data": "Giovedi 18 dicembre 2003 16.05.29" - }, - "record": [ - { - "codice_cliente": "5", - "rag_soc": "Miami American Cafe", - "codice_fiscale": "IT07654930130", - "indirizzo": { - "-tipo": "casa", - "#text": "Viale Carlo Espinasse 5, Como" - }, - "num_prodotti": "13" - }, - { - "codice_cliente": "302", - "rag_soc": "Filiberto Gilardi", - "codice_fiscale": "IT87654770157", - "indirizzo": { - "-tipo": "ufficio", - "#text": "Via Biancospini 20, Messina" - }, - "num_prodotti": "8" - }, - { - "codice_cliente": "1302", - "rag_soc": "Eidon", - "codice_fiscale": "IT887511231", - "indirizzo": { - "-tipo": "ufficio", - "#text": "Via Bassini 17/2, Milano" - }, - "num_prodotti": "18" - }, - { - "codice_cliente": "202", - "rag_soc": "SkillNet", - "codice_fiscale": "IT887642131", - "indirizzo": { - "-tipo": "ufficio", - "#text": "Via Chiasserini 11A, Milano" - }, - "num_prodotti": "24" - }, - { - "codice_cliente": "12", - "rag_soc": "Eidon", - "codice_fiscale": "IT04835710965", - "indirizzo": { - "-tipo": "casa", - "#text": "Via Cignoli 17/2, Roma" - }, - "num_prodotti": "1112" - }, - { - "codice_cliente": "5", - "rag_soc": "Miami American Cafe", - "codice_fiscale": "IT07654930130", - "indirizzo": { - "-tipo": "casa", - "#text": "Viale Carlo Espinasse 5, Como" - }, - "num_prodotti": "13" - }, - { - "codice_cliente": "302", - "rag_soc": "Filiberto Gilardi", - "codice_fiscale": "IT87654770157", - "indirizzo": { - "-tipo": "ufficio", - "#text": "Via Biancospini 20, Messina" - }, - "num_prodotti": "8" - }, - { - "codice_cliente": "1302", - "rag_soc": "Eidon", - "codice_fiscale": "IT887511231", - "indirizzo": { - "-tipo": "ufficio", - "#text": "Via Bassini 17/2, Milano" - }, - "num_prodotti": "18" - }, - { - "codice_cliente": "202", - "rag_soc": "SkillNet", - "codice_fiscale": "IT887642131", - "indirizzo": { - "-tipo": "ufficio", - "#text": "Via Chiasserini 11A, Milano" - }, - "num_prodotti": "24" - }, - { - "codice_cliente": "202", - "rag_soc": "SkillNet", - "codice_fiscale": "IT887642131", - "indirizzo": { - "-tipo": "ufficio", - "#text": "Via Chiasserini 11A, Milano" - }, - "num_prodotti": "24" - }, - { - "codice_cliente": "12", - "rag_soc": "Eidon", - "codice_fiscale": "IT04835710965", - "indirizzo": { - "-tipo": "casa", - "#text": "Via Cignoli 17/2, Roma" - }, - "num_prodotti": "1112" - } - ] - } -} \ No newline at end of file diff --git a/vendor/udx/lib-utility/test/fixtures/sample.php b/vendor/udx/lib-utility/test/fixtures/sample.php deleted file mode 100644 index 249a1c596..000000000 --- a/vendor/udx/lib-utility/test/fixtures/sample.php +++ /dev/null @@ -1,14 +0,0 @@ - - - - 1.1 - - Mercato di test - Giovedi 18 dicembre 2003 16.05.29 - - - 5 - Miami American Cafe - IT07654930130 - Viale Carlo Espinasse 5, Como - 13 - - - 302 - Filiberto Gilardi - IT87654770157 - Via Biancospini 20, Messina - 8 - - - 1302 - Eidon - IT887511231 - Via Bassini 17/2, Milano - 18 - - - 202 - SkillNet - IT887642131 - Via Chiasserini 11A, Milano - 24 - - - 12 - Eidon - IT04835710965 - Via Cignoli 17/2, Roma - 1112 - - - 5 - Miami American Cafe - IT07654930130 - Viale Carlo Espinasse 5, Como - 13 - - - 302 - Filiberto Gilardi - IT87654770157 - Via Biancospini 20, Messina - 8 - - - 1302 - Eidon - IT887511231 - Via Bassini 17/2, Milano - 18 - - - 202 - SkillNet - IT887642131 - Via Chiasserini 11A, Milano - 24 - - - 202 - SkillNet - IT887642131 - Via Chiasserini 11A, Milano - 24 - - - 12 - Eidon - IT04835710965 - Via Cignoli 17/2, Roma - 1112 - - diff --git a/vendor/udx/lib-utility/test/js/basic.js b/vendor/udx/lib-utility/test/js/basic.js deleted file mode 100644 index dc66872f1..000000000 --- a/vendor/udx/lib-utility/test/js/basic.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Basic JavaScript Tests. - * - * @type {{Utility Basic Tests: {test-one: "test-one"}}} - */ -module.exports = { - - "Utility Tests": { - - "example-test": function() { - - } - - } - -}; \ No newline at end of file diff --git a/vendor/udx/lib-utility/test/php/basic-test.php b/vendor/udx/lib-utility/test/php/basic-test.php deleted file mode 100644 index ed4b44239..000000000 --- a/vendor/udx/lib-utility/test/php/basic-test.php +++ /dev/null @@ -1,58 +0,0 @@ - 10 - ); - - $defaultsSettings = array( - "someDefault" => 7 - ); - - $finalConfiguration = UsabilityDynamics\Utility::defaults( $myConfiguration, $defaultsSettings ); - - $this->assertEquals( 7, $finalConfiguration->someDefault ); - $this->assertEquals( 10, $finalConfiguration->someOther ); - - } - - /** - * Test Utility::findUp(); - * - */ - public function testFindUp() { - - // Traverse upward directory tree until fixtures/sample.json is found. - $sampleJSON = UsabilityDynamics\Utility::findUp( 'fixtures/sample.json' ); - - // Traverse upward directory tree until fixtures/sample.xml is found. - $sampleXML = UsabilityDynamics\Utility::findUp( 'fixtures/sample.xml' ); - - // Traverse upward directory tree until fixtures/sample.php is found. - UsabilityDynamics\Utility::findUp( 'fixtures/sample.php' ); - - // JSON Formatted properly. - $this->assertEquals( 1.1, $sampleJSON->anagrafica->{"@version"} ); - - // XML Formatted properly. - $this->assertEquals( 1.1, (string) $sampleXML->version ); - - // Custom class loaded. - $this->assertEquals( true, class_exists( 'MySampleClass' ) ); - - // Custom class method is accessible. - $this->assertEquals( true, method_exists( 'MySampleClass', 'test_method' ) ); - - } - -} diff --git a/vendor/udx/lib-wp-bootstrap/changes.md b/vendor/udx/lib-wp-bootstrap/changes.md index 40b309617..29e76ae36 100644 --- a/vendor/udx/lib-wp-bootstrap/changes.md +++ b/vendor/udx/lib-wp-bootstrap/changes.md @@ -1,3 +1,15 @@ +### 1.3.3 + +* Require user to be logged in while dismissing Admin Panel notices. + +### 1.3.2 + +* Improve security while processing AJAX requests in Admin Panel. + +### 1.3.1 + +* Remove dependency from `udx/lib-utility`. + ### 1.2.2 * Fixed `path` utility function: detecting if dir belongs to plugins directory by `WP_PLUGIN_DIR`, but not only by deprecated `PLUGINDIR`. \ No newline at end of file diff --git a/vendor/udx/lib-wp-bootstrap/composer.json b/vendor/udx/lib-wp-bootstrap/composer.json index 3d77eb3b7..9886f0f3e 100755 --- a/vendor/udx/lib-wp-bootstrap/composer.json +++ b/vendor/udx/lib-wp-bootstrap/composer.json @@ -8,8 +8,7 @@ "minimum-stability": "dev", "license": "MIT", "require": { - "php": ">=5.3", - "udx/lib-utility": "~0.3" + "php": ">=5.3" }, "autoload": { "classmap": [ "lib/classes" ] diff --git a/vendor/udx/lib-wp-bootstrap/lib/classes/class-bootstrap-plugin.php b/vendor/udx/lib-wp-bootstrap/lib/classes/class-bootstrap-plugin.php index 19111339a..22c124dcf 100644 --- a/vendor/udx/lib-wp-bootstrap/lib/classes/class-bootstrap-plugin.php +++ b/vendor/udx/lib-wp-bootstrap/lib/classes/class-bootstrap-plugin.php @@ -38,6 +38,8 @@ protected function __construct( $args ) { add_action( 'plugins_loaded', array( $this, 'define_license_manager' ), 1 ); //** Initialize plugin here. All plugin actions must be added on this step */ add_action( 'plugins_loaded', array( $this, 'pre_init' ), 100 ); + //** TGM Plugin activation. */ + add_action( 'plugins_loaded', array( $this, 'check_plugins_requirements' ), 10 ); $this->boot(); } diff --git a/vendor/udx/lib-wp-bootstrap/lib/classes/class-bootstrap-theme.php b/vendor/udx/lib-wp-bootstrap/lib/classes/class-bootstrap-theme.php index d6d0df96d..5594b0cba 100644 --- a/vendor/udx/lib-wp-bootstrap/lib/classes/class-bootstrap-theme.php +++ b/vendor/udx/lib-wp-bootstrap/lib/classes/class-bootstrap-theme.php @@ -50,6 +50,8 @@ protected function __construct( $args ) { parent::__construct( $args ); //** Load text domain */ add_action( 'after_setup_theme', array( $this, 'load_textdomain' ), 1 ); + //** TGM Plugin activation. */ + $this->check_plugins_requirements(); //** May be initialize Licenses Manager. */ $this->define_license_manager(); //** Maybe define license client */ diff --git a/vendor/udx/lib-wp-bootstrap/lib/classes/class-bootstrap.php b/vendor/udx/lib-wp-bootstrap/lib/classes/class-bootstrap.php index bfabb6288..f395058df 100644 --- a/vendor/udx/lib-wp-bootstrap/lib/classes/class-bootstrap.php +++ b/vendor/udx/lib-wp-bootstrap/lib/classes/class-bootstrap.php @@ -148,7 +148,7 @@ public function get( $key = null, $default = null ) { public function get_schema( $key = '' ) { if( $this->schema === null ) { if( !empty( $this->schema_path ) && file_exists( $this->schema_path ) ) { - $this->schema = (array)\UsabilityDynamics\Utility::l10n_localize( json_decode( file_get_contents( $this->schema_path ), true ), (array)$this->get_localization() ); + $this->schema = (array)Utility::l10n_localize( json_decode( file_get_contents( $this->schema_path ), true ), (array)$this->get_localization() ); } } //** Break if composer.json does not exist */ @@ -440,6 +440,37 @@ public function render_upgrade_notice() { echo apply_filters( 'ud::bootstrap::upgrade_notice::template', $content, $this->slug, $vars ); } + /** + * Check plugins requirements + * + * @author peshkov@UD + */ + public function check_plugins_requirements() { + //** Determine if we have TGMA Plugin Activation initialized. */ + $is_tgma = $this->is_tgma; + if( $is_tgma ) { + $tgma = TGM_Plugin_Activation::get_instance(); + //** Maybe get TGMPA notices. */ + $notices = $tgma->notices( get_class( $this ) ); + if( !empty( $notices[ 'messages' ] ) && is_array( $notices[ 'messages' ] ) ) { + $error_links = false; + $message_links = false; + foreach( $notices[ 'messages' ] as $m ) { + if( $m[ 'type' ] == 'error' ) $error_links = true; + elseif( $m[ 'type' ] == 'message' ) $message_links = true; + $this->errors->add( $m[ 'value' ], $m[ 'type' ] ); + } + //** Maybe add footer action links to errors and|or notices block. */ + if( !empty( $notices[ 'links' ] ) && is_array( $notices[ 'links' ] ) ) { + foreach( $notices[ 'links' ] as $type => $links ) { + foreach( $links as $link ) { + $this->errors->add_action_link( $link, $type ); + } + } + } + } + } + } /** * Maybe determines if Composer autoloader is included and modules classes are up to date @@ -483,6 +514,15 @@ private function plugins_dependencies() { return; } $plugins = $this->get_schema( 'extra.schemas.dependencies.plugins' ); + if( !empty( $plugins ) && is_array( $plugins ) ) { + $tgma = TGM_Plugin_Activation::get_instance(); + foreach( $plugins as $plugin ) { + $plugin[ '_referrer' ] = get_class( $this ); + $plugin[ '_referrer_name' ] = $this->name; + $tgma->register( $plugin ); + } + $this->is_tgma = true; + } } diff --git a/vendor/udx/lib-wp-bootstrap/lib/classes/class-errors.php b/vendor/udx/lib-wp-bootstrap/lib/classes/class-errors.php index 441dba011..d3945f5e2 100644 --- a/vendor/udx/lib-wp-bootstrap/lib/classes/class-errors.php +++ b/vendor/udx/lib-wp-bootstrap/lib/classes/class-errors.php @@ -148,10 +148,16 @@ public function admin_notices() { if ( is_multisite() && ! is_super_admin() ) { return; } + //** Ignore messages on TGM Plugin Activation page */ + if( TGM_Plugin_Activation::get_instance()->is_tgmpa_page() ) { + return; + } $errors = apply_filters( 'ud:errors:admin_notices', $this->errors, $this->args ); $messages = apply_filters( 'ud:messages:admin_notices', $this->messages, $this->args ); $warnings = apply_filters( 'ud:warnings:admin_notices', $this->warnings, $this->args ); + + $nonce = wp_create_nonce('ud_dismiss'); if( !empty( $errors ) || !empty( $messages ) || !empty( $warnings ) ) { echo ""; @@ -175,7 +181,11 @@ public function admin_notices() { $message = '
                    • ' . implode( '
                    • ', $warnings ) . '
                    '; $message = sprintf( __( '

                    %s has the following warnings:

                    %s', $this->domain ), $this->name, $message ); if( $this->dismiss ) { - $this->action_links[ 'warnings' ][] = '' . __( 'Dismiss this warning', $this->domain ) . ''; + $this->action_links[ 'warnings' ][] = + '' . + __( 'Dismiss this warning', $this->domain ) . ''; } if( !empty( $this->action_links[ 'warnings' ] ) && is_array( $this->action_links[ 'warnings' ] ) ) { $message .= '

                    ' . implode( ' | ', $this->action_links[ 'warnings' ] ) . '

                    '; @@ -195,7 +205,11 @@ public function admin_notices() { $message = sprintf( __( '

                    %s is active, but has the following notices:

                    %s', $this->domain ), $this->name, $message ); } if( $this->dismiss ) { - $this->action_links[ 'messages' ][] = '' . __( 'Dismiss this notice', $this->domain ) . ''; + $this->action_links[ 'messages' ][] = + '' . + __( 'Dismiss this notice', $this->domain ) . ''; } $message .= '

                    ' . implode( ' | ', $this->action_links[ 'messages' ] ) . '

                    '; echo '
                    ' . $message . '
                    '; @@ -217,20 +231,30 @@ public function admin_notices() { * dismiss the notice ajax callback * @throws \Exception */ - public function dismiss_notices(){ + public function dismiss_notices() { + check_ajax_referer('ud_dismiss'); + + if ( !is_user_logged_in() ) { + wp_send_json_error( array( 'error' => __( 'You are not allowed to do this action.', $this->domain ) ) ); + } + $response = array( 'success' => '0', 'error' => __( 'There was an error in request.', $this->domain ), ); + $error = false; - if( empty($_POST['key']) ) { + $option_key = isset($_POST['key']) ? sanitize_key($_POST['key']) : ''; + + if ( strpos($option_key, 'dismissed_') !== 0 ) { $response['error'] = __( 'Invalid key', $this->domain ); $error = true; } - if ( ! $error && update_option( ( $_POST['key'] ), time() ) ) { + if ( !$error && update_option( $option_key, time() ) ) { $response['success'] = '1'; + $response['error'] = null; } wp_send_json( $response ); diff --git a/vendor/udx/lib-wp-bootstrap/lib/classes/class-tgm-bulk-installer.php b/vendor/udx/lib-wp-bootstrap/lib/classes/class-tgm-bulk-installer.php new file mode 100644 index 000000000..b53aa39fc --- /dev/null +++ b/vendor/udx/lib-wp-bootstrap/lib/classes/class-tgm-bulk-installer.php @@ -0,0 +1,554 @@ + + * @author Gary Jones + * @copyright Copyright (c) 2012, Thomas Griffin + * @license http://opensource.org/licenses/gpl-2.0.php GPL v2 or later + * @link https://github.com/thomasgriffin/TGM-Plugin-Activation + */ + +/* + Copyright 2014 Thomas Griffin (thomasgriffinmedia.com) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, as + published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/** + * The WP_Upgrader file isn't always available. If it isn't available, + * we load it here. + * + * We check to make sure no action or activation keys are set so that WordPress + * doesn't try to re-include the class when processing upgrades or installs outside + * of the class. + * + * @since 2.2.0 + */ + +namespace UsabilityDynamics\WP { + + if ( ! class_exists( 'WP_Upgrader' ) ) { + require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + } + + if ( ! class_exists( 'UsabilityDynamics\WP\TGM_Bulk_Installer' ) ) { + /** + * Installer class to handle bulk plugin installations. + * + * Extends WP_Upgrader and customizes to suit the installation of multiple + * plugins. + * + * @since 2.2.0 + * + * @package TGM-Plugin-Activation + * @author Thomas Griffin + * @author Gary Jones + */ + class TGM_Bulk_Installer extends \WP_Upgrader { + + /** + * Holds result of bulk plugin installation. + * + * @since 2.2.0 + * + * @var string + */ + public $result; + + /** + * Flag to check if bulk installation is occurring or not. + * + * @since 2.2.0 + * + * @var boolean + */ + public $bulk = false; + + /** + * Processes the bulk installation of plugins. + * + * @since 2.2.0 + * + * @param array $packages The plugin sources needed for installation. + * @return string|boolean Install confirmation messages on success, false on failure. + */ + public function bulk_install( $packages ) { + + // Pass installer skin object and set bulk property to true. + $this->init(); + $this->bulk = true; + + // Set install strings and automatic activation strings (if config option is set to true). + $this->install_strings(); + if ( TGM_Plugin_Activation::$instance->is_automatic ) { + $this->activate_strings(); + } + + // Run the header string to notify user that the process has begun. + $this->skin->header(); + + // Connect to the Filesystem. + $res = $this->fs_connect( array( WP_CONTENT_DIR, WP_PLUGIN_DIR ) ); + if ( ! $res ) { + $this->skin->footer(); + return false; + } + + // Set the bulk header and prepare results array. + $this->skin->bulk_header(); + $results = array(); + + // Get the total number of packages being processed and iterate as each package is successfully installed. + $this->update_count = count( $packages ); + $this->update_current = 0; + + // Loop through each plugin and process the installation. + foreach ( $packages as $plugin ) { + $this->update_current++; // Increment counter. + + // Do the plugin install. + $result = $this->run( + array( + 'package' => $plugin, // The plugin source. + 'destination' => WP_PLUGIN_DIR, // The destination dir. + 'clear_destination' => false, // Do we want to clear the destination or not? + 'clear_working' => true, // Remove original install file. + 'is_multi' => true, // Are we processing multiple installs? + 'hook_extra' => array( 'plugin' => $plugin, ), // Pass plugin source as extra data. + ) + ); + + // Store installation results in result property. + $results[$plugin] = $this->result; + + // Prevent credentials auth screen from displaying multiple times. + if ( false === $result ) { + break; + } + } + + // Pass footer skin strings. + $this->skin->bulk_footer(); + $this->skin->footer(); + + // Return our results. + return $results; + + } + + /** + * Performs the actual installation of each plugin. + * + * This method also activates the plugin in the automatic flag has been + * set to true for the TGMPA class. + * + * @since 2.2.0 + * + * @param array $options The installation cofig options + * @return null/array Return early if error, array of installation data on success + */ + public function run( $options ) { + + // Default config options. + $defaults = array( + 'package' => '', + 'destination' => '', + 'clear_destination' => false, + 'clear_working' => true, + 'is_multi' => false, + 'hook_extra' => array(), + ); + + // Parse default options with config options from $this->bulk_upgrade and extract them. + $options = wp_parse_args( $options, $defaults ); + extract( $options ); + + // Connect to the Filesystem. + $res = $this->fs_connect( array( WP_CONTENT_DIR, $destination ) ); + if ( ! $res ) { + return false; + } + + // Return early if there is an error connecting to the Filesystem. + if ( is_wp_error( $res ) ) { + $this->skin->error( $res ); + return $res; + } + + // Call $this->header separately if running multiple times. + if ( ! $is_multi ) + $this->skin->header(); + + // Set strings before the package is installed. + $this->skin->before(); + + // Download the package (this just returns the filename of the file if the package is a local file). + $download = $this->download_package( $package ); + if ( is_wp_error( $download ) ) { + $this->skin->error( $download ); + $this->skin->after(); + return $download; + } + + // Don't accidentally delete a local file. + $delete_package = ( $download != $package ); + + // Unzip file into a temporary working directory. + $working_dir = $this->unpack_package( $download, $delete_package ); + if ( is_wp_error( $working_dir ) ) { + $this->skin->error( $working_dir ); + $this->skin->after(); + return $working_dir; + } + + // Install the package into the working directory with all passed config options. + $result = $this->install_package( + array( + 'source' => $working_dir, + 'destination' => $destination, + 'clear_destination' => $clear_destination, + 'clear_working' => $clear_working, + 'hook_extra' => $hook_extra, + ) + ); + + // Pass the result of the installation. + $this->skin->set_result( $result ); + + // Set correct strings based on results. + if ( is_wp_error( $result ) ) { + $this->skin->error( $result ); + $this->skin->feedback( 'process_failed' ); + } + // The plugin install is successful. + else { + $this->skin->feedback( 'process_success' ); + } + + // Only process the activation of installed plugins if the automatic flag is set to true. + if ( TGM_Plugin_Activation::$instance->is_automatic ) { + // Flush plugins cache so we can make sure that the installed plugins list is always up to date. + wp_cache_flush(); + + // Get the installed plugin file and activate it. + $plugin_info = $this->plugin_info( $package ); + $activate = activate_plugin( $plugin_info ); + + // Re-populate the file path now that the plugin has been installed and activated. + TGM_Plugin_Activation::$instance->populate_file_path(); + + // Set correct strings based on results. + if ( is_wp_error( $activate ) ) { + $this->skin->error( $activate ); + $this->skin->feedback( 'activation_failed' ); + } + // The plugin activation is successful. + else { + $this->skin->feedback( 'activation_success' ); + } + } + + // Flush plugins cache so we can make sure that the installed plugins list is always up to date. + wp_cache_flush(); + + // Set install footer strings. + $this->skin->after(); + if ( ! $is_multi ) { + $this->skin->footer(); + } + + return $result; + + } + + /** + * Sets the correct install strings for the installer skin to use. + * + * @since 2.2.0 + */ + public function install_strings() { + + $this->strings['no_package'] = __( 'Install package not available.', 'tgmpa' ); + $this->strings['downloading_package'] = __( 'Downloading install package from %s…', 'tgmpa' ); + $this->strings['unpack_package'] = __( 'Unpacking the package…', 'tgmpa' ); + $this->strings['installing_package'] = __( 'Installing the plugin…', 'tgmpa' ); + $this->strings['process_failed'] = __( 'Plugin install failed.', 'tgmpa' ); + $this->strings['process_success'] = __( 'Plugin installed successfully.', 'tgmpa' ); + + } + + /** + * Sets the correct activation strings for the installer skin to use. + * + * @since 2.2.0 + */ + public function activate_strings() { + + $this->strings['activation_failed'] = __( 'Plugin activation failed.', 'tgmpa' ); + $this->strings['activation_success'] = __( 'Plugin activated successfully.', 'tgmpa' ); + + } + + /** + * Grabs the plugin file from an installed plugin. + * + * @since 2.2.0 + * + * @return string|boolean Return plugin file on success, false on failure + */ + public function plugin_info() { + + // Return false if installation result isn't an array or the destination name isn't set. + if ( ! is_array( $this->result ) ) { + return false; + } + + if ( empty( $this->result['destination_name'] ) ) { + return false; + } + + /// Get the installed plugin file or return false if it isn't set. + $plugin = get_plugins( '/' . $this->result['destination_name'] ); + if ( empty( $plugin ) ) { + return false; + } + + // Assume the requested plugin is the first in the list. + $pluginfiles = array_keys( $plugin ); + + return $this->result['destination_name'] . '/' . $pluginfiles[0]; + + } + + } + } + + if ( ! class_exists( 'UsabilityDynamics\WP\TGM_Bulk_Installer_Skin' ) ) { + /** + * Installer skin to set strings for the bulk plugin installations.. + * + * Extends Bulk_Upgrader_Skin and customizes to suit the installation of multiple + * plugins. + * + * @since 2.2.0 + * + * @package TGM-Plugin-Activation + * @author Thomas Griffin + * @author Gary Jones + */ + class TGM_Bulk_Installer_Skin extends \Bulk_Upgrader_Skin { + + /** + * Holds plugin info for each individual plugin installation. + * + * @since 2.2.0 + * + * @var array + */ + public $plugin_info = array(); + + /** + * Holds names of plugins that are undergoing bulk installations. + * + * @since 2.2.0 + * + * @var array + */ + public $plugin_names = array(); + + /** + * Integer to use for iteration through each plugin installation. + * + * @since 2.2.0 + * + * @var integer + */ + public $i = 0; + + /** + * Constructor. Parses default args with new ones and extracts them for use. + * + * @since 2.2.0 + * + * @param array $args Arguments to pass for use within the class. + */ + public function __construct( $args = array() ) { + + // Parse default and new args. + $defaults = array( 'url' => '', 'nonce' => '', 'names' => array() ); + $args = wp_parse_args( $args, $defaults ); + + // Set plugin names to $this->plugin_names property. + $this->plugin_names = $args['names']; + + // Extract the new args. + parent::__construct( $args ); + + } + + /** + * Sets install skin strings for each individual plugin. + * + * Checks to see if the automatic activation flag is set and uses the + * the proper strings accordingly. + * + * @since 2.2.0 + */ + public function add_strings() { + + // Automatic activation strings. + if ( TGM_Plugin_Activation::$instance->is_automatic ) { + $this->upgrader->strings['skin_upgrade_start'] = __( 'The installation and activation process is starting. This process may take a while on some hosts, so please be patient.', 'tgmpa' ); + $this->upgrader->strings['skin_update_successful'] = __( '%1$s installed and activated successfully.', 'tgmpa' ) . ' ' . __( 'Show Details', 'tgmpa' ) . '.'; + $this->upgrader->strings['skin_upgrade_end'] = __( 'All installations and activations have been completed.', 'tgmpa' ); + $this->upgrader->strings['skin_before_update_header'] = __( 'Installing and Activating Plugin %1$s (%2$d/%3$d)', 'tgmpa' ); + } + // Default installation strings. + else { + $this->upgrader->strings['skin_upgrade_start'] = __( 'The installation process is starting. This process may take a while on some hosts, so please be patient.', 'tgmpa' ); + $this->upgrader->strings['skin_update_failed_error'] = __( 'An error occurred while installing %1$s: %2$s.', 'tgmpa' ); + $this->upgrader->strings['skin_update_failed'] = __( 'The installation of %1$s failed.', 'tgmpa' ); + $this->upgrader->strings['skin_update_successful'] = __( '%1$s installed successfully.', 'tgmpa' ) . ' ' . __( 'Show Details', 'tgmpa' ) . '.'; + $this->upgrader->strings['skin_upgrade_end'] = __( 'All installations have been completed.', 'tgmpa' ); + $this->upgrader->strings['skin_before_update_header'] = __( 'Installing Plugin %1$s (%2$d/%3$d)', 'tgmpa' ); + } + + } + + /** + * Outputs the header strings and necessary JS before each plugin installation. + * + * @since 2.2.0 + */ + public function before( $title = '' ) { + + // We are currently in the plugin installation loop, so set to true. + $this->in_loop = true; + + printf( '

                    ' . $this->upgrader->strings['skin_before_update_header'] . '

                    ', $this->plugin_names[$this->i], $this->upgrader->update_current, $this->upgrader->update_count ); + echo ''; + echo '

                    '; + + // Flush header output buffer. + $this->before_flush_output(); + + } + + /** + * Outputs the footer strings and necessary JS after each plugin installation. + * + * Checks for any errors and outputs them if they exist, else output + * success strings. + * + * @since 2.2.0 + */ + public function after( $title = '' ) { + + // Close install strings. + echo '

                    '; + + // Output error strings if an error has occurred. + if ( $this->error || ! $this->result ) { + if ( $this->error ) { + echo '

                    ' . sprintf( $this->upgrader->strings['skin_update_failed_error'], $this->plugin_names[$this->i], $this->error ) . '

                    '; + } else { + echo '

                    ' . sprintf( $this->upgrader->strings['skin_update_failed'], $this->plugin_names[$this->i] ) . '

                    '; + } + + echo ''; + } + + // If the result is set and there are no errors, success! + if ( ! empty( $this->result ) && ! is_wp_error( $this->result ) ) { + echo '

                    ' . sprintf( $this->upgrader->strings['skin_update_successful'], $this->plugin_names[$this->i], 'jQuery(\'#progress-' . esc_js( $this->upgrader->update_current ) . '\').toggle();jQuery(\'span\', this).toggle(); return false;' ) . '

                    '; + echo ''; + } + + // Set in_loop and error to false and flush footer output buffer. + $this->reset(); + $this->after_flush_output(); + + } + + /** + * Outputs links after bulk plugin installation is complete. + * + * @since 2.2.0 + */ + public function bulk_footer() { + + // Serve up the string to say installations (and possibly activations) are complete. + parent::bulk_footer(); + + // Flush plugins cache so we can make sure that the installed plugins list is always up to date. + wp_cache_flush(); + + // Display message based on if all plugins are now active or not. + $complete = array(); + foreach ( TGM_Plugin_Activation::$instance->plugins as $plugin ) { + if ( ! is_plugin_active( $plugin['file_path'] ) ) { + echo '

                    ' . TGM_Plugin_Activation::$instance->strings['return'] . '

                    '; + $complete[] = $plugin; + break; + } + // Nothing to store. + else { + $complete[] = ''; + } + } + + // Filter out any empty entries. + $complete = array_filter( $complete ); + + // All plugins are active, so we display the complete string and hide the menu to protect users. + if ( empty( $complete ) ) { + echo '

                    ' . sprintf( TGM_Plugin_Activation::$instance->strings['complete'], '' . __( 'Return to the Dashboard', 'tgmpa' ) . '' ) . '

                    '; + echo ''; + } + + } + + /** + * Flush header output buffer. + * + * @since 2.2.0 + */ + public function before_flush_output() { + + wp_ob_end_flush_all(); + flush(); + + } + + /** + * Flush footer output buffer and iterate $this->i to make sure the + * installation strings reference the correct plugin. + * + * @since 2.2.0 + */ + public function after_flush_output() { + + wp_ob_end_flush_all(); + flush(); + $this->i++; + + } + + } + } + +} \ No newline at end of file diff --git a/vendor/udx/lib-wp-bootstrap/lib/classes/class-tgm-list-table.php b/vendor/udx/lib-wp-bootstrap/lib/classes/class-tgm-list-table.php new file mode 100644 index 000000000..8b7d9c436 --- /dev/null +++ b/vendor/udx/lib-wp-bootstrap/lib/classes/class-tgm-list-table.php @@ -0,0 +1,681 @@ + + * @author Gary Jones + * @copyright Copyright (c) 2012, Thomas Griffin + * @license http://opensource.org/licenses/gpl-2.0.php GPL v2 or later + * @link https://github.com/thomasgriffin/TGM-Plugin-Activation + */ + +/* + Copyright 2014 Thomas Griffin (thomasgriffinmedia.com) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, as + published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +namespace UsabilityDynamics\WP { + + /** + * WP_List_Table isn't always available. If it isn't available, + * we load it here. + * + * @since 2.2.0 + */ + if ( ! class_exists( 'WP_List_Table' ) ) { + require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' ); + } + + if ( ! class_exists( 'UsabilityDynamics\WP\TGMPA_List_Table' ) ) { + + /** + * List table class for handling plugins. + * + * Extends the WP_List_Table class to provide a future-compatible + * way of listing out all required/recommended plugins. + * + * Gives users an interface similar to the Plugin Administration + * area with similar (albeit stripped down) capabilities. + * + * This class also allows for the bulk install of plugins. + * + * @since 2.2.0 + * + * @package TGM-Plugin-Activation + * @author Thomas Griffin + * @author Gary Jones + */ + class TGMPA_List_Table extends \WP_List_Table { + + /** + * References parent constructor and sets defaults for class. + * + * The constructor also grabs a copy of $instance from the TGMPA class + * and stores it in the global object TGM_Plugin_Activation::$instance. + * + * @since 2.2.0 + * + * @global unknown $status + * @global string $page + */ + public function __construct() { + + global $status, $page; + + parent::__construct( + array( + 'singular' => 'plugin', + 'plural' => 'plugins', + 'ajax' => false, + ) + ); + + } + + /** + * Gathers and renames all of our plugin information to be used by + * WP_List_Table to create our table. + * + * @since 2.2.0 + * + * @return array $table_data Information for use in table. + */ + protected function _gather_plugin_data() { + + // Load thickbox for plugin links. + TGM_Plugin_Activation::$instance->admin_init(); + TGM_Plugin_Activation::$instance->thickbox(); + + // Prep variables for use and grab list of all installed plugins. + $table_data = array(); + $i = 0; + $installed_plugins = get_plugins(); + + foreach ( TGM_Plugin_Activation::$instance->plugins as $plugin ) { + if ( is_plugin_active( $plugin['file_path'] ) ) { + continue; // No need to display plugins if they are installed and activated. + } + + //echo "
                    "; print_r( $plugin ); echo "
                    "; //die(); + + $table_data[$i]['sanitized_plugin'] = $plugin['name']; + $table_data[$i]['slug'] = $this->_get_plugin_data_from_name( $plugin['name'] ); + + $external_url = $this->_get_plugin_data_from_name( $plugin['name'], 'external_url' ); + $source = $this->_get_plugin_data_from_name( $plugin['name'], 'source' ); + + if ( $external_url && preg_match( '|^http(s)?://|', $external_url ) ) { + $table_data[$i]['plugin'] = '' . $plugin['name'] . ''; + } + elseif ( ! $source || preg_match( '|^http://wordpress.org/extend/plugins/|', $source ) ) { + $url = esc_url( add_query_arg( + array( + 'tab' => 'plugin-information', + 'plugin' => $this->_get_plugin_data_from_name( $plugin['name'] ), + 'TB_iframe' => 'true', + 'width' => '640', + 'height' => '500', + ), + admin_url( 'plugin-install.php' ) + ) ); + + $table_data[$i]['plugin'] = '' . $plugin['name'] . ''; + } + else { + $table_data[$i]['plugin'] = '' . $plugin['name'] . ''; // No hyperlink. + } + + if ( isset( $table_data[$i]['plugin'] ) && (array) $table_data[$i]['plugin'] ) { + $plugin['name'] = $table_data[$i]['plugin']; + } + + if ( ! empty( $plugin['source'] ) || ( isset( $plugin['private'] ) && $plugin['private'] == true ) ) { + // The plugin must be from a private repository. + if ( !empty( $plugin['source'] ) && preg_match( '|^http(s)?://|', $plugin['source'] ) ) { + $table_data[$i]['source'] = __( 'Private Repository', 'tgmpa' ); + // The plugin is pre-packaged with the theme. + } elseif( isset( $plugin['private'] ) && $plugin['private'] == true ) { + $_source = !empty( $plugin[ 'author' ] ) ? $plugin[ 'author' ] : __( 'Private Repository', 'tgmpa' ); + $_url = !empty( $plugin[ 'author_url' ] ) ? $plugin[ 'author_url' ] : ( !empty( $plugin[ 'external_url' ] ) ? $plugin[ 'external_url' ] : false ); + $_source = !empty( $_url ) ? "{$_source}" : $_source; + $table_data[$i]['source'] = $_source; + } else { + $table_data[$i]['source'] = __( 'Pre-Packaged', 'tgmpa' ); + } + } + // The plugin is from the WordPress repository. + else { + $table_data[$i]['source'] = __( 'WordPress Repository', 'tgmpa' ); + } + + $table_data[$i]['source'] = "
                    {$table_data[$i]['source']}
                    "; + $table_data[$i]['type'] = isset( $plugin['required'] ) && $plugin['required'] ? __( 'Required', 'tgmpa' ) : __( 'Recommended', 'tgmpa' ); + + if ( ! isset( $installed_plugins[$plugin['file_path']] ) ) { + $table_data[$i]['status'] = sprintf( '%1$s', __( 'Not Installed', 'tgmpa' ) ); + } elseif ( is_plugin_inactive( $plugin['file_path'] ) ) { + $table_data[$i]['status'] = sprintf( '%1$s', __( 'Installed But Not Activated', 'tgmpa' ) ); + } + + $table_data[$i]['file_path'] = $plugin['file_path']; + $table_data[$i]['url'] = isset( $plugin['source'] ) ? $plugin['source'] : 'repo'; + + $i++; + } + + // Sort plugins by Required/Recommended type and by alphabetical listing within each type. + $resort = array(); + $req = array(); + $rec = array(); + + // Grab all the plugin types. + foreach ( $table_data as $plugin ) { + $resort[] = $plugin['type']; + } + + // Sort each plugin by type. + foreach ( $resort as $type ) { + if ( 'Required' == $type ) { + $req[] = $type; + } else { + $rec[] = $type; + } + } + + // Sort alphabetically each plugin type array, merge them and then sort in reverse (lists Required plugins first). + sort( $req ); + sort( $rec ); + array_merge( $resort, $req, $rec ); + array_multisort( $resort, SORT_DESC, $table_data ); + + return $table_data; + + } + + /** + * Retrieve plugin data, given the plugin name. Taken from the + * TGM_Plugin_Activation class. + * + * Loops through the registered plugins looking for $name. If it finds it, + * it returns the $data from that plugin. Otherwise, returns false. + * + * @since 2.2.0 + * + * @param string $name Name of the plugin, as it was registered. + * @param string $data Optional. Array key of plugin data to return. Default is slug. + * @return string|boolean Plugin slug if found, false otherwise. + */ + protected function _get_plugin_data_from_name( $name, $data = 'slug' ) { + + foreach ( TGM_Plugin_Activation::$instance->plugins as $plugin => $values ) { + if ( $name == $values['name'] && isset( $values[$data] ) ) { + return $values[$data]; + } + } + + return false; + + } + + /** + * Create default columns to display important plugin information + * like type, action and status. + * + * @since 2.2.0 + * + * @param array $item Array of item data. + * @param string $column_name The name of the column. + */ + public function column_default( $item, $column_name ) { + + switch ( $column_name ) { + case 'source': + case 'type': + case 'status': + return $item[$column_name]; + } + + } + + /** + * Create default title column along with action links of 'Install' + * and 'Activate'. + * + * @since 2.2.0 + * + * @param array $item Array of item data. + * @return string The action hover links. + */ + public function column_plugin( $item ) { + + //echo "
                    "; print_r( $item ); echo "
                    "; + + $installed_plugins = get_plugins(); + $actions = array(); + + //** No need to display any hover links. */ + if ( is_plugin_active( $item['file_path'] ) || !isset( TGM_Plugin_Activation::$instance->plugins[ $item[ 'slug' ] ] ) ) { + return sprintf( '%1$s %2$s', $item['plugin'], $this->row_actions( $actions ) ); + } + + $plugin = TGM_Plugin_Activation::$instance->plugins[ $item[ 'slug' ] ]; + + //** We need to display the 'Install' hover link. */ + if ( ! isset( $installed_plugins[$item['file_path']] ) ) { + if( isset( $plugin[ 'private' ] ) && $plugin[ 'private' ] == true ) { + //** Ignore 'Install' action since plugin is not available for direct upload. */ + } else { + $actions = array( + 'install' => sprintf( + '' . __( 'Install', 'tgmpa' ) . '', + wp_nonce_url( + esc_url( add_query_arg( + array( + 'page' => TGM_Plugin_Activation::$instance->menu, + 'plugin' => $item['slug'], + 'plugin_name' => $item['sanitized_plugin'], + 'plugin_source' => $item['url'], + 'tgmpa-install' => 'install-plugin', + ), + admin_url( 'themes.php' ) + ) ), + 'tgmpa-install' + ), + $item['sanitized_plugin'] + ), + ); + } + } + //** We need to display the 'Activate' hover link. */ + elseif ( is_plugin_inactive( $item['file_path'] ) ) { + $actions = array( + 'activate' => sprintf( + '' . __( 'Activate', 'tgmpa' ) . '', + esc_url( add_query_arg( + array( + 'page' => TGM_Plugin_Activation::$instance->menu, + 'plugin' => $item['slug'], + 'plugin_name' => $item['sanitized_plugin'], + 'plugin_source' => $item['url'], + 'tgmpa-activate' => 'activate-plugin', + 'tgmpa-activate-nonce' => wp_create_nonce( 'tgmpa-activate' ), + ), + admin_url( 'themes.php' ) + ) ), + $item['sanitized_plugin'] + ), + ); + } + + return sprintf( '%1$s %2$s', $item['plugin'], $this->row_actions( $actions ) ); + + } + + /** + * Required for bulk installing. + * + * Adds a checkbox for each plugin. + * + * @since 2.2.0 + * + * @param array $item Array of item data. + * @return string The input checkbox with all necessary info. + */ + public function column_cb( $item ) { + //** Ignore Plugins if they are not in list */ + if ( is_plugin_active( $item['file_path'] ) || !isset( TGM_Plugin_Activation::$instance->plugins[ $item[ 'slug' ] ] ) ) { + return ''; + } + //** Ignore plugin's action if it's private and not installed. */ + $plugin = TGM_Plugin_Activation::$instance->plugins[ $item[ 'slug' ] ]; + $installed_plugins = get_plugins(); + if( isset( $plugin[ 'private' ] ) && $plugin[ 'private' ] == true && !isset( $installed_plugins[$item['file_path']] ) ) { + return ''; + } + $value = $item['file_path'] . ',' . $item['url'] . ',' . $item['sanitized_plugin']; + return sprintf( '', $this->_args['singular'], $value, $item['sanitized_plugin'] ); + } + + /** + * Sets default message within the plugins table if no plugins + * are left for interaction. + * + * Hides the menu item to prevent the user from clicking and + * getting a permissions error. + * + * @since 2.2.0 + */ + public function no_items() { + + printf( __( 'No plugins to install or activate. Return to the Dashboard', 'tgmpa' ), admin_url() ); + echo ''; + + } + + /** + * Output all the column information within the table. + * + * @since 2.2.0 + * + * @return array $columns The column names. + */ + public function get_columns() { + + $columns = array( + 'cb' => '', + 'plugin' => __( 'Plugin', 'tgmpa' ), + 'source' => __( 'Source', 'tgmpa' ), + 'type' => __( 'Type', 'tgmpa' ), + 'status' => __( 'Status', 'tgmpa' ) + ); + + return $columns; + + } + + /** + * Defines all types of bulk actions for handling + * registered plugins. + * + * @since 2.2.0 + * + * @return array $actions The bulk actions for the plugin install table. + */ + public function get_bulk_actions() { + + $actions = array( + 'tgmpa-bulk-install' => __( 'Install', 'tgmpa' ), + 'tgmpa-bulk-activate' => __( 'Activate', 'tgmpa' ), + ); + + return $actions; + + } + + /** + * Processes bulk installation and activation actions. + * + * The bulk installation process looks either for the $_POST + * information or for the plugin info within the $_GET variable if + * a user has to use WP_Filesystem to enter their credentials. + * + * @since 2.2.0 + */ + public function process_bulk_actions() { + + // Bulk installation process. + if ( 'tgmpa-bulk-install' === $this->current_action() ) { + check_admin_referer( 'bulk-' . $this->_args['plural'] ); + + // Prep variables to be populated. + $plugins_to_install = array(); + $plugin_installs = array(); + $plugin_path = array(); + $plugin_name = array(); + + // Look first to see if information has been passed via WP_Filesystem. + if ( isset( $_GET['plugins'] ) ) { + $plugins = explode( ',', stripslashes( $_GET['plugins'] ) ); + } + // Looks like the user can use the direct method, take from $_POST. + elseif ( isset( $_POST['plugin'] ) ) { + $plugins = (array) $_POST['plugin']; + } + // Nothing has been submitted. + else { + $plugins = array(); + } + + // Grab information from $_POST if available. + if ( isset( $_POST['plugin'] ) ) { + foreach ( $plugins as $plugin_data ) { + $plugins_to_install[] = explode( ',', $plugin_data ); + } + + foreach ( $plugins_to_install as $plugin_data ) { + $plugin_installs[] = $plugin_data[0]; + $plugin_path[] = $plugin_data[1]; + $plugin_name[] = $plugin_data[2]; + } + } + // Information has been passed via $_GET. + else { + foreach ( $plugins as $key => $value ) { + // Grab plugin slug for each plugin. + if ( 0 == $key % 3 || 0 == $key ) { + $plugins_to_install[] = $value; + $plugin_installs[] = $value; + } + } + } + + // Look first to see if information has been passed via WP_Filesystem. + if ( isset( $_GET['plugin_paths'] ) ) { + $plugin_paths = explode( ',', stripslashes( $_GET['plugin_paths'] ) ); + } + // Looks like the user doesn't need to enter his FTP creds. + elseif ( isset( $_POST['plugin'] ) ) { + $plugin_paths = (array) $plugin_path; + } + // Nothing has been submitted. + else { + $plugin_paths = array(); + } + + // Look first to see if information has been passed via WP_Filesystem. + if ( isset( $_GET['plugin_names'] ) ) { + $plugin_names = explode( ',', stripslashes( $_GET['plugin_names'] ) ); + } + // Looks like the user doesn't need to enter his FTP creds. + elseif ( isset( $_POST['plugin'] ) ) { + $plugin_names = (array) $plugin_name; + } + // Nothing has been submitted. + else { + $plugin_names = array(); + } + + // Loop through plugin slugs and remove already installed plugins from the list. + $i = 0; + foreach ( $plugin_installs as $key => $plugin ) { + if ( preg_match( '|.php$|', $plugin ) ) { + unset( $plugin_installs[$key] ); + + // If the plugin path isn't in the $_GET variable, we can unset the corresponding path. + if ( ! isset( $_GET['plugin_paths'] ) ) + unset( $plugin_paths[$i] ); + + // If the plugin name isn't in the $_GET variable, we can unset the corresponding name. + if ( ! isset( $_GET['plugin_names'] ) ) + unset( $plugin_names[$i] ); + } + $i++; + } + + // No need to proceed further if we have no plugins to install. + if ( empty( $plugin_installs ) ) { + return false; + } + + // Reset array indexes in case we removed already installed plugins. + $plugin_installs = array_values( $plugin_installs ); + $plugin_paths = array_values( $plugin_paths ); + $plugin_names = array_values( $plugin_names ); + + // If we grabbed our plugin info from $_GET, we need to decode it for use. + $plugin_installs = array_map( 'urldecode', $plugin_installs ); + $plugin_paths = array_map( 'urldecode', $plugin_paths ); + $plugin_names = array_map( 'urldecode', $plugin_names ); + + // Pass all necessary information via URL if WP_Filesystem is needed. + $url = wp_nonce_url( + esc_url( add_query_arg( + array( + 'page' => TGM_Plugin_Activation::$instance->menu, + 'tgmpa-action' => 'install-selected', + 'plugins' => urlencode( implode( ',', $plugins ) ), + 'plugin_paths' => urlencode( implode( ',', $plugin_paths ) ), + 'plugin_names' => urlencode( implode( ',', $plugin_names ) ), + ), + admin_url( 'themes.php' ) + ) ), + 'bulk-plugins' + ); + $method = ''; // Leave blank so WP_Filesystem can populate it as necessary. + $fields = array( 'action', '_wp_http_referer', '_wpnonce' ); // Extra fields to pass to WP_Filesystem. + + if ( false === ( $creds = request_filesystem_credentials( $url, $method, false, false, $fields ) ) ) { + return true; + } + + if ( ! WP_Filesystem( $creds ) ) { + request_filesystem_credentials( $url, $method, true, false, $fields ); // Setup WP_Filesystem. + return true; + } + + require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; // Need for plugins_api + require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; // Need for upgrade classes + + // Store all information in arrays since we are processing a bulk installation. + $api = array(); + $sources = array(); + $install_path = array(); + + // Loop through each plugin to install and try to grab information from WordPress API, if not create 'tgmpa-empty' scalar. + $i = 0; + foreach ( $plugin_installs as $plugin ) { + $api[$i] = plugins_api( 'plugin_information', array( 'slug' => $plugin, 'fields' => array( 'sections' => false ) ) ) ? plugins_api( 'plugin_information', array( 'slug' => $plugin, 'fields' => array( 'sections' => false ) ) ) : (object) $api[$i] = 'tgmpa-empty'; + $i++; + } + + if ( is_wp_error( $api ) ) { + wp_die( TGM_Plugin_Activation::$instance->strings['oops'] . var_dump( $api ) ); + } + + // Capture download links from $api or set install link to pre-packaged/private repo. + $i = 0; + foreach ( $api as $object ) { + $sources[$i] = isset( $object->download_link ) && 'repo' == $plugin_paths[$i] ? $object->download_link : $plugin_paths[$i]; + $i++; + } + + // Finally, all the data is prepared to be sent to the installer. + $url = esc_url( add_query_arg( array( 'page' => TGM_Plugin_Activation::$instance->menu ), admin_url( 'themes.php' ) ) ); + $nonce = 'bulk-plugins'; + $names = $plugin_names; + + // Create a new instance of TGM_Bulk_Installer. + $installer = new TGM_Bulk_Installer( $skin = new TGM_Bulk_Installer_Skin( compact( 'url', 'nonce', 'names' ) ) ); + + // Wrap the install process with the appropriate HTML. + echo '
                    '; + if ( version_compare( TGM_Plugin_Activation::$instance->wp_version, '3.8', '<' ) ) { + screen_icon( apply_filters( 'tgmpa_default_screen_icon', 'themes' ) ); + } + echo '

                    ' . esc_html( get_admin_page_title() ) . '

                    '; + // Process the bulk installation submissions. + $installer->bulk_install( $sources ); + echo '
                    '; + + return true; + } + + // Bulk activation process. + if ( 'tgmpa-bulk-activate' === $this->current_action() ) { + check_admin_referer( 'bulk-' . $this->_args['plural'] ); + + // Grab plugin data from $_POST. + $plugins = isset( $_POST['plugin'] ) ? (array) $_POST['plugin'] : array(); + $plugins_to_activate = array(); + + // Split plugin value into array with plugin file path, plugin source and plugin name. + foreach ( $plugins as $i => $plugin ) { + $plugins_to_activate[] = explode( ',', $plugin ); + } + + foreach ( $plugins_to_activate as $i => $array ) { + if ( ! preg_match( '|.php$|', $array[0] ) ) { + unset( $plugins_to_activate[$i] ); + } + } + + // Return early if there are no plugins to activate. + if ( empty( $plugins_to_activate ) ) { + return; + } + + $plugins = array(); + $plugin_names = array(); + + foreach ( $plugins_to_activate as $plugin_string ) { + $plugins[] = $plugin_string[0]; + $plugin_names[] = $plugin_string[2]; + } + + $count = count( $plugin_names ); // Count so we can use _n function. + $last_plugin = array_pop( $plugin_names ); // Pop off last name to prep for readability. + $imploded = empty( $plugin_names ) ? '' . $last_plugin . '' : '' . ( implode( ', ', $plugin_names ) . ' and ' . $last_plugin . '.' ); + + // Now we are good to go - let's start activating plugins. + $activate = activate_plugins( $plugins ); + + if ( is_wp_error( $activate ) ) { + echo '

                    ' . $activate->get_error_message() . '

                    '; + } else { + printf( '

                    %1$s %2$s

                    ', _n( 'The following plugin was activated successfully:', 'The following plugins were activated successfully:', $count, 'tgmpa' ), $imploded ); + } + + // Update recently activated plugins option. + $recent = (array) get_option( 'recently_activated' ); + + foreach ( $plugins as $plugin => $time ) { + if ( isset( $recent[$plugin] ) ) { + unset( $recent[$plugin] ); + } + } + + update_option( 'recently_activated', $recent ); + + unset( $_POST ); // Reset the $_POST variable in case user wants to perform one action after another. + } + } + + /** + * Prepares all of our information to be outputted into a usable table. + * + * @since 2.2.0 + */ + public function prepare_items() { + + $per_page = 100; // Set it high so we shouldn't have to worry about pagination. + $columns = $this->get_columns(); // Get all necessary column information. + $hidden = array(); // No columns to hide, but we must set as an array. + $sortable = array(); // No reason to make sortable columns. + $this->_column_headers = array( $columns, $hidden, $sortable ); // Get all necessary column headers. + + // Process our bulk actions here. + $this->process_bulk_actions(); + + // Store all of our plugin data into $items array so WP_List_Table can use it. + $this->items = $this->_gather_plugin_data(); + + } + + } + } + +} diff --git a/vendor/udx/lib-wp-bootstrap/lib/classes/class-tgm-plugin-activation.php b/vendor/udx/lib-wp-bootstrap/lib/classes/class-tgm-plugin-activation.php new file mode 100644 index 000000000..8064f8819 --- /dev/null +++ b/vendor/udx/lib-wp-bootstrap/lib/classes/class-tgm-plugin-activation.php @@ -0,0 +1,1033 @@ + + * @author Gary Jones + * @copyright Copyright (c) 2012, Thomas Griffin + * @license http://opensource.org/licenses/gpl-2.0.php GPL v2 or later + * @link https://github.com/thomasgriffin/TGM-Plugin-Activation + */ + +/* + Copyright 2014 Thomas Griffin (thomasgriffinmedia.com) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, as + published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +namespace UsabilityDynamics\WP { + + if ( ! class_exists( 'UsabilityDynamics\WP\TGM_Plugin_Activation' ) ) { + /** + * Automatic plugin installation and activation library. + * + * Creates a way to automatically install and activate plugins from within themes. + * The plugins can be either pre-packaged, downloaded from the WordPress + * Plugin Repository or downloaded from a private repository. + * + * @since 1.0.0 + * + * @package TGM-Plugin-Activation + * @author Thomas Griffin + * @author Gary Jones + */ + class TGM_Plugin_Activation { + + /** + * Holds a copy of itself, so it can be referenced by the class name. + * + * @since 1.0.0 + * + * @var TGM_Plugin_Activation + */ + public static $instance; + + /** + * Holds arrays of plugin details. + * + * @since 1.0.0 + * + * @var array + */ + public $plugins = array(); + + /** + * + */ + public $referrers = array(); + + /** + * Name of the querystring argument for the admin page. + * + * @since 1.0.0 + * + * @var string + */ + public $menu = 'ud-install-plugins'; + + /** + * Default absolute path to folder containing pre-packaged plugin zip files. + * + * @since 2.0.0 + * + * @var string Absolute path prefix to packaged zip file location. Default is empty string. + */ + public $default_path = ''; + + /** + * Flag to show admin notices or not. + * + * @since 2.1.0 + * + * @var boolean + */ + public $has_notices = true; + + /** + * Flag to determine if the user can dismiss the notice nag. + * + * @since 2.4.0 + * + * @var boolean + */ + public $dismissable = true; + + /** + * Message to be output above nag notice if dismissable is false. + * + * @since 2.4.0 + * + * @var string + */ + public $dismiss_msg = ''; + + /** + * Flag to set automatic activation of plugins. Off by default. + * + * @since 2.2.0 + * + * @var boolean + */ + public $is_automatic = false; + + /** + * Optional message to display before the plugins table. + * + * @since 2.2.0 + * + * @var string Message filtered by wp_kses_post(). Default is empty string. + */ + public $message = ''; + + /** + * Holds configurable array of strings. + * + * Default values are added in the constructor. + * + * @since 2.0.0 + * + * @var array + */ + public $strings = array(); + + /** + * Error Notice types. + * + * @var array + */ + public $error_types = array( + 'notice_can_install_required', + 'notice_can_activate_required', + 'notice_ask_to_update', + ); + + /** + * Holds the version of WordPress. + * + * @since 2.4.0 + * + * @var int + */ + public $wp_version; + + /** + * Adds a reference of this object to $instance, populates default strings, + * does the tgmpa_init action hook, and hooks in the interactions to init. + * + * @since 1.0.0 + * + * @see TGM_Plugin_Activation::init() + */ + private function __construct() { + + $this->strings = array( + 'page_title' => __( 'Install Required Plugins', 'tgmpa' ), + 'menu_title' => __( 'Install Plugins', 'tgmpa' ), + 'installing' => __( 'Installing Plugin: %s', 'tgmpa' ), + 'oops' => __( 'Something went wrong.', 'tgmpa' ), + 'notice_can_install_required' => _n_noop( '%2$s requires the following plugin: %1$s.', '%2$s requires the following plugins: %1$s.' ), + 'notice_can_install_recommended' => _n_noop( '%2$s recommends the following plugin: %1$s.', '%2$s recommends the following plugins: %1$s.' ), + 'notice_cannot_install' => _n_noop( 'Sorry, but you do not have the correct permissions to install the %s plugin. Contact the administrator of this site for help on getting the plugin installed.', 'Sorry, but you do not have the correct permissions to install the %s plugins. Contact the administrator of this site for help on getting the plugins installed.' ), + 'notice_can_activate_required' => _n_noop( 'The following required plugin is currently inactive: %1$s.', 'The following required plugins are currently inactive: %1$s.' ), + 'notice_can_activate_recommended'=> _n_noop( 'The following recommended plugin is currently inactive: %1$s.', 'The following recommended plugins are currently inactive: %1$s.' ), + 'notice_cannot_activate' => _n_noop( 'Sorry, but you do not have the correct permissions to activate the %s plugin. Contact the administrator of this site for help on getting the plugin activated.', 'Sorry, but you do not have the correct permissions to activate the %s plugins. Contact the administrator of this site for help on getting the plugins activated.' ), + 'notice_ask_to_update' => _n_noop( 'The following plugin needs to be updated to its latest version to ensure maximum compatibility with %2$s: %1$s.', 'The following plugins need to be updated to their latest version to ensure maximum compatibility with %2$s: %1$s.' ), + 'notice_cannot_update' => _n_noop( 'Sorry, but you do not have the correct permissions to update the %s plugin. Contact the administrator of this site for help on getting the plugin updated.', 'Sorry, but you do not have the correct permissions to update the %s plugins. Contact the administrator of this site for help on getting the plugins updated.' ), + 'install_link' => _n_noop( 'Begin installing plugin', 'Begin installing plugins' ), + 'activate_link' => _n_noop( 'Begin activating plugin', 'Begin activating plugins' ), + 'return' => __( 'Return to Required Plugins Installer', 'tgmpa' ), + 'dashboard' => __( 'Return to the dashboard', 'tgmpa' ), + 'plugin_activated' => __( 'Plugin activated successfully.', 'tgmpa' ), + 'activated_successfully' => __( 'The following plugin was activated successfully:', 'tgmpa' ), + 'complete' => __( 'All plugins installed and activated successfully. %1$s', 'tgmpa' ), + 'dismiss' => __( 'Dismiss this notice', 'tgmpa' ), + ); + + // Set the current WordPress version. + global $wp_version; + $this->wp_version = $wp_version; + + // Announce that the class is ready, and pass the object (for advanced use). + do_action_ref_array( 'tgmpa_init', array( $this ) ); + + // When the rest of WP has loaded, kick-start the rest of the class. + //add_action( 'plugins_loaded', array( $this, 'init' ), 0 ); + add_action( 'init', array( $this, 'init' ) ); + + } + + /** + * Initialise the interactions between this class and WordPress. + * + * Hooks in three new methods for the class: admin_menu, notices and styles. + * + * @since 2.0.0 + * + * @see TGM_Plugin_Activation::admin_menu() + * @see TGM_Plugin_Activation::notices() + * @see TGM_Plugin_Activation::styles() + */ + public function init() { + + // After this point, the plugins should be registered and the configuration set. + + // Proceed only if we have plugins to handle. + if ( $this->plugins ) { + $sorted = array(); + + foreach ( $this->plugins as $plugin ) { + $sorted[] = $plugin['name']; + } + + array_multisort( $sorted, SORT_ASC, $this->plugins ); + + add_action( 'admin_menu', array( $this, 'admin_menu' ) ); + add_filter( 'install_plugin_complete_actions', array( $this, 'actions' ) ); + add_action( 'switch_theme', array( $this, 'flush_plugins_cache' ) ); + + // Load admin bar in the header to remove flash when installing plugins. + if ( $this->is_tgmpa_page() ) { + remove_action( 'wp_footer', 'wp_admin_bar_render', 1000 ); + remove_action( 'admin_footer', 'wp_admin_bar_render', 1000 ); + add_action( 'wp_head', 'wp_admin_bar_render', 1000 ); + add_action( 'admin_head', 'wp_admin_bar_render', 1000 ); + } + + if ( $this->has_notices ) { + add_action( 'admin_init', array( $this, 'admin_init' ), 1 ); + add_action( 'admin_enqueue_scripts', array( $this, 'thickbox' ) ); + } + + // Setup the force activation hook. + foreach ( $this->plugins as $plugin ) { + if ( isset( $plugin['force_activation'] ) && true === $plugin['force_activation'] ) { + add_action( 'admin_init', array( $this, 'force_activation' ) ); + break; + } + } + + // Setup the force deactivation hook. + foreach ( $this->plugins as $plugin ) { + if ( isset( $plugin['force_deactivation'] ) && true === $plugin['force_deactivation'] ) { + add_action( 'switch_theme', array( $this, 'force_deactivation' ) ); + break; + } + } + } + + } + + /** + * Handles calls to show plugin information via links in the notices. + * + * We get the links in the admin notices to point to the TGMPA page, rather + * than the typical plugin-install.php file, so we can prepare everything + * beforehand. + * + * WP doesn't make it easy to show the plugin information in the thickbox - + * here we have to require a file that includes a function that does the + * main work of displaying it, enqueue some styles, set up some globals and + * finally call that function before exiting. + * + * Down right easy once you know how... + * + * @since 2.1.0 + * + * @global string $tab Used as iframe div class names, helps with styling + * @global string $body_id Used as the iframe body ID, helps with styling + * @return null Returns early if not the TGMPA page. + */ + public function admin_init() { + + if ( ! $this->is_tgmpa_page() ) { + return; + } + + if ( isset( $_REQUEST['tab'] ) && 'plugin-information' == $_REQUEST['tab'] ) { + require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; // Need for install_plugin_information(). + + wp_enqueue_style( 'plugin-install' ); + + global $tab, $body_id; + $body_id = $tab = 'plugin-information'; + + install_plugin_information(); + + exit; + } + + } + + /** + * Enqueues thickbox scripts/styles for plugin info. + * + * Thickbox is not automatically included on all admin pages, so we must + * manually enqueue it for those pages. + * + * Thickbox is only loaded if the user has not dismissed the admin + * notice or if there are any plugins left to install and activate. + * + * @since 2.1.0 + */ + public function thickbox() { + add_thickbox(); + } + + /** + * Adds submenu page under 'Appearance' tab. + * + * This method adds the submenu page letting users know that a required + * plugin needs to be installed. + * + * This page disappears once the plugin has been installed and activated. + * + * @since 1.0.0 + * + * @see TGM_Plugin_Activation::init() + * @see TGM_Plugin_Activation::install_plugins_page() + */ + public function admin_menu() { + + // Make sure privileges are correct to see the page + if ( ! current_user_can( 'install_plugins' ) ) { + return; + } + + $this->populate_file_path(); + + foreach ( $this->plugins as $plugin ) { + if ( ! is_plugin_active( $plugin['file_path'] ) ) { + add_theme_page( + $this->strings['page_title'], // Page title. + $this->strings['menu_title'], // Menu title. + 'edit_theme_options', // Capability. + $this->menu, // Menu slug. + array( $this, 'install_plugins_page' ) // Callback. + ); + break; + } + } + + } + + /** + * Echoes plugin installation form. + * + * This method is the callback for the admin_menu method function. + * This displays the admin page and form area where the user can select to install and activate the plugin. + * + * @since 1.0.0 + * + * @return null Aborts early if we're processing a plugin installation action + */ + public function install_plugins_page() { + + // Store new instance of plugin table in object. + $plugin_table = new TGMPA_List_Table; + + // Return early if processing a plugin installation action. + if ( isset( $_POST['action'] ) && 'tgmpa-bulk-install' == $_POST['action'] && $plugin_table->process_bulk_actions() || $this->do_plugin_install() ) { + return; + } + + ?> +
                    + + wp_version, '3.8', '<' ) ) { + screen_icon( apply_filters( 'ud_default_screen_icon', 'themes' ) ); + } ?> +

                    + prepare_items(); ?> + + message ) ) { + echo wp_kses_post( $this->message ); + } ?> + +
                    + + display(); ?> +
                    + +
                    + $this->menu, + 'plugin' => $plugin['slug'], + 'plugin_name' => $plugin['name'], + 'plugin_source' => $plugin['source'], + 'tgmpa-install' => 'install-plugin', + ), + admin_url( 'themes.php' ) + ) ), + 'tgmpa-install' + ); + $method = ''; // Leave blank so WP_Filesystem can populate it as necessary. + $fields = array( 'tgmpa-install' ); // Extra fields to pass to WP_Filesystem. + + if ( false === ( $creds = request_filesystem_credentials( $url, $method, false, false, $fields ) ) ) { + return true; + } + + if ( ! WP_Filesystem( $creds ) ) { + request_filesystem_credentials( $url, $method, true, false, $fields ); // Setup WP_Filesystem. + return true; + } + + require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; // Need for plugins_api. + require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; // Need for upgrade classes. + + // Set plugin source to WordPress API link if available. + if ( isset( $plugin['source'] ) && 'repo' == $plugin['source'] ) { + $api = plugins_api( 'plugin_information', array( 'slug' => $plugin['slug'], 'fields' => array( 'sections' => false ) ) ); + + if ( is_wp_error( $api ) ) { + wp_die( $this->strings['oops'] . var_dump( $api ) ); + } + + if ( isset( $api->download_link ) ) { + $plugin['source'] = $api->download_link; + } + } + + // Set type, based on whether the source starts with http:// or https://. + $type = preg_match( '|^http(s)?://|', $plugin['source'] ) ? 'web' : 'upload'; + + // Prep variables for Plugin_Installer_Skin class. + $title = sprintf( $this->strings['installing'], $plugin['name'] ); + $url = esc_url( add_query_arg( array( 'action' => 'install-plugin', 'plugin' => $plugin['slug'] ), 'update.php' ) ); + if ( isset( $_GET['from'] ) ) { + $url .= esc_url( add_query_arg( 'from', urlencode( stripslashes( $_GET['from'] ) ), $url ) ); + } + + $nonce = 'install-plugin_' . $plugin['slug']; + + // Prefix a default path to pre-packaged plugins. + $source = ( 'upload' == $type ) ? $this->default_path . $plugin['source'] : $plugin['source']; + + // Create a new instance of Plugin_Upgrader. + $upgrader = new \Plugin_Upgrader( $skin = new \Plugin_Installer_Skin( compact( 'type', 'title', 'url', 'nonce', 'plugin', 'api' ) ) ); + + // Perform the action and install the plugin from the $source urldecode(). + $upgrader->install( $source ); + + // Flush plugins cache so we can make sure that the installed plugins list is always up to date. + wp_cache_flush(); + + // Only activate plugins if the config option is set to true. + if ( $this->is_automatic ) { + $plugin_activate = $upgrader->plugin_info(); // Grab the plugin info from the Plugin_Upgrader method. + $activate = activate_plugin( $plugin_activate ); // Activate the plugin. + $this->populate_file_path(); // Re-populate the file path now that the plugin has been installed and activated. + + if ( is_wp_error( $activate ) ) { + echo '

                    ' . $activate->get_error_message() . '

                    '; + echo '

                    ' . $this->strings['return'] . '

                    '; + return true; // End it here if there is an error with automatic activation + } + else { + echo '

                    ' . $this->strings['plugin_activated'] . '

                    '; + } + } + + // Display message based on if all plugins are now active or not. + $complete = array(); + foreach ( $this->plugins as $plugin ) { + if ( ! is_plugin_active( $plugin['file_path'] ) ) { + echo '

                    ' . $this->strings['return'] . '

                    '; + $complete[] = $plugin; + break; + } + // Nothing to store. + else { + $complete[] = ''; + } + } + + // Filter out any empty entries. + $complete = array_filter( $complete ); + + // All plugins are active, so we display the complete string and hide the plugin menu. + if ( empty( $complete ) ) { + echo '

                    ' . sprintf( $this->strings['complete'], '' . __( 'Return to the Dashboard', 'tgmpa' ) . '' ) . '

                    '; + echo ''; + } + + return true; + } + // Checks for actions from hover links to process the activation. + elseif ( isset( $_GET['plugin'] ) && ( isset( $_GET['tgmpa-activate'] ) && 'activate-plugin' == $_GET['tgmpa-activate'] ) ) { + check_admin_referer( 'tgmpa-activate', 'tgmpa-activate-nonce' ); + + // Populate $plugin array with necessary information. + $plugin['name'] = $_GET['plugin_name']; + $plugin['slug'] = $_GET['plugin']; + $plugin['source'] = $_GET['plugin_source']; + + $plugin_path = $this->_get_plugin_basename_from_slug($plugin['slug']); // Retrieve all plugins. + $activate = activate_plugin( $plugin_path ); // Activate the plugin. + + if ( is_wp_error( $activate ) ) { + echo '

                    ' . $activate->get_error_message() . '

                    '; + echo '

                    ' . $this->strings['return'] . '

                    '; + return true; // End it here if there is an error with activation. + } + else { + // Make sure message doesn't display again if bulk activation is performed immediately after a single activation. + if ( ! isset( $_POST['action'] ) ) { + $msg = $this->strings['activated_successfully'] . ' ' . $plugin['name'] . ''; + echo '

                    ' . $msg . '

                    '; + } + } + } + + return false; + + } + + /** + * Echoes required plugin notice. + * + * Outputs a message telling users that a specific plugin is required for + * their theme. If appropriate, it includes a link to the form page where + * users can install and activate the plugin. + * + * @since 1.0.0 + * + * @global object $current_screen + * @return null Returns early if we're on the Install page. + */ + public function notices( $referrer = false ) { + //** Check if get_plugins() function exists. This is required on the front end of the */ + //** site, since it is in a file that is normally only loaded in the admin. */ + if ( ! function_exists( 'get_plugins' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + + $installed_plugins = \get_plugins(); // Retrieve a list of all the plugins + $this->populate_file_path(); + + $message = array(); // Store the messages in an array to be outputted after plugins have looped through. + + $e_install_link = false; // Set to false, change to true in loop if conditions exist, used for action link 'install'. + $e_install_link_count = 0; // Used to determine plurality of install action link text. + $e_activate_link = false; // Set to false, change to true in loop if conditions exist, used for action link 'activate'. + $e_activate_link_count = 0; // Used to determine plurality of activate action link text. + + $m_install_link = false; // Set to false, change to true in loop if conditions exist, used for action link 'install'. + $m_install_link_count = 0; // Used to determine plurality of install action link text. + $m_activate_link = false; // Set to false, change to true in loop if conditions exist, used for action link 'activate'. + $m_activate_link_count = 0; // Used to determine plurality of activate action link text. + + foreach ( $this->referrers as $plugin ) { + //** We must return only notices for referrer */ + if( empty( $referrer ) || $referrer != $plugin[ '_referrer' ] || !isset( $this->plugins[ $plugin[ 'slug' ] ] ) ) { + continue; + } + $plugin[ 'file_path' ] = $this->plugins[ $plugin[ 'slug' ] ][ 'file_path' ]; + // If the plugin is installed and active, check for minimum version argument before moving forward. + if ( is_plugin_active( $plugin['file_path'] ) ) { + // A minimum version has been specified. + if ( isset( $plugin['version'] ) ) { + if ( isset( $installed_plugins[$plugin['file_path']]['Version'] ) ) { + // If the current version is less than the minimum required version, we display a message. + if ( version_compare( $installed_plugins[$plugin['file_path']]['Version'], $plugin['version'], '<' ) ) { + if ( current_user_can( 'install_plugins' ) ) { + $message['notice_ask_to_update'][] = $plugin; + } else { + $message['notice_cannot_update'][] = $plugin; + } + } + } + // Can't find the plugin, so iterate to the next condition. + else { + continue; + } + } + // No minimum version specified, so iterate over the plugin. + else { + continue; + } + } + + // Not installed. + if ( ! isset( $installed_plugins[$plugin['file_path']] ) ) { + if ( current_user_can( 'install_plugins' ) ) { + if ( isset( $plugin['required'] ) && $plugin['required'] ) { + $e_install_link = true; // We need to display the 'install' action link. + $e_install_link_count++; // Increment the install link count. + $message['notice_can_install_required'][] = $plugin; + } + // This plugin is only recommended. + else { + $m_install_link = true; // We need to display the 'install' action link. + $m_install_link_count++; // Increment the install link count. + $message['notice_can_install_recommended'][] = $plugin; + } + } elseif( !is_user_logged_in() && isset( $plugin['required'] ) && $plugin['required'] ) { + $message['notice_can_install_required'][] = $plugin; + } + // Need higher privileges to install the plugin. + else { + if ( isset( $plugin['required'] ) && $plugin['required'] ) { + $message['notice_can_install_required'][] = $plugin; + $message['notice_cannot_activate'][] = $plugin; + } + else { + $message['notice_cannot_activate'][] = $plugin; + } + } + } + // Installed but not active. + elseif ( is_plugin_inactive( $plugin['file_path'] ) ) { + if ( current_user_can( 'activate_plugins' ) ) { + if ( isset( $plugin['required'] ) && $plugin['required'] ) { + $e_activate_link = true; // We need to display the 'activate' action link. + $e_activate_link_count++; // Increment the activate link count. + $message['notice_can_activate_required'][] = $plugin; + } + // This plugin is only recommended. + else { + $m_activate_link = true; // We need to display the 'activate' action link. + $m_activate_link_count++; // Increment the activate link count. + $message['notice_can_activate_recommended'][] = $plugin; + } + } elseif( !is_user_logged_in() && isset( $plugin['required'] ) && $plugin['required'] ) { + $message['notice_can_install_required'][] = $plugin; + } + // Need higher privileges to activate the plugin. + else { + if ( isset( $plugin['required'] ) && $plugin['required'] ) { + $message['notice_can_install_required'][] = $plugin; + $message['notice_cannot_activate'][] = $plugin; + } + else { + $message['notice_cannot_activate'][] = $plugin; + } + + } + } + } + + //return $message; + + $prepared = array(); + + // If we have notices to display, we move forward. + if ( ! empty( $message ) ) { + krsort( $message ); // Sort messages. + + // Grab all plugin names. + foreach ( $message as $type => $plugin_groups ) { + $linked_plugin_groups = array(); + + // Count number of plugins in each message group to calculate singular/plural message. + $count = count( $plugin_groups ); + + // Loop through the plugin names to make the ones pulled from the .org repo linked. + foreach ( $plugin_groups as $plugin ) { + $plugin_group_single_name = $plugin[ 'name' ]; + $external_url = $this->_get_plugin_data_from_name( $plugin_group_single_name, 'external_url' ); + $source = $this->_get_plugin_data_from_name( $plugin_group_single_name, 'source' ); + + if ( $external_url && preg_match( '|^http(s)?://|', $external_url ) ) { + $linked_plugin_groups[] = '' . $plugin_group_single_name . ''; + } + elseif ( ! $source || preg_match( '|^http://wordpress.org/extend/plugins/|', $source ) ) { + $url = esc_url( add_query_arg( + array( + 'tab' => 'plugin-information', + 'plugin' => $this->_get_plugin_data_from_name( $plugin_group_single_name ), + 'TB_iframe' => 'true', + 'width' => '640', + 'height' => '500', + ), + admin_url( 'plugin-install.php' ) + ) ); + + $linked_plugin_groups[] = '' . $plugin_group_single_name . ''; + } + else { + $linked_plugin_groups[] = $plugin_group_single_name; // No hyperlink. + } + + if ( isset( $linked_plugin_groups ) && (array) $linked_plugin_groups ) { + $plugin_groups = $linked_plugin_groups; + } + } + + $last_plugin = array_pop( $plugin_groups ); // Pop off last name to prep for readability. + $imploded = empty( $plugin_groups ) ? '' . $last_plugin . '' : '' . ( implode( ', ', $plugin_groups ) . ' and ' . $last_plugin . '' ); + + $prepared['messages'][] = array( + 'type' => ( in_array( $type, $this->error_types ) && $plugin[ 'required' ] ? 'error' : 'message' ), + 'value' => sprintf( translate_nooped_plural( $this->strings[$type], $count, 'tgmpa' ), $imploded, $plugin[ '_referrer_name' ], $count ), + ); + + } + + //** Setup variables to determine if action links are needed. */ + $e_show_install_link = $e_install_link ? '' . translate_nooped_plural( $this->strings['install_link'], $e_install_link_count, 'tgmpa' ) . '' : ''; + $e_show_activate_link = $e_activate_link ? '' . translate_nooped_plural( $this->strings['activate_link'], $e_activate_link_count, 'tgmpa' ) . '' : ''; + + $m_show_install_link = $m_install_link ? '' . translate_nooped_plural( $this->strings['install_link'], $m_install_link_count, 'tgmpa' ) . '' : ''; + $m_show_activate_link = $m_activate_link ? '' . translate_nooped_plural( $this->strings['activate_link'], $m_activate_link_count, 'tgmpa' ) . '' : ''; + + //** Define all of the action links. */ + $prepared[ 'links' ] = array( + 'error' => array_filter( array( + 'install' => ( current_user_can( 'install_plugins' ) ) ? $e_show_install_link : false, + 'activate' => ( current_user_can( 'activate_plugins' ) ) ? $e_show_activate_link : false, + ) ), + 'message' => array_filter( array( + 'install' => ( current_user_can( 'install_plugins' ) ) ? $m_show_install_link : false, + 'activate' => ( current_user_can( 'activate_plugins' ) ) ? $m_show_activate_link : false, + ) ), + ); + } + + return $prepared; + } + + /** + * Add individual plugin to our collection of plugins. + * + * If the required keys are not set or the plugin has already + * been registered, the plugin is not added. + * + * @since 2.0.0 + * + * @param array $plugin Array of plugin arguments. + */ + public function register( $plugin ) { + if ( ! isset( $plugin['slug'] ) || ! isset( $plugin['name'] ) ) { + return; + } + if( isset( $this->plugins[ $plugin[ 'slug' ] ] ) ) { + $_plugin = $this->plugins[ $plugin[ 'slug' ] ]; + //** Version must be set the highest to prevent issues. */ + if( !empty( $_plugin[ 'version' ] ) && !empty( $plugin[ 'version' ] ) ) { + $version = version_compare( $_plugin[ 'version' ], $plugin[ 'version' ], '<' ) ? $plugin[ 'version' ] : $_plugin[ 'version' ]; + } else { + $version = !empty( $plugin[ 'version' ] ) ? $plugin[ 'version' ] : ( !empty( $_plugin[ 'version' ] ) ? $_plugin[ 'version' ] : false ); + } + if( !empty( $version ) ) { + $this->plugins[ $plugin[ 'slug' ] ][ 'version' ] = $version; + } + //** Parent plugin must be set as required if any child plugin requires it. */ + $this->plugins[ $plugin[ 'slug' ] ][ 'required' ] = $_plugin[ 'required' ] == true ? $_plugin[ 'required' ] : $plugin[ 'required' ]; + } else { + $_plugin = $plugin; + unset( $_plugin[ '_referrer' ] ); + unset( $_plugin[ '_referrer_name' ] ); + $this->plugins[ $plugin[ 'slug' ] ] = $_plugin; + } + $this->referrers[] = $plugin; + } + + /** + * Amend default configuration settings. + * + * @since 2.0.0 + * + * @param array $config Array of config options to pass as class properties. + */ + public function config( $config ) { + + $keys = array( 'default_path', 'has_notices', 'dismissable', 'dismiss_msg', 'menu', 'is_automatic', 'message', 'strings' ); + + foreach ( $keys as $key ) { + if ( isset( $config[$key] ) ) { + if ( is_array( $config[$key] ) ) { + foreach ( $config[$key] as $subkey => $value ) { + $this->{$key}[$subkey] = $value; + } + } else { + $this->$key = $config[$key]; + } + } + } + + } + + /** + * Amend action link after plugin installation. + * + * @since 2.0.0 + * + * @param array $install_actions Existing array of actions. + * @return array Amended array of actions. + */ + public function actions( $install_actions ) { + + // Remove action links on the TGMPA install page. + if ( $this->is_tgmpa_page() ) { + return false; + } + + return $install_actions; + + } + + /** + * Flushes the plugins cache on theme switch to prevent stale entries + * from remaining in the plugin table. + * + * @since 2.4.0 + */ + public function flush_plugins_cache() { + + wp_cache_flush(); + + } + + /** + * Set file_path key for each installed plugin. + * + * @since 2.1.0 + */ + public function populate_file_path() { + + // Add file_path key for all plugins. + foreach ( $this->plugins as $plugin => $values ) { + $this->plugins[$plugin]['file_path'] = $this->_get_plugin_basename_from_slug( $values['slug'] ); + } + + } + + /** + * Helper function to extract the file path of the plugin file from the + * plugin slug, if the plugin is installed. + * + * @since 2.0.0 + * + * @param string $slug Plugin slug (typically folder name) as provided by the developer. + * @return string Either file path for plugin if installed, or just the plugin slug. + */ + protected function _get_plugin_basename_from_slug( $slug ) { + $keys = array_keys( get_plugins() ); + $_keys = array(); + /** Try to get slug of activated plugin at first */ + foreach ( $keys as $key ) { + if ( preg_match( '|^' . $slug .'(-v?[0-9\.]+)?/|', $key ) ) { + if( is_plugin_active( $key ) ) { + return $key; + } else { + array_push( $_keys, $key ); + } + } + } + /** Get key from any non activated but installed matched plugin */ + if( !empty( $_keys ) ) { + return $_keys[0]; + } + return $slug; + } + + /** + * Retrieve plugin data, given the plugin name. + * + * Loops through the registered plugins looking for $name. If it finds it, + * it returns the $data from that plugin. Otherwise, returns false. + * + * @since 2.1.0 + * + * @param string $name Name of the plugin, as it was registered. + * @param string $data Optional. Array key of plugin data to return. Default is slug. + * @return string|boolean Plugin slug if found, false otherwise. + */ + protected function _get_plugin_data_from_name( $name, $data = 'slug' ) { + + foreach ( $this->plugins as $plugin => $values ) { + if ( $name == $values['name'] && isset( $values[$data] ) ) { + return $values[$data]; + } + } + + return false; + + } + + /** + * Determine if we're on the TGMPA Install page. + * + * @since 2.1.0 + * + * @return boolean True when on the TGMPA page, false otherwise. + */ + public function is_tgmpa_page() { + + if ( isset( $_GET['page'] ) && $this->menu === $_GET['page'] ) { + return true; + } + + return false; + + } + + /** + * Forces plugin activation if the parameter 'force_activation' is + * set to true. + * + * This allows theme authors to specify certain plugins that must be + * active at all times while using the current theme. + * + * Please take special care when using this parameter as it has the + * potential to be harmful if not used correctly. Setting this parameter + * to true will not allow the specified plugin to be deactivated unless + * the user switches themes. + * + * @since 2.2.0 + */ + public function force_activation() { + // Set file_path parameter for any installed plugins. + $this->populate_file_path(); + $installed_plugins = get_plugins(); + foreach ( $this->plugins as $plugin ) { + // Oops, plugin isn't there so iterate to next condition. + if ( isset( $plugin['force_activation'] ) && $plugin['force_activation'] && ! isset( $installed_plugins[$plugin['file_path']] ) ) { + continue; + } + // There we go, activate the plugin. + elseif ( isset( $plugin['force_activation'] ) && $plugin['force_activation'] && is_plugin_inactive( $plugin['file_path'] ) ) { + activate_plugin( $plugin['file_path'] ); + } + } + } + + /** + * Forces plugin deactivation if the parameter 'force_deactivation' + * is set to true. + * + * This allows theme authors to specify certain plugins that must be + * deactived upon switching from the current theme to another. + * + * Please take special care when using this parameter as it has the + * potential to be harmful if not used correctly. + * + * @since 2.2.0 + */ + public function force_deactivation() { + + // Set file_path parameter for any installed plugins. + $this->populate_file_path(); + + foreach ( $this->plugins as $plugin ) { + // Only proceed forward if the paramter is set to true and plugin is active. + if ( isset( $plugin['force_deactivation'] ) && $plugin['force_deactivation'] && is_plugin_active( $plugin['file_path'] ) ) { + deactivate_plugins( $plugin['file_path'] ); + } + } + + } + + /** + * Returns the singleton instance of the class. + * + * @since 2.4.0 + * + * @return object The TGM_Plugin_Activation object. + */ + public static function get_instance() { + if ( ! isset( self::$instance ) && !( self::$instance instanceof TGM_Plugin_Activation ) ) { + self::$instance = new TGM_Plugin_Activation(); + } + return self::$instance; + } + + } + + } + +} diff --git a/vendor/udx/lib-wp-bootstrap/lib/classes/class-utility.php b/vendor/udx/lib-wp-bootstrap/lib/classes/class-utility.php index 2a28eb12b..71fba229f 100644 --- a/vendor/udx/lib-wp-bootstrap/lib/classes/class-utility.php +++ b/vendor/udx/lib-wp-bootstrap/lib/classes/class-utility.php @@ -101,6 +101,58 @@ static private function _path_dir( $instance ) { return $path; } + /** + * Localization Functionality. + * + * Replaces array's l10n data. + * Helpful for localization of data which is stored in JSON files ( see /schemas ) + * + * Usage: + * + * add_filter( 'ud::schema::localization', function($locals){ + * return array_merge( array( 'value_for_translating' => __( 'Blah Blah' ) ), $locals ); + * }); + * + * $result = self::l10n_localize (array( + * 'key' => 'l10n.value_for_translating' + * ) ); + * + * + * @param array $data + * @param array $l10n translated values + * @return array + * @author peshkov@UD + */ + static public function l10n_localize( $data, $l10n = array() ) { + + if ( !is_array( $data ) && !is_object( $data ) ) { + return $data; + } + + //** The Localization's list. */ + $l10n = apply_filters( 'ud::schema::localization', $l10n ); + + //** Replace l10n entries */ + foreach( $data as $k => $v ) { + if ( is_array( $v ) ) { + $data[ $k ] = self::l10n_localize( $v, $l10n ); + } elseif ( is_string( $v ) ) { + if ( strpos( $v, 'l10n' ) !== false ) { + preg_match_all( '/l10n\.([^\s]*)/', $v, $matches ); + if ( !empty( $matches[ 1 ] ) ) { + foreach ( $matches[ 1 ] as $i => $m ) { + if ( array_key_exists( $m, $l10n ) ) { + $data[ $k ] = str_replace( $matches[ 0 ][ $i ], $l10n[ $m ], $data[ $k ] ); + } + } + } + } + } + } + + return $data; + } + } } diff --git a/vendor/udx/lib-wp-bootstrap/static/scripts/ud-dismiss.js b/vendor/udx/lib-wp-bootstrap/static/scripts/ud-dismiss.js index 8d248e79a..fa7edb809 100644 --- a/vendor/udx/lib-wp-bootstrap/static/scripts/ud-dismiss.js +++ b/vendor/udx/lib-wp-bootstrap/static/scripts/ud-dismiss.js @@ -11,6 +11,7 @@ jQuery( document ).ready( function () { var data = { action: 'ud_dismiss', key: _this.data('key'), + _ajax_nonce: _this.data('nonce'), } jQuery.post( _ud_vars.ajaxurl, data, function ( result_data ) { diff --git a/vendor/wpmetabox/meta-box/.distignore b/vendor/wpmetabox/meta-box/.distignore new file mode 100644 index 000000000..a844e715c --- /dev/null +++ b/vendor/wpmetabox/meta-box/.distignore @@ -0,0 +1,24 @@ +node_modules +.git +.github +.gitignore +.gitattributes + +.DS_Store +Thumbs.db + +.distignore + +composer.json +composer.lock +package-lock.json +package.json + +gulpfile.js +phpcs.xml +phpstan.neon +README.md + +tests +css/scss + diff --git a/vendor/wpmetabox/meta-box/README.md b/vendor/wpmetabox/meta-box/README.md deleted file mode 100644 index caa5d09ab..000000000 --- a/vendor/wpmetabox/meta-box/README.md +++ /dev/null @@ -1,167 +0,0 @@ -# Meta Box - WordPress Custom Fields Framework - -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/wpmetabox/meta-box/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/wpmetabox/meta-box/?branch=master) -![Total Downloads](https://img.shields.io/wordpress/plugin/dt/meta-box.svg) -![WordPress](https://img.shields.io/wordpress/v/meta-box.svg) -[![License](https://img.shields.io/packagist/l/wpmetabox/meta-box.svg)](https://metabox.io) - -## Description - -**Meta Box is a powerful, professional, and lightweight toolkit for developers to create unlimited custom meta boxes and WordPress custom fields.** - -Meta Box helps you add [custom fields](https://metabox.io) and details on your website such as pages, posts, forms and anywhere you want using over 40 different field types such as text, images, file upload, checkboxes, and more. - -On top of that, each WordPress custom field type has extensive internal options for unlimited content possibilities. Complete customization and control is just a few clicks away. - -Adding WordPress custom fields and custom meta boxes is quick and painless: Select the field types you want in the user-friendly [Online Generator](https://metabox.io/online-generator/), then copy and paste the code into your child theme's `functions.php` file. - -**Boom! All the power with none of the bloat.** - -There are also free and premium extensions available to add enhanced capabilities. You can manage the display and organization of your WordPress custom fields, the conditions upon which they appear, and become the ultimate WordPress data wizard. - -You can also check out the [full list of extensions](https://metabox.io/plugins/) and [MetaBox.io](https://metabox.io) for details. - -### Features - -#### Create any type of metadata or custom fields in WordPress - -That's right – any type. No matter where you need to insert custom data and features, Meta Box's WordPress custom fields have your back, and with infinite options to boot. - -**Here are just a few of the data types you can customize:** - -- Posts -- Pages -- Custom post types -- [Taxonomies](https://metabox.io/plugins/mb-term-meta/) -- [Settings pages](https://metabox.io/plugins/mb-settings-page/) -- [Theme option pages](https://metabox.io/plugins/mb-settings-page/) -- [User profile pages](https://metabox.io/plugins/mb-user-profile/) -- [Post comments](https://metabox.io/plugins/mb-comment-meta/) -- [And even more data types](https://docs.metabox.io/field-settings/) than Batman has tools on his utility belt. - -#### A wide-range of field types and options - -Take your standard WordPress custom field and imagine it infinitely expanded. That's how many options Meta Box gives you: - -- Meta Box supports [40+ built-in WordPress custom field types](https://docs.metabox.io/field-settings/) for all your needs including text, textarea, WYSIWYG editor, image, file, post, select, checkbox, radio buttons, date/time picker, taxonomy, user, oembed and more to come. -- Not enough? You can also [effortlessly create your own field type](https://docs.metabox.io/custom-field-type/). -- Meta Box supports cloning fields for most field types including the WYSIWYG editor field. It also supports [repeatable field groups](https://metabox.io/plugins/meta-box-group/). -- Utilize WordPress' powerful [action](https://docs.metabox.io/actions/) and [filter](https://docs.metabox.io/filters/) system so you can build or change a site's appearance and behavior in the plugin. - -#### It's developer-friendly - -As a developer, you have enough on your plate. You shouldn't have to create an entirely new system for each project. Use Meta Box to your full advantage. - -You can use Meta Box and its custom fields in WordPress on as many websites as you want so you can use it on client projects as well. - -- Has an ultra-lightweight, yet powerful API that won't overload your site. -- Add only what you need instead of getting stuck with a bundle of features you don't even want that bloat your site. -- Meta Box [easily integrates with any theme and plugin](https://docs.metabox.io/integration/), and also [works with the Composer package dependency manager](https://docs.metabox.io/composer/). -- We use the [native WordPress meta data storage](https://docs.metabox.io/database/) and functions for ease of use and lightning-fast processing. -- It's compatible with WPML multilingual plugin, and is officially supported by the WPML team. - -#### Don't love coding? You're in luck! - -Meta Box is built mostly for developers since you need to copy and paste some code, but if you prefer a more visual system to create custom fields in WordPress, you can choose one or all of the extensions below: - -- [MB Custom Post Type](https://wordpress.org/plugins/mb-custom-post-type/) -- [Meta Box – Beaver Themer Integrator](https://metabox.io/plugins/meta-box-beaver-themer-integrator/) -- [Meta Box Builder](https://metabox.io/plugins/meta-box-builder/) - -The [Meta Box Builder extension](https://metabox.io/plugins/meta-box-builder/) has a ton of features to make quick work of any project: - -- All the power of Meta Box without touching a single line of code. -- It's designer-friendly, lightweight and works at top-notch speeds. -- Create an unlimited amount of WordPress custom fields at lightning speeds and with a user-friendly drag-and-drop interface. -- Over 40 custom field types available that you can drag and drop to where you need ‘em. -- Export your custom fields and settings to PHP. Then, add it to a new site without needing to install this extension for an incredibly lightweight option. -- It has the goods with conditional logic, priority and context options ready and waiting. - -### Extensions - -Speaking of extensions, there are a ton of free and premium ones available to further extend the already powerful core Meta Box plugin so you can supercharge your custom fields in WordPress. - -You'll have ultimate control to add whatever meta box and custom fields in WordPress you could ever want. Then, you can tailor it all to fit your exact specifications. - -#### Free Extensions - -- [MB Custom Post Type](https://wordpress.org/plugins/mb-custom-post-type/): Create and manage custom post types and taxonomies quickly with an easy-to-use interface. -- [MB Relationships](https://wordpress.org/plugins/mb-relationships/): Create as many connections as you want from post-to-post or page-to-page. -- [Meta Box Yoast SEO](https://wordpress.org/plugins/meta-box-yoast-seo/): Add WordPress custom fields to Yoast SEO Content Analysis to generate more accurate SEO scores. -- [MB Rest API](https://metabox.io/plugins/mb-rest-api/): Pull all meta values from posts and terms into the WP REST API responses. -- [MB Comment Meta](https://wordpress.org/plugins/mb-comment-meta/): Add WordPress custom fields to comments in WordPress. It supports all field types and options. -- [MB Custom Taxonomy](https://metabox.io/plugins/custom-taxonomy/): Create and manage custom taxonomies in WordPress with a user-friendly interface. -- [Meta Box Text Limiter](https://wordpress.org/plugins/meta-box-text-limiter/): Limit the number of characters or words entered for text and textarea fields. -- [Meta Box – FacetWP Integrator](https://metabox.io/plugins/meta-box-facetwp-integrator/): Integrates Meta Box, and FacetWP to make WordPress custom fields searchable and filterable in the frontend. -- [Meta Box – Beaver Themer Integrator](https://metabox.io/plugins/meta-box-beaver-themer-integrator/): Integrates Meta Box, and Beaver Themer to show WordPress custom fields easier in the frontend. - -#### Premium Extensions - -- [MB Blocks](https://metabox.io/plugins/mb-blocks/): Create custom Gutenberg blocks with PHP, using the same syntax in Meta Box. -- [Meta Box Builder](https://metabox.io/plugins/meta-box-builder/): Create custom meta boxes and custom fields in WordPress using a user-friendly drag-and-drop interface. -- [Meta Box Group](https://metabox.io/plugins/meta-box-group/): Create repeatable groups of WordPress custom fields for better appearance and structure. -- [MB Settings Page](https://metabox.io/plugins/mb-settings-page/): Create settings pages for themes, plugins or websites with beautiful syntax. -- [MB Term Meta](https://metabox.io/plugins/mb-term-meta/): Add meta data to categories, tags or any custom taxonomy with simple syntax. -- [Meta Box Conditional Logic](https://metabox.io/plugins/meta-box-conditional-logic/): Add visibility dependency for custom meta boxes and custom fields in WordPress. -- [Meta Box Include Exclude](https://metabox.io/plugins/meta-box-include-exclude/): Show or hide meta boxes by ID, page template, taxonomy, or custom function. -- [MB Frontend Submission](https://metabox.io/plugins/mb-frontend-submission/): Create frontend forms for users to submit custom content and embed them anywhere with a shortcode. -- [Meta Box Columns](https://metabox.io/plugins/meta-box-columns/): Display eye-catching custom fields in WordPress by putting them into 12-column grids. -- [Meta Box Tabs](https://metabox.io/plugins/meta-box-tabs/): Painlessly create tabs for meta boxes. There are 3 supported WordPress-native tab styles and icons. -- [MB Admin Columns](https://metabox.io/plugins/mb-admin-columns/): Display WordPress custom fields in table columns on admin screens for all post types. -- [MB Custom Table](https://metabox.io/plugins/mb-custom-table/): Save custom field data to custom tables instead of the default meta tables to reduce your database's size and increase its performance. -- [MB Revision](https://metabox.io/plugins/mb-revision/): Track changes to custom fields in WordPress with revisions. You can save, compare and restore the changes smoothly. -- [MB User Meta](https://metabox.io/plugins/mb-user-meta/): Quickly add WordPress custom fields to user profiles in the wp_usermeta table with simple syntax. -- [Meta Box Geolocation](https://metabox.io/plugins/meta-box-geolocation/): Automatically and instantly populate location data with the power of the Google Maps Geolocation API. -- [Meta Box Template](https://metabox.io/plugins/meta-box-template/): Make defining custom meta boxes and WordPress custom fields way easier with templates. -- [Meta Box Tooltip](https://metabox.io/plugins/meta-box-tooltip/): Display help information for custom fields in WordPress using beautiful tooltips. -- [Meta Box Show Hide](https://metabox.io/plugins/meta-box-show-hide-javascript/): Toggle meta boxes by page template, post format, taxonomy and category via JavaScript. - -See all the available [extensions on the Meta Box website](https://metabox.io/plugins/). - -### Detailed Documentation - -We won't leave you high and dry. - -We provide regularly updated, and extensive documentation as well as tutorials on how to use MetaBox and custom fields in WordPress to your advantage as well as in the most efficient way possible. - -Here are a few guides to quickly get you started with Meta Box and creating your own WordPress custom fields: - -- [Quick Start Guide](https://docs.metabox.io/quick-start/) -- [Creating Meta Boxes](https://docs.metabox.io/creating-meta-boxes/) -- [Field Settings](https://docs.metabox.io/field-settings/) -- [Displaying Fields](https://docs.metabox.io/displaying-fields/) - -Check out more on the [Meta Box Documentation](https://docs.metabox.io/) page. - -## Installation - -From within WordPress - -1. Visit **Plugins > Add New** -1. Search for **Meta Box** -1. Click the **Install Now** button to install the plugin -1. Click the **Activate** button to activate the plugin - -Manually - -1. Unzip the download package -1. Upload `meta-box` to the `/wp-content/plugins/` directory -1. Activate the plugin through the 'Plugins' menu in WordPress - -To getting started with the plugin, please read the [Quick Start Guide](https://docs.metabox.io/quick-start/). - -## Contributors - -- [Tran Ngoc Tuan Anh a.k.a Rilwis](https://deluxeblogtips.com) - Initial & lead developer -- [Franz Josef Kaiser](http://profiles.wordpress.org/f-j-kaiser) -- Omnicia -- ruanmer -- PerWiklander -- funkedgeek -- [truongwp](https://github.com/truongwp) - -[See full list of angels!](https://github.com/wpmetabox/meta-box/contributors) - -## Changelog - -[See full changelog here](https://github.com/wpmetabox/meta-box/blob/master/CHANGELOG.md). diff --git a/vendor/wpmetabox/meta-box/composer.json b/vendor/wpmetabox/meta-box/composer.json deleted file mode 100644 index aeac9c5b7..000000000 --- a/vendor/wpmetabox/meta-box/composer.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "wpmetabox/meta-box", - "type": "wordpress-plugin", - "keywords": [ - "wordpress", - "ui", - "select2", - "wp-admin", - "meta-box", - "wordpress-plugin", - "custom-field" - ], - "description": "A powerful, professional developer toolkit to create custom meta boxes and custom fields for WordPress websites.", - "homepage": "https://metabox.io", - "license": "GPL-2.0", - "minimum-stability": "stable", - "authors": [ - { - "name": "Tran Ngoc Tuan Anh", - "email": "anhtnt@elightup.com", - "homepage": "https://metabox.io", - "role": "Developer" - } - ] -} diff --git a/vendor/wpmetabox/meta-box/css/button-group.css b/vendor/wpmetabox/meta-box/css/button-group.css index 15e3b4be9..4a3f0a5b4 100644 --- a/vendor/wpmetabox/meta-box/css/button-group.css +++ b/vendor/wpmetabox/meta-box/css/button-group.css @@ -1,72 +1,82 @@ .rwmb-button-input-list { - margin: 0; - display: inline-block; -} -.rwmb-button-input-list li { - margin-bottom: 0; - list-style: none; + --color: var(--wp-admin-theme-color, #2271b1); } + .rwmb-button-input-list .rwmb-button_group { display: none; } -.rwmb-button-input-list li label { +.rwmb-button-input-list label { display: block; - border: #ccc solid 1px; + border: 1px solid #8c8f94; position: relative; z-index: 1; padding: 5px 10px; background: #fff; } -.rwmb-button-input-list li label.selected { - border-color: #0073aa; - background: #0073aa; +.rwmb-button-input-list .selected { + border-color: var(--color); + background: var(--color); color: #fff; z-index: 2; } -/* Layout not inline --------------------------------------------------*/ -.rwmb-button-input-list:not(.rwmb-inline) li label { + +/* Layout not inline */ +.rwmb-button-input-list:not(.rwmb-inline) label:not(:first-child) { border-top-width: 0; } -.rwmb-button-input-list:not(.rwmb-inline) li:first-child label { - border-top-width: 1px; -} -.rwmb-button-input-list:not(.rwmb-inline) li label.selected { - border-bottom: 1px solid #fff; -} -.rwmb-button-input-list:not(.rwmb-inline) li:last-child label.selected { - border-bottom-color: #0073aa; +.rwmb-button-input-list:not(.rwmb-inline) .selected:not(:last-child) { + border-bottom-color: rgba(255, 255, 255, .25); } -.rwmb-button-input-list:not(.rwmb-inline) > li:first-child:not(:last-child) label { +.rwmb-button-input-list:not(.rwmb-inline) > label:first-child:not(:last-child) { border-top-left-radius: 3px; border-top-right-radius: 3px; } -.rwmb-button-input-list:not(.rwmb-inline) > li:last-child:not(:first-child) label { +.rwmb-button-input-list:not(.rwmb-inline) > label:last-child:not(:first-child) { border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; } -/* Layout inline ----------------------------------------------*/ -.rwmb-button-input-list.rwmb-inline li { - display: inline-block; + +/* Layout inline */ +.rwmb-button-input-list.rwmb-inline { + display: flex; } -.rwmb-button-input-list.rwmb-inline li label { +.rwmb-button-input-list.rwmb-inline label:not(:first-child) { border-left-width: 0; } -.rwmb-button-input-list.rwmb-inline li:first-child label { - border-left-width: 1px; +.rwmb-button-input-list.rwmb-inline .selected:not(:last-child) { + border-right-color: rgba(255, 255, 255, .25); } -.rwmb-button-input-list.rwmb-inline li label.selected { - border-right-color: rgb(255, 255, 255); -} -.rwmb-button-input-list.rwmb-inline li:last-child label.selected { - border-right-color: #0073aa; -} -.rwmb-button-input-list.rwmb-inline > li:first-child:not(:last-child) label { +.rwmb-button-input-list.rwmb-inline > label:first-child:not(:last-child) { border-top-left-radius: 3px; border-bottom-left-radius: 3px; } -.rwmb-button-input-list.rwmb-inline > li:last-child:not(:first-child) label { +.rwmb-button-input-list.rwmb-inline > label:last-child:not(:first-child) { border-top-right-radius: 3px; border-bottom-right-radius: 3px; } + +/* Admin color schemes */ +.admin-color-blue .rwmb-button-input-list { + --color: var(--wp-admin-theme-color, #e1a948); +} +.admin-color-coffee .rwmb-button-input-list { + --color: var(--wp-admin-theme-color, #c7a589); +} +.admin-color-ectoplasm .rwmb-button-input-list { + --color: var(--wp-admin-theme-color, #a3b745); +} +.admin-color-light .rwmb-button-input-list { + --color: var(--wp-admin-theme-color, #04a4cc); +} +.admin-color-midnight .rwmb-button-input-list { + --color: var(--wp-admin-theme-color, #e14d43); +} +.admin-color-modern .rwmb-button-input-list { + --color: var(--wp-admin-theme-color, #3858e9); +} +.admin-color-ocean .rwmb-button-input-list { + --color: var(--wp-admin-theme-color, #9ebaa0); +} +.admin-color-sunrise .rwmb-button-input-list { + --color: var(--wp-admin-theme-color, #dd823b); +} \ No newline at end of file diff --git a/vendor/wpmetabox/meta-box/css/date.css b/vendor/wpmetabox/meta-box/css/date.css index adeac46ad..24d283f27 100644 --- a/vendor/wpmetabox/meta-box/css/date.css +++ b/vendor/wpmetabox/meta-box/css/date.css @@ -1,3 +1,10 @@ +body { + --mb-color-datepicker-primary: #23282d; + --mb-color-datepicker-border: #23282d; + --mb-color-datepicker-active: var(--wp-admin-theme-color, #2271b1); + --mb-color-datepicker-heading: #fff; +} + /* Fix empty block below admin footer (issue #24) */ #ui-datepicker-div { display: none; @@ -17,15 +24,10 @@ .ui-datepicker { padding: 0; border: 1px solid #ddd; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; + border-radius: 4px; } .ui-datepicker * { padding: 0; - font-family: "Open Sans", sans-serif; - -webkit-border-radius: 0; - -moz-border-radius: 0; border-radius: 0; } .ui-datepicker table { @@ -33,28 +35,19 @@ margin: 0; } .ui-datepicker .ui-datepicker-header, -.ui-timepicker-div .ui-widget-header{ +.ui-timepicker-div .ui-widget-header { border: none; - background: #23282d; - color: #fff; font-weight: normal; } .ui-datepicker .ui-datepicker-header .ui-state-hover { - background: #23282d; border-color: transparent; cursor: pointer; - -webkit-border-radius: 0; - -moz-border-radius: 0; border-radius: 0; } -.ui-datepicker thead { - background: #23282d; - color: #fff; -} + .ui-datepicker .ui-datepicker-title { margin-top: .4em; margin-bottom: .3em; - color: #fff; font-size: 14px; } .ui-datepicker .ui-datepicker-prev-hover, @@ -87,7 +80,6 @@ color: #fff; font-weight: normal; border: none; - border-top: 1px solid #32373c; } .ui-datepicker td { background: #f1f1f1; @@ -105,7 +97,6 @@ } .ui-datepicker td .ui-state-active, .ui-datepicker td .ui-state-hover { - background: #0073aa; color: #fff; } .ui-datepicker td.ui-state-disabled, @@ -113,7 +104,27 @@ opacity: 1; color: #999; } -/* timepicker button */ + + +/* Month and year select dropdowns */ +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { + background: none; + color: inherit; + border: none; +} +.ui-datepicker select.ui-datepicker-month option, +.ui-datepicker select.ui-datepicker-year option { + color: #3c434a; + background: #fff; +} + +/* Button pane */ +.ui-datepicker .ui-datepicker-buttonpane button { + border-radius: 2px; +} + +/* Timepicker */ .ui-timepicker-div .ui-slider-access { display: inline-block; } @@ -122,111 +133,78 @@ margin: 0 2px; border-radius: 4px; } -.ui-timepicker-div .ui-slider-access button span.ui-button-icon{ +.ui-timepicker-div .ui-slider-access button span.ui-button-icon { display: inline; } -/* Other Datepicker Color Schemes */ -/* Blue */ -.admin-color-blue .ui-datepicker .ui-datepicker-header, -.admin-color-blue .ui-timepicker-div .ui-widget-header, -.admin-color-blue .ui-datepicker .ui-datepicker-header .ui-state-hover, -.admin-color-blue .ui-datepicker thead { - background: #4796b3; -} -.admin-color-blue .ui-datepicker th { - border-color: #52accc; -} -.admin-color-blue .ui-datepicker td .ui-state-active, -.admin-color-blue .ui-datepicker td .ui-state-hover { - background: #096484; -} -/* Coffee */ -.admin-color-coffee .ui-datepicker .ui-datepicker-header, -.admin-color-cofee .ui-timepicker-div .ui-widget-header, -.admin-color-coffee .ui-datepicker .ui-datepicker-header .ui-state-hover, -.admin-color-coffee .ui-datepicker thead { - background: #46403c; -} -.admin-color-coffee .ui-datepicker th { - border-color: #59524c; -} -.admin-color-coffee .ui-datepicker td .ui-state-active, -.admin-color-coffee .ui-datepicker td .ui-state-hover { - background: #c7a589; -} -/* Ectoplasm */ -.admin-color-ectoplasm .ui-datepicker .ui-datepicker-header, -.admin-color-ectoplasm .ui-timepicker-div .ui-widget-header, -.admin-color-ectoplasm .ui-datepicker .ui-datepicker-header .ui-state-hover, -.admin-color-ectoplasm .ui-datepicker thead { - background: #413256; -} -.admin-color-ectoplasm .ui-datepicker th { - border-color: #523f6d; -} -.admin-color-ectoplasm .ui-datepicker td .ui-state-active, -.admin-color-ectoplasm .ui-datepicker td .ui-state-hover { - background: #a3b745; -} -/* Midnight */ -.admin-color-midnight .ui-datepicker .ui-datepicker-header, -.admin-color-midnight .ui-timepicker-div .ui-widget-header, -.admin-color-midnight .ui-datepicker .ui-datepicker-header .ui-state-hover, -.admin-color-midnight .ui-datepicker thead { - background: #26292c; -} -.admin-color-midnight .ui-datepicker th { - border-color: #363b3f; -} -.admin-color-midnight .ui-datepicker td .ui-state-active, -.admin-color-midnight .ui-datepicker td .ui-state-hover { - background: #e14d43; -} -/* Ocean */ -.admin-color-ocean .ui-datepicker .ui-datepicker-header, -.admin-color-ocean .ui-timepicker-div .ui-widget-header, -.admin-color-ocean .ui-datepicker .ui-datepicker-header .ui-state-hover, -.admin-color-ocean .ui-datepicker thead { - background: #627c83; -} -.admin-color-ocean .ui-datepicker th { - border-color: #738e96; -} -.admin-color-ocean .ui-datepicker td .ui-state-active, -.admin-color-ocean .ui-datepicker td .ui-state-hover { - background: #9ebaa0; -} -/* Sunrise */ -.admin-color-sunrise .ui-datepicker .ui-datepicker-header, -.admin-color-sunrise .ui-timepicker-div .ui-widget-header, -.admin-color-sunrise .ui-datepicker .ui-datepicker-header .ui-state-hover, -.admin-color-sunrise .ui-datepicker thead { - background: #be3631; -} -.admin-color-sunrise .ui-datepicker th { - border-color: #cf4944; -} -.admin-color-sunrise .ui-datepicker td .ui-state-active, -.admin-color-sunrise .ui-datepicker td .ui-state-hover { - background: #dd823b; +.ui-timepicker-oneLine .ui-widget-header { + margin-right: -2px; } -/* Light */ -.admin-color-light .ui-datepicker .ui-datepicker-header, -.admin-color-light .ui-timepicker-div .ui-widget-header, -.admin-color-light .ui-datepicker .ui-datepicker-header .ui-state-hover, -.admin-color-light .ui-datepicker thead { - background: #e5e5e5; + +/* Color schemes */ +.ui-datepicker .ui-datepicker-header, +.ui-timepicker-div .ui-widget-header, +.ui-datepicker .ui-datepicker-header .ui-state-hover, +.ui-datepicker thead { + background: var(--mb-color-datepicker-primary); + color: var(--mb-color-datepicker-heading); } -.admin-color-light .ui-datepicker td { - background: #fff; +.ui-datepicker th { + border-top: 1px solid var(--mb-color-datepicker-border); } +.ui-datepicker td .ui-state-active, +.ui-datepicker td .ui-state-hover { + background: var(--mb-color-datepicker-active); +} +.ui-datepicker .ui-datepicker-title { + color: var(--mb-color-datepicker-heading); +} + +.admin-color-blue { + --mb-color-datepicker-primary: #4796b3; + --mb-color-datepicker-border: #52accc; + --mb-color-datepicker-active: #096484; +} +.admin-color-coffee { + --mb-color-datepicker-primary: #46403c; + --mb-color-datepicker-border: #59524c; + --mb-color-datepicker-active: #c7a589; +} +.admin-color-ectoplasm { + --mb-color-datepicker-primary: #413256; + --mb-color-datepicker-border: #523f6d; + --mb-color-datepicker-active: #a3b745; +} +.admin-color-midnight { + --mb-color-datepicker-primary: #26292c; + --mb-color-datepicker-border: #363b3f; + --mb-color-datepicker-active: #e14d43; +} +.admin-color-modern { + --mb-color-datepicker-primary: #1e1e1e; + --mb-color-datepicker-border: #363b3f; + --mb-color-datepicker-active: #3858e9; +} +.admin-color-ocean { + --mb-color-datepicker-primary: #627c83; + --mb-color-datepicker-border: #738e96; + --mb-color-datepicker-active: #9ebaa0; +} +.admin-color-sunrise { + --mb-color-datepicker-primary: #be3631; + --mb-color-datepicker-border: #cf4944; + --mb-color-datepicker-active: #dd823b; +} +.admin-color-light { + --mb-color-datepicker-primary: #e5e5e5; + --mb-color-datepicker-border: #f0f0f0; + --mb-color-datepicker-active: #888; + --mb-color-datepicker-heading: inherit; +} +/* Light */ .admin-color-light .ui-datepicker .ui-datepicker-next span, .admin-color-light .ui-datepicker .ui-datepicker-prev span { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAADwCAYAAADvl7rLAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxMUIxRjI2RjhCODYxMUUzQTEyNERCMDU1QzdBQ0EyMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxMUIxRjI3MDhCODYxMUUzQTEyNERCMDU1QzdBQ0EyMCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjExQjFGMjZEOEI4NjExRTNBMTI0REIwNTVDN0FDQTIwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjExQjFGMjZFOEI4NjExRTNBMTI0REIwNTVDN0FDQTIwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+kKfR4AAAHcRJREFUeNrsXWuMXsdZnuMu4CUN2S0t0a6o4sQqAaooTncrKGrUNbe2qSC2uQqpqtexbCqI0xaQEBclKUL8qts6stqNkuwWiYqbajtqS9oAuyEISrubrLmUFnBSfmRXFa12KT+cKk2GM9mZ7ng858w7l3PmnO88jzQ633e+8565vs+8M9+8MwXnnAEAMEzsQREAAAgAAIABYkx9OHXqFEoDMDFVho0yTJdhE8UxOjhz5gwsAICk/Exep1AkGAK0DY6G93L+eUblnw4gATPNqMceEsBURMVxSwhFbO8TEj838j4V8B6eQHF1RWyzDnTl3zRIIDTNsCJ6RABdMf+mM6XBjNfsDXP1wm2hkEGN+ze1eyFpngYJ9IcAYs0/vQEVkenz7X1SwRZv2xNhqeJNVRcxac5Vj0AAAcSYf13pBVMMPfS8xyhhaFpy9pqhQ6CqNOe0ZgBPAgg1/7rcC8aQQJEx7lzkGzoEqkpz7noEPOcAmhhPxjTGzcA42zR/m0jDZkSPGZPvmCFQVZqh/B3EWMfTV6CKvm2F5LJAQhYCmWlGPYIAAJAPMMQhAAAAIAAAAEAAAACAAAAAAAEAAAACAAAABAAAAAhAA/zI8+wHoMcL772BEkBsA0i1J0CsM0yIAvGa0CZ55doPIIU7uF7uIJKeEUCKBpDS6yumEW4kTPt0S+mOVf7YtG84voekHXsB9IQAUlXeZgMk0JYC2dIe6swS2vBTK79P2mMdmTZayBPQEAGkrLyUJDDdkvLb0h7ryRZCAtOZlD/F8G264TwBDRJAURNYJhLwbcSpepqU+wFs9KDcqhR1OkHa4Q7cQbTlDRjjVRa6H0BuFInKbTqQ0IpE8YYqrl7n8CgcOAHkVKK+I+d+ACj/AQ4BAAAAAQAAAAIAAAAEAAAACAAAABAAAAAgAAAAeg1sCw64IJYBFwPNt4li1Mp/DJUPBSAoQUwZ8AwKlCLOQdT5HmLlh1ZCikM6eUsyOXqUJvMRW/660hcRaUlBHDyjEqdsuzxTW+O+BJCi8lOdyRcSf5GoAaWqhJAelCcsvyKB8sQocmzeU7SBWAuorbabmjxqy3+spcrnERkPbUhFR8z3UAVIMQ7NVQbcEneRIO/UvBSW/PuWAw+U54naQJFgCFZVlgV1DiDH2LlI/K5UzNlmL55ScYtEaQ9VoFTpbbsNhHaCqdKdoh045fe0pPxFBiKJnXtIwcAx6SgSpD+VCR3bA8XmPdUkZB+sv9TzGLV135QFUHTgXTl7z5Tx5yzH0PynznvRkTJscx4lZvhHjnesw4XXFRTIP/I/qvFiJSAADBggAAAAAQAAAAIAAAAEAAAACAAAABAAAABDIwB1suvQT3WNXU3YZ6RqA6m8QtuML/Zk6N60P8rhoBs9bABdJZO2G05omadsA0Vg/DZvuKkW4lZyKY7GM9Ocwx14inm6A28Q7zVdCSGVzztKAr7pmkqYh5DyT9kGeIDy1x1QO9Vg3E1YQDmPRXceklt3OGjV91w9H6Ugiw5aAr6706Q42Ti2/FO1gZCdeTYqLBkfIoptBzEWUGia60z/UEvOVZaNTwKGNIC6sVdo5fNMSp9SAXwbQS4yrMt7G+vbiwTtILUV7Itp4r1G5gCaVP62HCtiG38KBs6xFx5FCbpo9VQ1dNv4e7qFdhBjAcWmWcA8Xj3FMe/WuYw9HWwAdZMvoZWfk4FTKUCKrb24R/2lMEFD0rtZU9Z9PCo+9nj1IlDeVZaNEkATPb5vQcb0eKkYOCQdmyy9uedbH6kIkEeUv82nfbPFNKQq981Ew+DQ4V/tMe9jDTJnFzazYJEkkGszkk2WvucqPOOf1sa9PgTYtf0D+riZSGvx4mAQoE0SAjoGLAUGABAAAAAgAAAAQAAAAIAAAAAAAQBAVnAUQfsEkMobLdSjKlWl6/GjIYUpX+6yCz0hCfUeSACpvNFCPapSnYmnxy/eN83SHFLat14s9njwgsUf8JpCgXlLaR88AVR5o/n6NKf2KQ+NX5GJz8KWlCfqhnok8kRxhypwEdgTV3kDxigwi6w7kECCOQDfjQ1iPKpsCt/WxgrcQn4pThj2aYS2k3lTmNJNPEvNrw+BxJ7KDEQQQJ0LYRs+0dNaXLEbK8QoSpHAjCwSKVauHoxnym/Kd6QYjgyKAKq80dpi4VhvuBSurLlNxqLCAuEtNvqu9cQ8sO5SHfM+qCGAbbzssyXSlFFpIRsihO4HkMqVNbbx8wQkEDoOjm30tmGQ7xCCB86rxMjWkQCD8l8NH2/AjcAKjPGlZwHviXFlTWmG6uWQwowtAuOPSXusK23oxjAxsk0ORwZNAG1MIqV6X1dcWYvM70mhwLn86aGwGYcAAAAlBAEAAAACAAAABAAAAAgAAAAQAAAAIIDRxwTD8lFgoASQ0g871LGGJ5T1fYdQ/i02On+HxZ50CwyIAGIP1kzpCDOZqXy2LEQyEamAOWR1bIAEAAoBxKyfjlnPbfbUqhee9FAUcxmpz9l6usk/aXnHlmf85r0YQk1lPW2g6QNVBMAjeyCbPzj3JBSlbLryb0dYH769vpLflnGHnCxr5t0n/3V7ErjSkmo7N2AAGCOY/TygF09hRTCL8ucYi2+zdA41VOWvKjdX+ZvbsBUV9TuNpg/YCMBstFWffUzQWK+0WMSOu32tj7q8u8qhqpenluFGTb4LTfk30fQBGwHUKV0R0fCLSDLIRSCFQQKcMBfBa4ZCrrzUlU8XdtcBBjAH4OqNQhXWd0+8mP34YuQnLbJbWh62CUpW1NwriKQTgqrt3KD4gDcBxI7fQ7elKioCi5APGfPrsqn+hiwSP2cidjs1AEOA6IZYJG7UOREzB5ALmww9PpCIAIYOKBIw2CEAAAAgAAAAQAAAAIAAAAAAAQDNYoZdvZZhpkfpF5PLe42ACeeOE8Aho8Ety3tt4/0szoc/FiKuBVa9l8BMC8q/arm/6hH3TEbyEIr+rTLcXIbLMtws740Fpj8kHzcZsjd55iNEPjZOgV9whJg8XKVLeoWcK8P7yvC0/D4h79lg+3vskOX5w2U475no32dXH8t1kvktB64jDNc75svwL2U4UfH7LWVY81ReHbMR8qsOef250KPNRKO5VPP7/jI84yCA15dhvQzj8p4ggQNl+LIkAuaZfp98VNX9JY82wCxlcIkgFyJj4s/l9aTsiFLWY1FHAExTfoEV5rcCjkog4r0HA5jRlwTGLfcuE+QWy/BgYO+3qhW0uSJPnXa8WpMHpeCrNeSxyppdn3Cpouz0MnTFr5T/Go3Y1h3vrStPlXcKmjiVqm+Hy1aROLextVlxOrY8C1kp/5dlQwldQrvX+L4Q8I7vCIzbZQG4cLiCqLj87ZxDfq2CBCg9P69ogL7nFIqy+4bl/vd4lMM18nkR33cHluUdEcO4GIIIdYcviGkpWlT+nyjD39SZa4yo9FQo5Xe9pyASwGRg2sYD0x9jAQh83kICSvk/T3yHSQIU5dcx4fhOKbvrI8pUmPtfK8Pb5fe/kveYR/6ZhYR8ymDWsKhmCcOzvsNU/l+UdVZJAqlnZqnK76O8oeaU3us826IFYJIA81R+G0n6TuLtd3ynWGD/bdy7waPnvygVfl0jBHHve8vwPLH3rduZqs0l2inM+dh3/EoZPu45b3FSG4J9Urt/xfC7ib8Btzwadp3yqjCuffbBd2nBpwdbjFR+gSmNBJTy+2zEKRReOPUckmGTtTuTL8rpB40wTig/kcfvl439G1LxD8h2xuVvoRuSznoq/r6Ka+xwNMc7/iSA+MWw+TvZ7qSiUv6VJi2AVJM04wni+VLgO2MtgCm2u+OO3utvEhv/TI08lQRe6/juakSXDHNenx+qsya+T3vO9k/BunxfyI5Eucz3y5nf4bMvxzNG/S3UKX8oAcxGmDkU5f8DqYBVv6UimSbmACjjzNkG5XVFrPvuakT63MWYTJPr7z+dJFzPuCbSeIK6/cuKK7UTWKy43+Y7QvCMhcStyv9yYXK+U9anTp1iwBXj7VsqfhfktDaQsuBar/9MT9OeqmPoG9SEoFX5z5w5k20I0HWsGdcho0Dae4tnKGUAXwAAGDBAAAAAAgAAAAQAAAAIAACATuAPZchCAOqU3NgjsUNg+i23vSeADcpHnbIYZ5bZ/bAp/+EfYtV7EXDm3qPhhEOeusCpypf8pp7IK/xRZPuZk6FtXFuG35Hh2sh3HdXCFRirUf4trcFST+gVm4gIBxB95dP9bMcD7kZ5pfhzi4U4a1qlndQUsKiRUygaUH61QMfljivK7AtGWlTaxP03svrFPue0PJtYIJShy3NygdEWOqmFJLoTzzqj+7jnllf4baNNCCVYIij9smzzy/LepNSDykU1hu6oOnxQku6C9h7KOROfNj7fHqH85oIkkf6vvFwoloVAuvLr3mirhMSLlwk/+Lrz50M3dPCRV0r3a2U4q13FfgWnPRvQjCQjteGJyzOv6mBPah4oPVVByP/nyvCjbMdF+7Yy/EMZfozRnWk423XiUTK3MvdKPpu8Qoi8+D/7BbbjonyTh7zZ+NUKvMWG26Ape9JCykWN9eYi8JOMvlJVtVmR9/NSr8XnpbqFQKbyq15vVv7WxgKLqn0EfLwM3ySJ6D/L8O9sx7tNrOJ71lP5Rd7Vzka+brm58Ndl+JEyPCaV6DFZHn8bOBzTFTJUXuCWAHmh/M8HyJk936Jn+9vybJuhFpmOGxI9o3CPluZDhpWybZsDWGDV69EVCSy00IC3ZdiSYZv5H8/1j2X4uTJ8VjaGT0r2PBeg/Oc0S6AP+Em2s/b9bdJ8FFfhTkrdYONmS2/lQ/ymvAqvCJAXPf9e5rfBy9EahXetxZ8zlN88X3KrwTmB3y3DB2p+/4B8xoV9Mqh0npblMS+HP9tVcwAnLeNZphHCWsXYtItQFsBXy/BP0pQU138LUP6Ynp+zMH/wSW3uxdcCEi6gP1+GP5VKL66/xGhuqcJj8UvamFu59CrzPUReKP6LEfL6HICv8psK/2QL1utWgHWr8Jtl+I2a30LIr5K8Xb4AIY1+SzOZ9xkm98EWFH+WoGwfb0n5Y0nAtIqo+C22sxmEmNi5Xl7Ffgq/V4YjNXJi/uY5456pdPs7LG9T/iXPcl4xlJhbFHjbUU9VJECZANT/cft7eX2zabo78q+P+VfqImvCGeh5trsT8Fci5wxC9hRci4xTWTuhyi9m+b9QMxZ+Y8PKr8qdSetHv/6MQ+45Y7z+r57x5pZf1Ig2RPkplhZlHsxGAtTZf9E+XirDu9nuZJ+YHPyI/O1xot6oMf9hXwKo2hBR78maxMmantJn+GGm1TftoT3/ag0JuP4CVD3cJa3xbHn0gLp83e8uiJ54M6IOc8nPJ1B+ZakuG0qs/w1IJW19GEclcTHp+ctl+Avt3oPyPS8Q33FaK4/aeFPvByDGiRcZAIwO5rShQR9wVPtcSYJN7QcA5QdGDSs9S6+X5QNfAAAYMEAAAAACAAAABAAAAAgAGCno7sVzRJk5drUb7s2J0uPzV2wX3MAHSQC3WhrArRnSxwfYCNQ+DI8Y9x9h/nsz3Meu9H1YJpDAj8vnjsjwOhnE8twfIsSpt533Vih/YQQdwnPxHVL+TTJwee82QvwzlrZLPVDFtReDaz8GinzsOw556g2v0yPbOgC15nulDB+W9xZlwzPdOykJ8WV9m3zMO3LgqCwzVV6qTCkLVPQ8i3cck8o/71kWKg0KYj+GZwnyIv5rLPe/VYZvMporrYj3UUk+qgz09NT51KdwBzdXkFK9WDmju5tT47Zhy/EOtZpR30BmVbtfEPJvi+Pb7thqHYDNAlDKLypJLOn9Wba7BnmdARQsamV5VCu3RQ9ZJpXeVH6qW+s+47uPG/TzUtkvy/BNSQBUPMp2l4NPsqv98ldaqIP9bNeblHlaA+buT75W6LbMp+7J6uPRyo20zBDJ0YQ4i3FaC/9DHQJ8WDM71RFH8y0pT5W50sZwgBODCwcqFJbiT3+MVXuzKYuAMoy4N7IcXtK+v8Toh2t+SPb8qpzuNZR/ifCO8Yrgg1XP+wp72ZW7P+3V4qce8inK/7Rm0jPmdzhpETF/UkjiEW3tNWzHGew1WrgCdSsBdeU/Rhx7VLFUm6Z8ivMJY3GRXX023LzH8OlYpPLbNnVhmvldhz+TCm/6DFySyu2CGPdfsMw5+KzPF77/L7A8uMby/Wvy86uJ73iP9lmQofIsvZFoBfAKsqJ0Pspa+LpG3nuk8j/Fdrboq50D4DKRE0ajU5XZxpZeLOIdvEFZah6qfOepcyh/XIZ3Wu4L99DbA5WfqoAi7fdU/PZ+tutp6Jt3KoHp4+gXtfsvyOEIdQ6gapztGsPfWPM8Z/UernrcVcO797UwB/AG+fmr2v3n9LZbNwdwQBvzPyp7fqX8B4jKYc7uVs34UuV93lE4QowsNQ/rFSb8eoDy61aE8At/0jG5pCv/QdkgC4/eVxDUAzLdeqAov8qjauhM63HUfAZ1DC3C/7GdM+5f4WF+zzK/reNMvFKGZ+X1WuNzDKjD6Ng5gBukbl+vBSaJgbuGABeloq+zK/9C8v0HYMhQ5r8qs6fZ7r8ALrzT6PFFr/k6trspxJuJY1/X7rV1eFqm/3Py+w8QlV8nsRU5Dl6RQ4ctLf/HPN71dc+0rzH75itiQ1HXCcfCVNePprd9PkwYgt3o+J3SCXKP+za8lmTKNnw8+FD/BoyBMuNNc/9Jqfx1vuVc6wXXEtWdb/nr/1psa+NefbvsPTUNWd2/qwxfZDubuW4GtCVlKt9kmcsoHJOAr2e7e2Ay7bPYTq5ug9JDjLbnpNoxK+QddbKUoewVQ4CmjwcvMsv3EdsV+b695fJ6tWa++/yjIHr3v5NEtaiRldog43/LcB1hMuzhyPRXbQ3nOpzleXb1rlLUcj2foA7Ot6k3YwwAqk3vXw+UXaohN+ZQ/lQktsaG2YF4Ab4AAAACAAAABAAAAAhAwyFGXwGocIccA5rLZ5cY/WQaAAAyE8A5I1Bwdxk+VYZ3WX57l/ztbhQ7AHSbAN5m9PyH5D1Xz3/GuGdbOXfGwxJYldbDakDenjUskLkE5TWHJuNVb2ZYRdH0gwDUARyTbHddtutQjiMe8VKfnTGuPthnfF9OoPzLRBI4ajT8owHxxb4jVl4p7IxFuV2Y9bwPdIgA9N5f92F2WQF3VTQiTnw2NZT1MZngXXMagbhIQCia6bO/6KmAse9Q8qK+xuV1MYAEZiy9+QzUZrQJQO/pJ9iVa5dPBiphKE4GxqunXy0/XQk08+cM68G1xn7R837ds/OSwOY936GU/zNsZ2XbZzQS8MUa1GQ4BDBnjP31HVWUFdDmOPg/jKsvVNqFI85hovLrPbyv8qfGeWmBnQ+QfcLxndVYbLGbrsxo5LGmkQish44TwDKhB19uMX0rMv5YpTvI3GvPbWZ+TuVXhDvB/P+KFXiL43udxRa7hHZBU3jdnXUBKtddApirMKEnCGaywFmPeKnPzrG4GXzVmCm7sKywK3fLCVX+ec/7dc8uSitm0fMd4rnHyvBWtuPd9lb5PWRbt5mEMrAAOkwAyxUmtG1zBduzF2pMSsqzrCaeUKvD15w1SSCk51+yKJrvcdWx71jSSOCypvxLnuUnTPdZwzKgzAmYlkQqywJokADWPBuGicfLcJwge1w+SzXdGaOfyZ5q2HEw0uxfMhr9UoZ3xMoXzL6vAP7KGyGMJa5Y4cP9X3LM+h7jN7ErjJjMesJTGWN6jSKCBNBbAYMigFR4Qob3ongBEGl/hgAAAIAAAAAAAQAAAAIAAAAEAAAACAAYIOZYuG9AjCyQkQBEpVF931nNO3jNd6B5LLC49fdzLHwVZows0AELQFVgLBH4koYZ30RAGlTaJyz3eEAaFE4Q5U/UpIl7lIXvseRmfCdkmOuI8nOGXZV6NwRomwjM+IQjz0FNeeYIJucy2/UADEl/yjznIFJmKKCPInOtDEOtvirZAlZBf+cAVEM+0eLYc1lrMIXWmHlNz20+G6N4ZhpClLBtxWc15ZMTGP71nABWZK/6YEtpU/EdNBrQQWZfXlpUPBvjx2+mwRex8Y8SsCS4pwSw0nJDNuOb0Ex61+YgKxoRqDmAkPSnzPNKBiIoKoKP7MGIeA/WWAEHoXYdYuWK48G5bKz3RzRa8zjn2KPCgXhz27fs5yzDqjZkgYbhOh48RYUVMAF7b26vaNZUm7JAB+cAgGFihWFfBRAAAAAgAAAAQAAAAIAAAAAAAQAAMJoEEHqyLQAAPSUAsXruHu37DTJMeLxX92C7z1MWAIBMBKBO0zXPortR3qcq8gG2swhEnAVwr5S9NUF6XQ4lJ5jdjVaFEyMuDwBeMFcCnpbXfzbur2i/HyO896ImJ5YTn2M7J/Qe0H5rAmLzi8JBIPpptaMmDwDBFoDo3eeloqohgDDf1Uk+6/J3ihWgeqxH5PPKEWY9cDjg40oqDsO8Vl71z+I6XoZVh/y1Mj79HSr4yvMI+b2WK0UeAIIsgP3yqh/ceb/2+YLswfcTeiDx3G1s51TbeTmEOCyHAuL7BxvM06sqCKQgEskrjWthvIMRFFi/vsqTxFS8k4b8JMOyWqBBC+CSvN5Z8eydxnOuIcCS1ogFEWzL6+mGen6F6yxhQl43mPsMRPHsD7Pdo9H1dzxHkL9OyutXJe8bv/4eavwAEGQBbEszfY7t/PW3pP12VPbqK/I5quIWsucXcwD7yvAoCzujnoqTZfii4/e1EZYHAC+Y+wHcKsfpasx/Qfb8BzTT/qInAajvaiOIZYIpq5vstisAABGo2g/golTy+9jOX4FK8c/Le9QZ/Lq9AAoP+aorAACJhwA6CRxG0QDA6AO+AAAAAgAAAAQAAAAIAACA4RLAHWxnDYDpiLIkf3Mht/xb2M5KQ1P+g/K3UZfve/0NXb5VmOsA7i7DGYeMePCBit9yy99Vhocc8sfL8PCIyve9/oYu3xrUOgCdAAQ7fYoo/44yfNrCfDnlf6oMnyXK/3QZHh8x+b7X39DlsxCAPgQ4YrMQmH3xzRHivSq45I+zqxcPHXfI31mRfkZ89k6P9PvIFy3Ff8Qjfmr9FQnkWab411j1sWi+8RcJ2n8RqCutDQF4TaI5oXJ9HXfq5AvNJGaaycs948+V/lTxp0h/1Tuajr8gposFps8n/iKg/Yjff1X7/tGA9mc+Kzxkn3KQY6sWAPVosMJTSaoyR5XnxliXMjZ2pYdHKHcIScRWcJE4/b7vSJl2lqD9hKSfW0jABx8xCMAHb5DKblP+zmCMdRcvVnxuAzyBhZBKgXIrcEgHkKL8U8Qb60D27kA5ofxPd1356wggtgJ4ogZ4VF6X2O5fKzENKpQEeCISaav8eKTyxhIgz0AaLgskxIL6aGD+n9JIoLPKL6BPAp71kDtLvBcqr8b+izLo96rkH/ZQpoeJ93gCeRYhzzzkz3oQCqX+eEL5ttuPWX88g/xTNcp/tosEcMFDAS4Q71XBJf+QpQE+5JD/hIcCfoJ4jyWQ5y3Ff8Ejfmr98QTyLEP83EFATcvrJMAidaU1AhD/Kx8nyBxnV/8H3QV58b/qKYL8KWb/D7bv8n2vv6HLZycAZVrOsZ39/E18SP72sMM0zSkvVliJRRYfs/z2MfnbAyMs3/f6G7p8+5MlxlJgAAAGANtKQAAABgYQAACAAAAAAAEAAAACAAAABAAAwIjD5QtgA2V9O+Tj5AEgKwEIjFvuXfZ4d255AAASDAFyKt3lBGnI2ePiSDOg1wQQq4CXtRCCcSk7nkkBq7aEokI/1BQAekcA4zXmOFWBxyPkL2skEKqAjMXtI8BZvg0pACD7EGA8Y/rGE6QhZ+/LO5AGAKjEWINj/9zyAAAEEkDKDS0hDwA9HgIAAAACAAAABAAAAAgAAAAQAAAAIAAAAEAAAAVTDAuDgB4QQBdWsYm4Z7TrKCj/Rhmm0fSArhPAtHFFzx1Hhrryb6I4ga4TwIZxHbryx/TcUH5gEBYA13rKumvTwwZXCFXejQTKjzkAoDMYc1gAhXaloCBem8RsQz1/iAVgU37MAQC9IIBQC2DaojTmtUkzeNWDqHyV34cM65QfwwAAFkCHLQAoPwALIMAC6ALWEryjSeWf8nwfAPTGAhgVhFouVOXHHAAACyBAEbsO08x3fQeAvD0d5/hHCgCGCvgCAMCA8f8CDABatG6NN+gY2wAAAABJRU5ErkJggg=='); } -.admin-color-light .ui-datepicker th { - border-color: #fff; -} .admin-color-light .ui-datepicker .ui-datepicker-title, .admin-color-light .ui-datepicker td .ui-state-default, .admin-color-light .ui-datepicker th { @@ -235,7 +213,6 @@ .admin-color-light .ui-datepicker td .ui-state-active, .admin-color-light .ui-datepicker td .ui-state-hover { color: #fff; - background: #888; } .admin-color-light .ui-datepicker td.ui-state-disabled, .admin-color-light .ui-datepicker td.ui-state-disabled .ui-state-default { diff --git a/vendor/wpmetabox/meta-box/css/file.css b/vendor/wpmetabox/meta-box/css/file.css index 14409fe4d..d68de1804 100644 --- a/vendor/wpmetabox/meta-box/css/file.css +++ b/vendor/wpmetabox/meta-box/css/file.css @@ -6,7 +6,6 @@ display: flex; align-items: flex-start; margin-bottom: 12px; - background: #fff; cursor: move; } .rwmb-file-icon { diff --git a/vendor/wpmetabox/meta-box/css/input-list.css b/vendor/wpmetabox/meta-box/css/input-list.css index 1a614e77f..73cf26d83 100644 --- a/vendor/wpmetabox/meta-box/css/input-list.css +++ b/vendor/wpmetabox/meta-box/css/input-list.css @@ -2,22 +2,25 @@ margin-top: 0; } .rwmb-input-list { - margin: 0; line-height: 1.8; } .rwmb-input-list .rwmb-input-list { margin-left: 20px; } -.rwmb-input-list li { - list-style: none; - margin-bottom: 0; +.rwmb-input-list > label { + display: block; } .rwmb-input-list.rwmb-inline { line-height: inherit; + display: flex; + flex-wrap: wrap; + gap: 6px 12px; } -.rwmb-input-list.rwmb-inline li { - display: inline-block; + +/* Media modal */ +.attachment-details .compat-attachment-fields .rwmb-input-list > label > input { + margin: 0 0.25rem 0 0; } -.rwmb-input-list.rwmb-inline li:not(:last-child) { - margin-right: 20px; +.compat-attachment-fields .rwmb-input-list.rwmb-inline { + gap: 10px; } diff --git a/vendor/wpmetabox/meta-box/css/jqueryui/core.css b/vendor/wpmetabox/meta-box/css/jqueryui/core.css index a4c1b2de8..9e76684c2 100644 --- a/vendor/wpmetabox/meta-box/css/jqueryui/core.css +++ b/vendor/wpmetabox/meta-box/css/jqueryui/core.css @@ -1,5 +1,5 @@ /*! - * jQuery UI CSS Framework 1.12.1 + * jQuery UI CSS Framework 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -50,7 +50,7 @@ left: 0; position: absolute; opacity: 0; - filter:Alpha(Opacity=0); /* support: IE8 */ + -ms-filter: "alpha(opacity=0)"; /* support: IE8 */ } .ui-front { @@ -94,4 +94,4 @@ left: 0; width: 100%; height: 100%; -} +} \ No newline at end of file diff --git a/vendor/wpmetabox/meta-box/css/jqueryui/datepicker.css b/vendor/wpmetabox/meta-box/css/jqueryui/datepicker.css index c82ae33fb..ada2e7007 100644 --- a/vendor/wpmetabox/meta-box/css/jqueryui/datepicker.css +++ b/vendor/wpmetabox/meta-box/css/jqueryui/datepicker.css @@ -1,5 +1,5 @@ /*! - * jQuery UI Datepicker 1.12.1 + * jQuery UI Datepicker 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -182,4 +182,4 @@ background-repeat: no-repeat; left: .5em; top: .3em; -} +} \ No newline at end of file diff --git a/vendor/wpmetabox/meta-box/css/jqueryui/slider.css b/vendor/wpmetabox/meta-box/css/jqueryui/slider.css index e1f5030ee..d8496baf6 100644 --- a/vendor/wpmetabox/meta-box/css/jqueryui/slider.css +++ b/vendor/wpmetabox/meta-box/css/jqueryui/slider.css @@ -1,5 +1,5 @@ /*! - * jQuery UI Slider 1.12.1 + * jQuery UI Slider 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -17,7 +17,7 @@ z-index: 2; width: 1.2em; height: 1.2em; - cursor: default; + cursor: pointer; -ms-touch-action: none; touch-action: none; } @@ -72,4 +72,4 @@ } .ui-slider-vertical .ui-slider-range-max { top: 0; -} +} \ No newline at end of file diff --git a/vendor/wpmetabox/meta-box/css/jqueryui/theme.css b/vendor/wpmetabox/meta-box/css/jqueryui/theme.css index 79937075d..6569bcbfc 100644 --- a/vendor/wpmetabox/meta-box/css/jqueryui/theme.css +++ b/vendor/wpmetabox/meta-box/css/jqueryui/theme.css @@ -1,5 +1,5 @@ /*! - * jQuery UI CSS Framework 1.12.1 + * jQuery UI CSS Framework 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -172,18 +172,18 @@ a.ui-button:active, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; - filter:Alpha(Opacity=70); /* support: IE8 */ + -ms-filter: "alpha(opacity=70)"; /* support: IE8 */ font-weight: normal; } .ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; - filter:Alpha(Opacity=35); /* support: IE8 */ + -ms-filter: "alpha(opacity=35)"; /* support: IE8 */ background-image: none; } .ui-state-disabled .ui-icon { - filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */ + -ms-filter: "alpha(opacity=35)"; /* support: IE8 - See #6059 */ } /* Icons @@ -194,37 +194,12 @@ a.ui-button:active, width: 16px; height: 16px; } -.ui-icon, -.ui-widget-content .ui-icon { - background-image: url("images/ui-icons_444444_256x240.png")/*{iconsContent}*/; -} -.ui-widget-header .ui-icon { - background-image: url("images/ui-icons_444444_256x240.png")/*{iconsHeader}*/; -} -.ui-state-hover .ui-icon, -.ui-state-focus .ui-icon, -.ui-button:hover .ui-icon, -.ui-button:focus .ui-icon { - background-image: url("images/ui-icons_555555_256x240.png")/*{iconsHover}*/; -} -.ui-state-active .ui-icon, -.ui-button:active .ui-icon { - background-image: url("images/ui-icons_ffffff_256x240.png")/*{iconsActive}*/; -} -.ui-state-highlight .ui-icon, -.ui-button .ui-state-highlight.ui-icon { - background-image: url("images/ui-icons_777620_256x240.png")/*{iconsHighlight}*/; -} -.ui-state-error .ui-icon, -.ui-state-error-text .ui-icon { - background-image: url("images/ui-icons_cc0000_256x240.png")/*{iconsError}*/; -} -.ui-button .ui-icon { - background-image: url("images/ui-icons_777777_256x240.png")/*{iconsDefault}*/; -} /* positioning */ -.ui-icon-blank { background-position: 16px 16px; } +/* Three classes needed to override `.ui-button:hover .ui-icon` */ +.ui-icon-blank.ui-icon-blank.ui-icon-blank { + background-image: none; +} .ui-icon-caret-1-n { background-position: 0 0; } .ui-icon-caret-1-ne { background-position: -16px 0; } .ui-icon-caret-1-e { background-position: -32px 0; } @@ -435,9 +410,9 @@ a.ui-button:active, .ui-widget-overlay { background: #aaaaaa/*{bgColorOverlay}*/ /*{bgImgUrlOverlay}*/ /*{bgOverlayXPos}*/ /*{bgOverlayYPos}*/ /*{bgOverlayRepeat}*/; opacity: .3/*{opacityOverlay}*/; - filter: Alpha(Opacity=30)/*{opacityFilterOverlay}*/; /* support: IE8 */ + -ms-filter: "alpha(opacity=30)"/*{opacityFilterOverlay}*/; /* support: IE8 */ } .ui-widget-shadow { -webkit-box-shadow: 0/*{offsetLeftShadow}*/ 0/*{offsetTopShadow}*/ 5px/*{thicknessShadow}*/ #666666/*{bgColorShadow}*/; box-shadow: 0/*{offsetLeftShadow}*/ 0/*{offsetTopShadow}*/ 5px/*{thicknessShadow}*/ #666666/*{bgColorShadow}*/; -} +} \ No newline at end of file diff --git a/vendor/wpmetabox/meta-box/css/media-modal.css b/vendor/wpmetabox/meta-box/css/media-modal.css deleted file mode 100644 index c3e7080cb..000000000 --- a/vendor/wpmetabox/meta-box/css/media-modal.css +++ /dev/null @@ -1,18 +0,0 @@ -/* CSS fixes ---------------------------------------------------------------*/ -#post-body-content table.compat-attachment-fields, -#post-body-content table.compat-attachment-fields > tbody, -#post-body-content table.compat-attachment-fields tbody > tr, -#post-body-content table.compat-attachment-fields tbody > tr > th, -#post-body-content table.compat-attachment-fields tbody > tr > td, -#post-body-content table.compat-attachment-fields tbody > tr > td input, -#post-body-content table.compat-attachment-fields tbody > tr > td textarea { - display: block; - width: 100%; -} -#post-body-content table.compat-attachment-fields tbody > tr { - margin: 1em 0; -} -#post-body-content table.compat-attachment-fields tbody > tr > th.label span { - font-weight: 600; -} \ No newline at end of file diff --git a/vendor/wpmetabox/meta-box/css/media.css b/vendor/wpmetabox/meta-box/css/media.css index ac3cccda1..f5f3afdeb 100644 --- a/vendor/wpmetabox/meta-box/css/media.css +++ b/vendor/wpmetabox/meta-box/css/media.css @@ -1,5 +1,6 @@ .rwmb-media-list { margin: 0; + padding: 0; overflow: hidden; } .rwmb-edit-media, diff --git a/vendor/wpmetabox/meta-box/css/modal.css b/vendor/wpmetabox/meta-box/css/modal.css new file mode 100644 index 000000000..b98cc6477 --- /dev/null +++ b/vendor/wpmetabox/meta-box/css/modal.css @@ -0,0 +1,70 @@ +.rwmb-modal-add-button { + display: inline-block; + margin-top: 6px; +} + +body.rwmb-modal-show, +body.rwmb-modal-show .interface-interface-skeleton__sidebar { + overflow: hidden; +} + +/* Mimic style of media modal */ +.rwmb-modal { + position: fixed; + top: 30px; + left: 30px; + right: 30px; + bottom: 30px; + z-index: 160000; + overflow: hidden; + display: none; +} + +.rwmb-modal-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + min-height: 360px; + background: #000; + opacity: 0.7; + z-index: 159900; + display: none; +} + +.rwmb-modal-title { + background: #f0f0f1; + border-bottom: 1px solid #c3c4c7; + position: relative; +} + +.rwmb-modal-title h2 { + font-size: 22px; + line-height: 50px; + padding: 0 20px; + margin: 0; +} + +.rwmb-modal-close { + position: absolute; + top: 0; + right: 0; + width: 50px; + height: 50px; + font-size: 22px; + line-height: 50px; + margin: 0; + padding: 0; + border: none; + background: none; + color: #646970; + z-index: 1000; + cursor: pointer; + outline: none; + transition: color .1s ease-in-out; +} +.rwmb-modal-close:hover, +.rwmb-modal-close:active { + color: #135e96; +} \ No newline at end of file diff --git a/vendor/wpmetabox/meta-box/css/osm-frontend.css b/vendor/wpmetabox/meta-box/css/osm-frontend.css new file mode 100644 index 000000000..91c1f866b --- /dev/null +++ b/vendor/wpmetabox/meta-box/css/osm-frontend.css @@ -0,0 +1,4 @@ +img.leaflet-marker-icon { + margin-left: -12px; + margin-top: -41px; +} \ No newline at end of file diff --git a/vendor/wpmetabox/meta-box/css/select-tree.css b/vendor/wpmetabox/meta-box/css/select-tree.css index 1eecf565a..bee3a2987 100644 --- a/vendor/wpmetabox/meta-box/css/select-tree.css +++ b/vendor/wpmetabox/meta-box/css/select-tree.css @@ -1,5 +1,5 @@ -.rwmb-select-tree { - display: inline-block; +.rwmb-select-tree .rwmb-select-tree { + margin-top: 6px; } .rwmb-select-tree.hidden { diff --git a/vendor/wpmetabox/meta-box/css/style.css b/vendor/wpmetabox/meta-box/css/style.css index 097ccfffd..5ee16e670 100644 --- a/vendor/wpmetabox/meta-box/css/style.css +++ b/vendor/wpmetabox/meta-box/css/style.css @@ -33,6 +33,7 @@ .rwmb-input .select2-container, .rwmb-input textarea:not([cols]) { width: 100%; + box-sizing: border-box; } .rwmb-input input[type="checkbox"], .rwmb-input input[type="radio"] { @@ -41,10 +42,11 @@ .rwmb-input input[type="button"] { width: auto; } -.rwmb-input input, +.rwmb-input input:not([type="checkbox"]):not([type="radio"]), .rwmb-input textarea, .rwmb-input select { max-width: 100%; + margin-inline: 0; } .rwmb-textarea { resize: vertical; diff --git a/vendor/wpmetabox/meta-box/css/switch.css b/vendor/wpmetabox/meta-box/css/switch.css index ec244a949..5ea409bd6 100644 --- a/vendor/wpmetabox/meta-box/css/switch.css +++ b/vendor/wpmetabox/meta-box/css/switch.css @@ -1,5 +1,3 @@ -/* style switch ------------------------------*/ .rwmb-switch-label { position: relative; display: inline-block; @@ -9,6 +7,8 @@ min-width: 40px; height: 22px; box-sizing: border-box; + + --color: var(--wp-admin-theme-color, #2271b1); } .rwmb-switch.rwmb-switch { @@ -16,8 +16,8 @@ } .rwmb-switch:checked + .rwmb-switch-status .rwmb-switch-slider { - background-color: #0073aa; - box-shadow: 0 0 1px #0073aa; + background-color: var(--color); + box-shadow: 0 0 1px var(--color); } .rwmb-switch:checked + .rwmb-switch-status .rwmb-switch-slider:before { @@ -42,7 +42,6 @@ right: 0; bottom: 0; z-index: 15; - -webkit-transition: .4s; transition: .4s; } @@ -55,7 +54,6 @@ bottom: 2px; z-index: 99; background-color: white; - -webkit-transition: .4s; transition: .4s; border-radius: 2px; } @@ -83,6 +81,7 @@ font-size: 11px; position: relative; z-index: 20; + line-height: 18px; } .rwmb-switch-on { @@ -94,27 +93,27 @@ } /* Admin color schemes */ -.admin-color-blue .rwmb-switch:checked + .rwmb-switch-status .rwmb-switch-slider { - background-color: #e1a948; - box-shadow: 0 0 1px #e1a948; -} -.admin-color-coffee .rwmb-switch:checked + .rwmb-switch-status .rwmb-switch-slider { - background-color: #c7a589; - box-shadow: 0 0 1px #c7a589; -} -.admin-color-ectoplasm .rwmb-switch:checked + .rwmb-switch-status .rwmb-switch-slider { - background-color: #a3b745; - box-shadow: 0 0 1px #a3b745; -} -.admin-color-midnight .rwmb-switch:checked + .rwmb-switch-status .rwmb-switch-slider { - background-color: #e14d43; - box-shadow: 0 0 1px #e14d43; -} -.admin-color-ocean .rwmb-switch:checked + .rwmb-switch-status .rwmb-switch-slider { - background-color: #9ebaa0; - box-shadow: 0 0 1px #9ebaa0; -} -.admin-color-sunrise .rwmb-switch:checked + .rwmb-switch-status .rwmb-switch-slider { - background-color: #dd823b; - box-shadow: 0 0 1px #dd823b; -} \ No newline at end of file +.admin-color-blue .rwmb-switch-label { + --color: var(--wp-admin-theme-color, #e1a948); +} +.admin-color-coffee .rwmb-switch-label { + --color: var(--wp-admin-theme-color, #c7a589); +} +.admin-color-ectoplasm .rwmb-switch-label { + --color: var(--wp-admin-theme-color, #a3b745); +} +.admin-color-light .rwmb-switch-label { + --color: var(--wp-admin-theme-color, #04a4cc); +} +.admin-color-midnight .rwmb-switch-label { + --color: var(--wp-admin-theme-color, #e14d43); +} +.admin-color-modern .rwmb-switch-label { + --color: var(--wp-admin-theme-color, #3858e9); +} +.admin-color-ocean .rwmb-switch-label { + --color: var(--wp-admin-theme-color, #9ebaa0); +} +.admin-color-sunrise .rwmb-switch-label { + --color: var(--wp-admin-theme-color, #dd823b); +} diff --git a/vendor/wpmetabox/meta-box/css/taxonomy.css b/vendor/wpmetabox/meta-box/css/taxonomy.css deleted file mode 100644 index 257967f4e..000000000 --- a/vendor/wpmetabox/meta-box/css/taxonomy.css +++ /dev/null @@ -1,18 +0,0 @@ -.rwmb-taxonomy-add, -.rwmb-taxonomy-add-form { - margin-top: 6px; -} -.rwmb-taxonomy-add-button { - padding: 0; - border: 0; - background: none; - color: #0073aa; - text-decoration: underline; - cursor: pointer; -} -.rwmb-taxonomy-add-button:hover { - color: #00a0d2; -} -.rwmb-taxonomy-add-form.rwmb-hidden { - display: none; -} \ No newline at end of file diff --git a/vendor/wpmetabox/meta-box/gulpfile.js b/vendor/wpmetabox/meta-box/gulpfile.js deleted file mode 100644 index 78e191b94..000000000 --- a/vendor/wpmetabox/meta-box/gulpfile.js +++ /dev/null @@ -1,27 +0,0 @@ -const { src, dest, series } = require('gulp'); -const babel = require('gulp-babel'); -const concat = require('gulp-concat'); -const terser = require('gulp-terser'); -const clean = require('gulp-clean'); - -const validationCompile = () => { - return src('js/validation/validation.js') - .pipe(babel({ - presets: ['@babel/env'] - })) - .pipe(dest('js/build/')); -} - -const validationConcat = () => { - return src(['js/validation/jquery.validate.js', 'js/validation/additional-methods.js', 'js/build/validation.js']) - .pipe(concat('validation.min.js')) - .pipe(terser()) - .pipe(dest('js')); -} - -const validationClean = () => { - return src('js/build', {read: false}) - .pipe(clean()); -} - -exports.default = series( validationCompile, validationConcat, validationClean ); \ No newline at end of file diff --git a/vendor/wpmetabox/meta-box/inc/about/about.php b/vendor/wpmetabox/meta-box/inc/about/about.php index a1cc32551..ebd2055df 100644 --- a/vendor/wpmetabox/meta-box/inc/about/about.php +++ b/vendor/wpmetabox/meta-box/inc/about/about.php @@ -1,12 +1,6 @@ update_checker = $update_checker; } - /** - * Init hooks. - */ public function init() { // Add links to about page in the plugin action links. - add_filter( 'plugin_action_links_meta-box/meta-box.php', array( $this, 'plugin_links' ), 20 ); + add_filter( 'plugin_action_links_meta-box/meta-box.php', [ $this, 'plugin_links' ], 20 ); // Add a shared top-level admin menu and Dashboard page. Use priority 5 to show Dashboard at the top. - add_action( 'admin_menu', array( $this, 'add_menu' ), 5 ); - add_action( 'admin_menu', array( $this, 'add_submenu' ), 5 ); + add_action( 'admin_menu', [ $this, 'add_menu' ], 5 ); + add_action( 'admin_menu', [ $this, 'add_submenu' ], 5 ); // If no admin menu, then hide the About page. - add_action( 'admin_head', array( $this, 'hide_page' ) ); + add_action( 'admin_head', [ $this, 'hide_page' ] ); // Redirect to about page after activation. - add_action( 'activated_plugin', array( $this, 'redirect' ), 10, 2 ); + add_action( 'activated_plugin', [ $this, 'redirect' ], 10, 2 ); } - /** - * Add links to About page. - * - * @param array $links Array of plugin links. - * - * @return array - */ - public function plugin_links( $links ) { + public function plugin_links( array $links ): array { $links[] = '' . esc_html__( 'About', 'meta-box' ) . ''; if ( ! $this->update_checker->has_extensions() ) { $links[] = '' . esc_html__( 'Go Pro', 'meta-box' ) . ''; @@ -58,9 +42,6 @@ public function plugin_links( $links ) { return $links; } - /** - * Register admin page. - */ public function add_menu() { if ( ! $this->has_menu() ) { return; @@ -75,9 +56,6 @@ public function add_menu() { ); } - /** - * Add submenu for the About page. - */ public function add_submenu() { $parent_menu = $this->has_menu() ? 'meta-box' : $this->get_parent_menu(); $about = add_submenu_page( @@ -86,29 +64,15 @@ public function add_submenu() { __( 'Dashboard', 'meta-box' ), 'activate_plugins', 'meta-box', - array( $this, 'render' ) + [ $this, 'render' ] ); - add_action( "load-$about", array( $this, 'load_about' ) ); - } - - /** - * Functions and hooks for about page. - */ - public function load_about() { - $this->enqueue(); - add_filter( 'admin_footer_text', array( $this, 'change_footer_text' ) ); + add_action( "load-$about", [ $this, 'enqueue' ] ); } - /** - * Hide about page from the admin menu. - */ public function hide_page() { remove_submenu_page( $this->get_parent_menu(), 'meta-box' ); } - /** - * Render admin page. - */ public function render() { ?>
                    @@ -133,6 +97,7 @@ public function render() {
                    update_checker->has_extensions() ) { include __DIR__ . '/sections/upgrade.php'; } @@ -144,20 +109,9 @@ public function render() { Meta Box ★★★★★ on WordPress.org to help us spread the word. Thank you from the Meta Box team!', 'meta-box' ), 'https://wordpress.org/support/view/plugin-reviews/meta-box?filter=5#new-post' ) ); + wp_enqueue_style( 'meta-box-about', RWMB_URL . 'inc/about/css/about.css', [], RWMB_VER ); + wp_enqueue_script( 'meta-box-about', RWMB_URL . 'inc/about/js/about.js', [ 'jquery' ], RWMB_VER, true ); } /** @@ -179,43 +133,23 @@ public function redirect( $plugin, $network_wide = false ) { die; } - /** - * Get link to the plugin admin menu. - * - * @return string - */ - protected function get_menu_link() { + private function get_menu_link(): string { $menu = $this->has_menu() ? 'admin.php?page=meta-box' : $this->get_parent_menu() . '?page=meta-box'; return admin_url( $menu ); } - /** - * Get default parent menu, which is Plugins. - * - * @return string - */ - protected function get_parent_menu() { + private function get_parent_menu(): string { return 'plugins.php'; } - /** - * Check if the plugin has a top-level admin menu. - * - * @return bool - */ - protected function has_menu() { + private function has_menu(): bool { return apply_filters( 'rwmb_admin_menu', false ); } - /** - * Check if Meta Box is bundled by TGM Activation Class. - * - * @return bool - */ - protected function is_bundled() { + private function is_bundled(): bool { // @codingStandardsIgnoreLine foreach ( $_REQUEST as $key => $value ) { - if ( false !== strpos( $key, 'tgmpa' ) || ( ! is_array( $value ) && false !== strpos( $value, 'tgmpa' ) ) ) { + if ( str_contains( $key, 'tgmpa' ) || ( is_string( $value ) && str_contains( $value, 'tgmpa' ) ) ) { return true; } } diff --git a/vendor/wpmetabox/meta-box/inc/about/css/about.css b/vendor/wpmetabox/meta-box/inc/about/css/about.css index 46a8afa81..dd0e34e30 100644 --- a/vendor/wpmetabox/meta-box/inc/about/css/about.css +++ b/vendor/wpmetabox/meta-box/inc/about/css/about.css @@ -193,4 +193,42 @@ left: 0; width: 100%; height: 100%; -} \ No newline at end of file +} +#getting-started .tutorial a { + font-size: 32px; + font-weight: 600; + color:#32373c; + text-decoration: unset; +} +#getting-started .tutorial a:hover { + color: #2271b1; +} +.tutorial-items{ + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 15px 30px; + margin-top: 30px; +} +@media (max-width: 767px) { + .tutorial-items{ + grid-template-columns: repeat(1, 1fr); + gap: 15px 0px; + } +} +.tutorial-items a{ + font-size: 20px; + font-weight: 500; + color:#32373c; + text-decoration: unset; +} +.tutorial-items a:hover{ + color:#2271b1; +} +.tutorial-items a span{ + margin-right: 5px; +} +.tutorial-items a p{ + font-size: 14px; + font-weight: 400; + color:#32373c; +} diff --git a/vendor/wpmetabox/meta-box/inc/about/dashboard.php b/vendor/wpmetabox/meta-box/inc/about/dashboard.php index 2c970d68c..a2c584a17 100644 --- a/vendor/wpmetabox/meta-box/inc/about/dashboard.php +++ b/vendor/wpmetabox/meta-box/inc/about/dashboard.php @@ -5,29 +5,23 @@ class RWMB_Dashboard { private $translations; private $slug; - public function __construct( $feed_url, $link, $translations ) { + public function __construct( string $feed_url, string $link, array $translations ) { $this->feed_url = $feed_url; $this->link = $link; $this->translations = $translations; $this->slug = sanitize_title( $translations['title'] ); $transient_name = $this->get_transient_name(); - add_filter( "transient_$transient_name", array( $this, 'add_news' ) ); - add_action( "wp_ajax_{$this->slug}-dismiss-news", array( $this, 'ajax_dismiss' ) ); + add_filter( "transient_$transient_name", [ $this, 'add_news' ] ); + add_action( "wp_ajax_{$this->slug}-dismiss-news", [ $this, 'ajax_dismiss' ] ); } - private function get_transient_name() { - include ABSPATH . WPINC . '/version.php'; - global $wp_version; - - $locale = function_exists( 'get_user_locale' ) ? get_user_locale() : get_locale(); - $prefix = version_compare( $wp_version, '4.8', '>=') ? 'dash_v2_' : 'dash_'; - $widget_id = 'dashboard_primary'; - - return version_compare( $wp_version, '4.3', '>=' ) ? $prefix . md5( "{$widget_id}_{$locale}" ) : 'dash_' . md5( $widget_id ); + private function get_transient_name() : string { + $locale = get_user_locale(); + return 'dash_v2_' . md5( "dashboard_primary_{$locale}" ); } - public function add_news( $value ) { + public function add_news( string $value ) : string { $is_dismissed = get_user_meta( get_current_user_id(), $this->slug . '_dismiss_news', true ); $is_dismissed = apply_filters( 'rwmb_dismiss_dashboard_widget', $is_dismissed ); if ( $is_dismissed ) { @@ -41,15 +35,15 @@ public function add_news( $value ) { return $value . $this->get_html() . $script; } - private function get_html() { + private function get_html() : string { $cache_key = $this->slug . '-news'; - $output = get_transient( $cache_key ); - if ( false !== $output) { + $output = get_transient( $cache_key ); + if ( false !== $output ) { return $output; } - $feeds = array( - $this->slug => array( + $feeds = [ + $this->slug => [ 'link' => $this->link, 'url' => $this->feed_url, 'title' => $this->translations['title'], @@ -57,13 +51,13 @@ private function get_html() { 'show_summary' => 0, 'show_author' => 0, 'show_date' => 0, - ) - ); + ], + ]; ob_start(); wp_dashboard_primary_output( 'dashboard_primary', $feeds ); - $output = ob_get_clean(); + $output = (string) ob_get_clean(); - $output = preg_replace( '/(.+?)<\/a>/i', '' . esc_html( $this->translations['title'] ) . ': $2', $output ); + $output = (string) preg_replace( '/(.+?)<\/a>/i', '' . esc_html( $this->translations['title'] ) . ': $2', $output ); $output = str_replace( '
                  • ', '
                  • ', $output ); set_transient( $cache_key, $output, DAY_IN_SECONDS ); @@ -93,4 +87,4 @@ public function ajax_dismiss() { update_user_meta( get_current_user_id(), $this->slug . '_dismiss_news', 1 ); wp_send_json_success(); } -} \ No newline at end of file +} diff --git a/vendor/wpmetabox/meta-box/inc/about/sections/extensions.php b/vendor/wpmetabox/meta-box/inc/about/sections/extensions.php index 77cc540c3..be8330925 100644 --- a/vendor/wpmetabox/meta-box/inc/about/sections/extensions.php +++ b/vendor/wpmetabox/meta-box/inc/about/sections/extensions.php @@ -1,11 +1,5 @@ - -?>


                    diff --git a/vendor/wpmetabox/meta-box/inc/about/sections/getting-started-pro.php b/vendor/wpmetabox/meta-box/inc/about/sections/getting-started-pro.php index e0bff9ea9..fcf2d66a3 100644 --- a/vendor/wpmetabox/meta-box/inc/about/sections/getting-started-pro.php +++ b/vendor/wpmetabox/meta-box/inc/about/sections/getting-started-pro.php @@ -1,6 +1,18 @@ + +

                    +

                    +

                    +
                    +

                    +

                    +

                    +

                    +

                    +

                    +
                    diff --git a/vendor/wpmetabox/meta-box/inc/about/sections/getting-started.php b/vendor/wpmetabox/meta-box/inc/about/sections/getting-started.php index 85bf11238..a4445c098 100644 --- a/vendor/wpmetabox/meta-box/inc/about/sections/getting-started.php +++ b/vendor/wpmetabox/meta-box/inc/about/sections/getting-started.php @@ -1,11 +1,5 @@ - -?>
                    diff --git a/vendor/wpmetabox/meta-box/inc/about/sections/products.php b/vendor/wpmetabox/meta-box/inc/about/sections/products.php index feac1cb36..af9264c41 100644 --- a/vendor/wpmetabox/meta-box/inc/about/sections/products.php +++ b/vendor/wpmetabox/meta-box/inc/about/sections/products.php @@ -1,19 +1,13 @@ - +

                    - +

                    -
                    \ No newline at end of file +
                    diff --git a/vendor/wpmetabox/meta-box/inc/about/sections/review.php b/vendor/wpmetabox/meta-box/inc/about/sections/review.php new file mode 100644 index 000000000..11942bd60 --- /dev/null +++ b/vendor/wpmetabox/meta-box/inc/about/sections/review.php @@ -0,0 +1,11 @@ + + +
                    +

                    + +

                    +
                    +

                    +

                    +
                    +
                    diff --git a/vendor/wpmetabox/meta-box/inc/about/sections/support.php b/vendor/wpmetabox/meta-box/inc/about/sections/support.php index d0c7263ed..7efedd944 100644 --- a/vendor/wpmetabox/meta-box/inc/about/sections/support.php +++ b/vendor/wpmetabox/meta-box/inc/about/sections/support.php @@ -1,19 +1,13 @@ - -?>

                    array( - 'href' => array(), - ), - ); + $allowed_html = [ + 'a' => [ + 'href' => [], + ], + ]; // Translators: %s - link to documentation. echo wp_kses( sprintf( __( 'Still need help with Meta Box? We offer excellent support for you. But don\'t forget to check our documentation first.', 'meta-box' ), 'https://docs.metabox.io?utm_source=WordPress&utm_medium=link&utm_campaign=plugin' ), $allowed_html ); ?> diff --git a/vendor/wpmetabox/meta-box/inc/about/sections/tabs.php b/vendor/wpmetabox/meta-box/inc/about/sections/tabs.php index 45175e24d..f5fb0a378 100644 --- a/vendor/wpmetabox/meta-box/inc/about/sections/tabs.php +++ b/vendor/wpmetabox/meta-box/inc/about/sections/tabs.php @@ -1,11 +1,5 @@ - -?>

                    '; + protected static function end_html( array $field ) : string { + return RWMB_Clone::add_clone_button( $field ) . static::input_description( $field ) . '
                    '; } - /** - * Display field label description. - * - * @param array $field Field parameters. - * @return string - */ - protected static function label_description( $field ) { + protected static function label_description( array $field ) : string { $id = $field['id'] ? ' id="' . esc_attr( $field['id'] ) . '-label-description"' : ''; return $field['label_description'] ? "{$field['label_description']}

                    " : ''; } - /** - * Display field description. - * - * @param array $field Field parameters. - * @return string - */ - protected static function input_description( $field ) { + protected static function input_description( array $field ) : string { $id = $field['id'] ? ' id="' . esc_attr( $field['id'] ) . '-description"' : ''; return $field['desc'] ? "{$field['desc']}

                    " : ''; } @@ -161,7 +124,7 @@ protected static function input_description( $field ) { * * @return mixed */ - public static function raw_meta( $object_id, $field, $args = array() ) { + public static function raw_meta( $object_id, $field, $args = [] ) { if ( empty( $field['id'] ) ) { return ''; } @@ -212,11 +175,11 @@ public static function meta( $post_id, $saved, $field ) { $meta = ! $saved || ! $field['save_field'] ? $field['std'] : $meta; if ( $field['clone'] ) { - $meta = RWMB_Helpers_Array::ensure( $meta ); + $meta = Arr::ensure( $meta ); // Ensure $meta is an array with values so that the foreach loop in self::show() runs properly. if ( empty( $meta ) ) { - $meta = array( '' ); + $meta = [ '' ]; } if ( $field['multiple'] ) { @@ -224,10 +187,10 @@ public static function meta( $post_id, $saved, $field ) { // If users set std for a cloneable checkbox list field in the Builder, they can only set [value1, value2]. We need to transform it to [[value1, value2]]. // In other cases, make sure each value is an array. - $meta = is_array( $first ) ? array_map( 'RWMB_Helpers_Array::ensure', $meta ) : array( $meta ); + $meta = is_array( $first ) ? array_map( 'MetaBox\Support\Arr::ensure', $meta ) : [ $meta ]; } } elseif ( $field['multiple'] ) { - $meta = RWMB_Helpers_Array::ensure( $meta ); + $meta = Arr::ensure( $meta ); } return $meta; @@ -240,7 +203,7 @@ public static function meta( $post_id, $saved, $field ) { * @param int $object_id The object ID. * @param array $field The field settings. */ - public static function process_value( $value, $object_id, $field ) { + public static function process_value( $value, $object_id, array $field ) { $old_value = self::call( $field, 'raw_meta', $object_id ); // Allow field class change the value. @@ -319,45 +282,42 @@ public static function save( $new, $old, $post_id, $field ) { public static function normalize( $field ) { // Quick define text fields with "name" attribute only. if ( is_string( $field ) ) { - $field = array( + $field = [ 'name' => $field, 'id' => sanitize_key( $field ), - ); - } - $field = wp_parse_args( - $field, - array( - 'id' => '', - 'name' => '', - 'type' => 'text', - 'label_description' => '', - 'multiple' => false, - 'std' => '', - 'desc' => '', - 'format' => '', - 'before' => '', - 'after' => '', - 'field_name' => isset( $field['id'] ) ? $field['id'] : '', - 'placeholder' => '', - 'save_field' => true, - - 'clone' => false, - 'min_clone' => 0, - 'max_clone' => 0, - 'sort_clone' => false, - 'add_button' => __( '+ Add more', 'meta-box' ), - 'clone_default' => false, - 'clone_as_multiple' => false, - - 'class' => '', - 'disabled' => false, - 'required' => false, - 'autofocus' => false, - 'attributes' => array(), - - 'sanitize_callback' => null, - ) - ); + ]; + } + $field = wp_parse_args( $field, [ + 'id' => '', + 'name' => '', + 'type' => 'text', + 'label_description' => '', + 'multiple' => false, + 'std' => '', + 'desc' => '', + 'format' => '', + 'before' => '', + 'after' => '', + 'field_name' => $field['id'] ?? '', + 'placeholder' => '', + 'save_field' => true, + + 'clone' => false, + 'min_clone' => 0, + 'max_clone' => 0, + 'sort_clone' => false, + 'add_button' => __( '+ Add more', 'meta-box' ), + 'clone_default' => false, + 'clone_as_multiple' => false, + + 'class' => '', + 'disabled' => false, + 'required' => false, + 'autofocus' => false, + 'attributes' => [], + + 'sanitize_callback' => null, + ] ); // Store the original ID to run correct filters for the clonable field. if ( $field['clone'] ) { @@ -365,13 +325,10 @@ public static function normalize( $field ) { } if ( $field['clone_default'] ) { - $field['attributes'] = wp_parse_args( - $field['attributes'], - array( - 'data-default' => $field['std'], - 'data-clone-default' => 'true', - ) - ); + $field['attributes'] = wp_parse_args( $field['attributes'], [ + 'data-default' => $field['std'], + 'data-clone-default' => 'true', + ] ); } if ( 1 === $field['max_clone'] ) { @@ -390,31 +347,29 @@ public static function normalize( $field ) { * @return array */ public static function get_attributes( $field, $value = null ) { - $attributes = wp_parse_args( - $field['attributes'], - array( - 'disabled' => $field['disabled'], - 'autofocus' => $field['autofocus'], - 'required' => $field['required'], - 'id' => $field['id'], - 'class' => '', - 'name' => $field['field_name'], - ) - ); + $attributes = wp_parse_args( $field['attributes'], [ + 'disabled' => $field['disabled'], + 'autofocus' => $field['autofocus'], + 'required' => $field['required'], + 'id' => $field['id'], + 'class' => '', + 'name' => $field['field_name'], + ] ); + + $attributes['class'] = trim( implode( ' ', array_merge( [ "rwmb-{$field['type']}" ], (array) $attributes['class'] ) ) ); - $attributes['class'] = trim( implode( ' ', array_merge( array( "rwmb-{$field['type']}" ), (array) $attributes['class'] ) ) ); + $id = $attributes['id'] ?: $field['id']; + if ( $field['name'] || $field['label_description'] ) { + $attributes['aria-labelledby'] = "$id-label"; + } + if ( $field['desc'] ) { + $attributes['aria-describedby'] = "$id-description"; + } return $attributes; } - /** - * Renders an attribute array into an html attributes string. - * - * @param array $attributes HTML attributes. - * - * @return string - */ - public static function render_attributes( $attributes ) { + public static function render_attributes( array $attributes ) : string { $output = ''; $attributes = array_filter( $attributes, 'RWMB_Helpers_Value::is_valid_for_attribute' ); @@ -438,13 +393,13 @@ public static function render_attributes( $attributes ) { * Each field can extend this function and add more data to the returned value. * See specific field classes for details. * - * @param array $field Field parameters. - * @param array $args Additional arguments. Rarely used. See specific fields for details. - * @param int|null $post_id Post ID. null for current post. Optional. + * @param array $field Field parameters. + * @param array $args Additional arguments. Rarely used. See specific fields for details. + * @param ?int $post_id Post ID. * * @return mixed Field value */ - public static function get_value( $field, $args = array(), $post_id = null ) { + public static function get_value( $field, $args = [], $post_id = null ) { // Some fields does not have ID like heading, custom HTML, etc. if ( empty( $field['id'] ) ) { return ''; @@ -459,7 +414,7 @@ public static function get_value( $field, $args = array(), $post_id = null ) { // Make sure meta value is an array for cloneable and multiple fields. if ( $field['clone'] || $field['multiple'] ) { - $value = is_array( $value ) && $value ? $value : array(); + $value = is_array( $value ) && ! empty( $value ) ? $value : []; } return $value; @@ -482,7 +437,7 @@ public static function get_value( $field, $args = array(), $post_id = null ) { * * @return string HTML output of the field */ - public static function the_value( $field, $args = array(), $post_id = null ) { + public static function the_value( $field, $args = [], $post_id = null ) { $value = self::call( 'get_value', $field, $args, $post_id ); if ( false === $value ) { @@ -562,15 +517,14 @@ public static function call() { if ( is_string( $check ) ) { $method = array_shift( $args ); $field = reset( $args ); // Keep field as 1st param. - } - // Params: field, method name, other params. - else { + } else { + // Params: field, method name, other params. $field = array_shift( $args ); $method = array_shift( $args ); if ( 'raw_meta' === $method ) { // Add field param after object id. - array_splice( $args, 1, 0, array( $field ) ); + array_splice( $args, 1, 0, [ $field ] ); } else { $args[] = $field; // Add field as last param. } @@ -578,10 +532,10 @@ public static function call() { $class = RWMB_Helpers_Field::get_class( $field ); if ( method_exists( $class, $method ) ) { - return call_user_func_array( array( $class, $method ), $args ); - } else { - _deprecated_function( "$class::$method", '5.4.8' ); + return call_user_func_array( [ $class, $method ], $args ); } + + _deprecated_function( esc_html( "$class::$method" ), '5.4.8' ); } /** @@ -602,10 +556,10 @@ public static function filter() { $field = array_shift( $args ); // List of filters. - $filters = array( + $filters = [ 'rwmb_' . $name, 'rwmb_' . $field['type'] . '_' . $name, - ); + ]; if ( $field['id'] ) { $field_id = $field['clone'] ? $field['_original_id'] : $field['id']; $filters[] = 'rwmb_' . $field_id . '_' . $name; diff --git a/vendor/wpmetabox/meta-box/inc/fields/autocomplete.php b/vendor/wpmetabox/meta-box/inc/fields/autocomplete.php index 746ec59db..902d7c96c 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/autocomplete.php +++ b/vendor/wpmetabox/meta-box/inc/fields/autocomplete.php @@ -1,28 +1,17 @@ __( 'Delete', 'meta-box' ), - ) - ); + RWMB_Helpers_Field::localize_script_once( 'rwmb-autocomplete', 'RWMB_Autocomplete', [ + 'delete' => __( 'Delete', 'meta-box' ), + ] ); } /** @@ -34,19 +23,19 @@ public static function admin_enqueue_scripts() { */ public static function html( $meta, $field ) { if ( ! is_array( $meta ) ) { - $meta = array( $meta ); + $meta = [ $meta ]; } $field = apply_filters( 'rwmb_autocomplete_field', $field, $meta ); $options = $field['options']; if ( is_array( $field['options'] ) ) { - $options = array(); + $options = []; foreach ( $field['options'] as $value => $label ) { - $options[] = array( + $options[] = [ 'value' => $value, 'label' => $label, - ); + ]; } $options = wp_json_encode( $options ); } diff --git a/vendor/wpmetabox/meta-box/inc/fields/background.php b/vendor/wpmetabox/meta-box/inc/fields/background.php index d639f92e3..bb695499c 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/background.php +++ b/vendor/wpmetabox/meta-box/inc/fields/background.php @@ -1,30 +1,21 @@ 'color', - 'id' => "{$field['id']}_color", - 'field_name' => "{$field['field_name']}[color]", - 'alpha_channel' => true, - ) - ); + $color = RWMB_Color_Field::normalize( [ + 'type' => 'color', + 'id' => "{$field['id']}_color", + 'field_name' => "{$field['field_name']}[color]", + 'alpha_channel' => true, + ] ); RWMB_Color_Field::admin_enqueue_scripts( $color ); RWMB_File_Input_Field::admin_enqueue_scripts(); } @@ -38,118 +29,103 @@ public static function admin_enqueue_scripts() { * @return string */ public static function html( $meta, $field ) { - $meta = wp_parse_args( - $meta, - array( - 'color' => '', - 'image' => '', - 'repeat' => '', - 'attachment' => '', - 'position' => '', - 'size' => '', - ) - ); + $meta = wp_parse_args( $meta, [ + 'color' => '', + 'image' => '', + 'repeat' => '', + 'attachment' => '', + 'position' => '', + 'size' => '', + ] ); $output = '
                    '; // Color. - $color = RWMB_Color_Field::normalize( - array( - 'type' => 'color', - 'id' => "{$field['id']}_color", - 'field_name' => "{$field['field_name']}[color]", - 'alpha_channel' => true, - ) - ); + $color = RWMB_Color_Field::normalize( [ + 'type' => 'color', + 'id' => "{$field['id']}_color", + 'field_name' => "{$field['field_name']}[color]", + 'alpha_channel' => true, + ] ); $output .= RWMB_Color_Field::html( $meta['color'], $color ); $output .= '
                    '; $output .= '
                    '; // Image. - $image = RWMB_File_Input_Field::normalize( - array( - 'type' => 'file_input', - 'id' => "{$field['id']}_image", - 'field_name' => "{$field['field_name']}[image]", - 'placeholder' => __( 'Background Image', 'meta-box' ), - ) - ); + $image = RWMB_File_Input_Field::normalize( [ + 'type' => 'file_input', + 'id' => "{$field['id']}_image", + 'field_name' => "{$field['field_name']}[image]", + 'placeholder' => __( 'Background Image', 'meta-box' ), + ] ); $output .= RWMB_File_Input_Field::html( $meta['image'], $image ); $output .= '
                    '; $output .= '
                    '; // Repeat. - $repeat = RWMB_Select_Field::normalize( - array( - 'type' => 'select', - 'id' => "{$field['id']}_repeat", - 'field_name' => "{$field['field_name']}[repeat]", - 'placeholder' => esc_html__( '-- Repeat --', 'meta-box' ), - 'options' => array( - 'no-repeat' => esc_html__( 'No Repeat', 'meta-box' ), - 'repeat' => esc_html__( 'Repeat All', 'meta-box' ), - 'repeat-x' => esc_html__( 'Repeat Horizontally', 'meta-box' ), - 'repeat-y' => esc_html__( 'Repeat Vertically', 'meta-box' ), - 'inherit' => esc_html__( 'Inherit', 'meta-box' ), - ), - ) - ); + $repeat = RWMB_Select_Field::normalize( [ + 'type' => 'select', + 'id' => "{$field['id']}_repeat", + 'field_name' => "{$field['field_name']}[repeat]", + 'placeholder' => esc_html__( '-- Repeat --', 'meta-box' ), + 'options' => [ + 'no-repeat' => esc_html__( 'No Repeat', 'meta-box' ), + 'repeat' => esc_html__( 'Repeat All', 'meta-box' ), + 'repeat-x' => esc_html__( 'Repeat Horizontally', 'meta-box' ), + 'repeat-y' => esc_html__( 'Repeat Vertically', 'meta-box' ), + 'inherit' => esc_html__( 'Inherit', 'meta-box' ), + ], + ] ); $output .= RWMB_Select_Field::html( $meta['repeat'], $repeat ); // Position. - $position = RWMB_Select_Field::normalize( - array( - 'type' => 'select', - 'id' => "{$field['id']}_position", - 'field_name' => "{$field['field_name']}[position]", - 'placeholder' => esc_html__( '-- Position --', 'meta-box' ), - 'options' => array( - 'top left' => esc_html__( 'Top Left', 'meta-box' ), - 'top center' => esc_html__( 'Top Center', 'meta-box' ), - 'top right' => esc_html__( 'Top Right', 'meta-box' ), - 'center left' => esc_html__( 'Center Left', 'meta-box' ), - 'center center' => esc_html__( 'Center Center', 'meta-box' ), - 'center right' => esc_html__( 'Center Right', 'meta-box' ), - 'bottom left' => esc_html__( 'Bottom Left', 'meta-box' ), - 'bottom center' => esc_html__( 'Bottom Center', 'meta-box' ), - 'bottom right' => esc_html__( 'Bottom Right', 'meta-box' ), - ), - ) - ); + $position = RWMB_Select_Field::normalize( [ + 'type' => 'select', + 'id' => "{$field['id']}_position", + 'field_name' => "{$field['field_name']}[position]", + 'placeholder' => esc_html__( '-- Position --', 'meta-box' ), + 'options' => [ + 'top left' => esc_html__( 'Top Left', 'meta-box' ), + 'top center' => esc_html__( 'Top Center', 'meta-box' ), + 'top right' => esc_html__( 'Top Right', 'meta-box' ), + 'center left' => esc_html__( 'Center Left', 'meta-box' ), + 'center center' => esc_html__( 'Center Center', 'meta-box' ), + 'center right' => esc_html__( 'Center Right', 'meta-box' ), + 'bottom left' => esc_html__( 'Bottom Left', 'meta-box' ), + 'bottom center' => esc_html__( 'Bottom Center', 'meta-box' ), + 'bottom right' => esc_html__( 'Bottom Right', 'meta-box' ), + ], + ] ); $output .= RWMB_Select_Field::html( $meta['position'], $position ); // Attachment. - $attachment = RWMB_Select_Field::normalize( - array( - 'type' => 'select', - 'id' => "{$field['id']}_attachment", - 'field_name' => "{$field['field_name']}[attachment]", - 'placeholder' => esc_html__( '-- Attachment --', 'meta-box' ), - 'options' => array( - 'fixed' => esc_html__( 'Fixed', 'meta-box' ), - 'scroll' => esc_html__( 'Scroll', 'meta-box' ), - 'inherit' => esc_html__( 'Inherit', 'meta-box' ), - ), - ) - ); + $attachment = RWMB_Select_Field::normalize( [ + 'type' => 'select', + 'id' => "{$field['id']}_attachment", + 'field_name' => "{$field['field_name']}[attachment]", + 'placeholder' => esc_html__( '-- Attachment --', 'meta-box' ), + 'options' => [ + 'fixed' => esc_html__( 'Fixed', 'meta-box' ), + 'scroll' => esc_html__( 'Scroll', 'meta-box' ), + 'inherit' => esc_html__( 'Inherit', 'meta-box' ), + ], + ] ); $output .= RWMB_Select_Field::html( $meta['attachment'], $attachment ); // Size. - $size = RWMB_Select_Field::normalize( - array( - 'type' => 'select', - 'id' => "{$field['id']}_size", - 'field_name' => "{$field['field_name']}[size]", - 'placeholder' => esc_html__( '-- Size --', 'meta-box' ), - 'options' => array( - 'inherit' => esc_html__( 'Inherit', 'meta-box' ), - 'cover' => esc_html__( 'Cover', 'meta-box' ), - 'contain' => esc_html__( 'Contain', 'meta-box' ), - ), - ) - ); + $size = RWMB_Select_Field::normalize( [ + 'type' => 'select', + 'id' => "{$field['id']}_size", + 'field_name' => "{$field['field_name']}[size]", + 'placeholder' => esc_html__( '-- Size --', 'meta-box' ), + 'options' => [ + 'inherit' => esc_html__( 'Inherit', 'meta-box' ), + 'cover' => esc_html__( 'Cover', 'meta-box' ), + 'contain' => esc_html__( 'Contain', 'meta-box' ), + ], + ] ); $output .= RWMB_Select_Field::html( $meta['size'], $size ); $output .= '
                    '; diff --git a/vendor/wpmetabox/meta-box/inc/fields/button-group.php b/vendor/wpmetabox/meta-box/inc/fields/button-group.php index beb765b17..399caca79 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/button-group.php +++ b/vendor/wpmetabox/meta-box/inc/fields/button-group.php @@ -1,20 +1,13 @@ ', - $field['inline'] ? ' rwmb-inline' : '' + '
                    ', + $field['inline'] ? 'rwmb-inline' : '' ); $output .= $walker->walk( $options, -1 ); - $output .= ''; + $output .= '
                    '; return $output; } @@ -47,18 +40,14 @@ public static function html( $meta, $field ) { */ public static function normalize( $field ) { $field = parent::normalize( $field ); - $field = wp_parse_args( - $field, - array( - 'inline' => null, - ) - ); + $field = wp_parse_args( $field, [ + 'inline' => true, + ] ); $field = $field['multiple'] ? RWMB_Multiple_Values_Field::normalize( $field ) : $field; $field = RWMB_Input_Field::normalize( $field ); $field['flatten'] = true; - $field['inline'] = ! $field['multiple'] && ! isset( $field['inline'] ) ? true : $field['inline']; return $field; } diff --git a/vendor/wpmetabox/meta-box/inc/fields/button.php b/vendor/wpmetabox/meta-box/inc/fields/button.php index c98867a36..63d358548 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/button.php +++ b/vendor/wpmetabox/meta-box/inc/fields/button.php @@ -1,12 +1,8 @@ __( 'Click me', 'meta-box' ), - ) - ); + $field = wp_parse_args( $field, [ + 'std' => __( 'Click me', 'meta-box' ), + ] ); $field = parent::normalize( $field ); return $field; } @@ -47,12 +40,9 @@ public static function normalize( $field ) { */ public static function get_attributes( $field, $value = null ) { $attributes = parent::get_attributes( $field, $value ); - $attributes = wp_parse_args( - $attributes, - array( - 'type' => $field['type'], - ) - ); + $attributes = wp_parse_args( $attributes, [ + 'type' => $field['type'], + ] ); $attributes['class'] .= ' button hide-if-no-js'; return $attributes; diff --git a/vendor/wpmetabox/meta-box/inc/fields/checkbox-list.php b/vendor/wpmetabox/meta-box/inc/fields/checkbox-list.php index 81f99a0ae..60581b23e 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/checkbox-list.php +++ b/vendor/wpmetabox/meta-box/inc/fields/checkbox-list.php @@ -1,12 +1,8 @@ true, - 'options' => array(), - ) - ); + $field = wp_parse_args( $field, [ + 'flatten' => true, + 'options' => [], + ] ); // Use callback: function_name format from Meta Box Builder. if ( isset( $field['_callback'] ) && is_callable( $field['_callback'] ) ) { @@ -44,21 +37,14 @@ public static function normalize( $field ) { return $field; } - /** - * Transform field options into the verbose format. - * - * @param array $options Field options. - * - * @return array - */ - public static function transform_options( $options ) { - $transformed = array(); + public static function transform_options( $options ) : array { + $transformed = []; $options = (array) $options; foreach ( $options as $value => $label ) { - $option = is_array( $label ) ? $label : array( + $option = is_array( $label ) ? $label : [ 'label' => (string) $label, 'value' => (string) $value, - ); + ]; if ( isset( $option['label'] ) && isset( $option['value'] ) ) { $transformed[ $option['value'] ] = (object) $option; } diff --git a/vendor/wpmetabox/meta-box/inc/fields/color.php b/vendor/wpmetabox/meta-box/inc/fields/color.php index db8ee4704..c3bf47a7f 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/color.php +++ b/vendor/wpmetabox/meta-box/inc/fields/color.php @@ -1,26 +1,19 @@ false, - 'js_options' => array(), - ) - ); + $field = wp_parse_args( $field, [ + 'alpha_channel' => false, + 'js_options' => [], + ] ); - $field['js_options'] = wp_parse_args( - $field['js_options'], - array( - 'defaultColor' => false, - 'hide' => true, - 'palettes' => true, - ) - ); + $field['js_options'] = wp_parse_args( $field['js_options'], [ + 'defaultColor' => false, + 'hide' => true, + 'palettes' => true, + ] ); $field = parent::normalize( $field ); @@ -65,12 +52,9 @@ public static function normalize( $field ) { */ public static function get_attributes( $field, $value = null ) { $attributes = parent::get_attributes( $field, $value ); - $attributes = wp_parse_args( - $attributes, - array( - 'data-options' => wp_json_encode( $field['js_options'] ), - ) - ); + $attributes = wp_parse_args( $attributes, [ + 'data-options' => wp_json_encode( $field['js_options'] ), + ] ); $attributes['type'] = 'text'; if ( $field['alpha_channel'] ) { diff --git a/vendor/wpmetabox/meta-box/inc/fields/custom-html.php b/vendor/wpmetabox/meta-box/inc/fields/custom-html.php index a0a798715..ad39844af 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/custom-html.php +++ b/vendor/wpmetabox/meta-box/inc/fields/custom-html.php @@ -1,12 +1,8 @@ 'j', 'dd' => 'd', 'oo' => 'z', @@ -29,7 +27,7 @@ class RWMB_Datetime_Field extends RWMB_Input_Field { 'y' => 'y', 'yy' => 'Y', 'o' => 'z', - ); + ]; /** * Translate time format from jQuery UI time picker to PHP date(). @@ -38,7 +36,7 @@ class RWMB_Datetime_Field extends RWMB_Input_Field { * * @var array */ - protected static $time_formats = array( + protected static $time_formats = [ 'H' => 'G', 'HH' => 'H', 'h' => 'g', @@ -48,38 +46,38 @@ class RWMB_Datetime_Field extends RWMB_Input_Field { 'l' => 'u', 'tt' => 'a', 'TT' => 'A', - ); + ]; public static function register_assets() { - // jQueryUI base theme: https://github.com/jquery/jquery-ui/tree/1.12.1/themes/base + // jQueryUI base theme: https://github.com/jquery/jquery-ui/tree/1.13.2/themes/base $url = RWMB_CSS_URL . 'jqueryui'; - wp_register_style( 'jquery-ui-core', "$url/core.css", [], '1.12.1' ); - wp_register_style( 'jquery-ui-theme', "$url/theme.css", [], '1.12.1' ); - wp_register_style( 'jquery-ui-datepicker', "$url/datepicker.css", ['jquery-ui-core', 'jquery-ui-theme'], '1.12.1' ); - wp_register_style( 'jquery-ui-slider', "$url/slider.css", ['jquery-ui-core', 'jquery-ui-theme'], '1.12.1' ); + wp_register_style( 'jquery-ui-core', "$url/core.css", [], '1.13.2' ); + wp_register_style( 'jquery-ui-theme', "$url/theme.css", [], '1.13.2' ); + wp_register_style( 'jquery-ui-datepicker', "$url/datepicker.css", [ 'jquery-ui-core', 'jquery-ui-theme' ], '1.13.2' ); + wp_register_style( 'jquery-ui-slider', "$url/slider.css", [ 'jquery-ui-core', 'jquery-ui-theme' ], '1.13.2' ); // jQueryUI timepicker addon: https://github.com/trentrichardson/jQuery-Timepicker-Addon - wp_register_style( 'jquery-ui-timepicker', "$url/jquery-ui-timepicker-addon.min.css", ['rwmb-date', 'jquery-ui-slider'], '1.6.3' ); + wp_register_style( 'jquery-ui-timepicker', "$url/jquery-ui-timepicker-addon.min.css", [ 'rwmb-date', 'jquery-ui-slider' ], '1.6.3' ); - wp_register_style( 'rwmb-date', RWMB_CSS_URL . 'date.css', ['jquery-ui-datepicker'], RWMB_VER ); + wp_register_style( 'rwmb-date', RWMB_CSS_URL . 'date.css', [ 'jquery-ui-datepicker' ], RWMB_VER ); // Scripts. $url = RWMB_JS_URL . 'jqueryui'; - wp_register_script( 'jquery-ui-timepicker', "$url/jquery-ui-timepicker-addon.min.js", ['jquery-ui-datepicker', 'jquery-ui-slider'], '1.6.3', true ); - wp_register_script( 'jquery-ui-timepicker-slider', "$url/jquery-ui-sliderAccess.js", ['jquery-ui-datepicker', 'jquery-ui-slider'], '0.3', true ); - wp_register_script( 'jquery-ui-timepicker-i18n', "$url/jquery-ui-timepicker-addon-i18n.min.js", ['jquery-ui-timepicker'], '1.6.3', true ); + wp_register_script( 'jquery-ui-timepicker', "$url/jquery-ui-timepicker-addon.min.js", [ 'jquery-ui-datepicker', 'jquery-ui-slider' ], '1.6.3', true ); + wp_register_script( 'jquery-ui-timepicker-slider', "$url/jquery-ui-sliderAccess.js", [ 'jquery-ui-datepicker', 'jquery-ui-slider' ], '0.3', true ); + wp_register_script( 'jquery-ui-timepicker-i18n', "$url/jquery-ui-timepicker-addon-i18n.min.js", [ 'jquery-ui-timepicker' ], '1.6.3', true ); - wp_register_script( 'rwmb-datetime', RWMB_JS_URL . 'datetime.js', ['jquery-ui-datepicker', 'jquery-ui-timepicker-i18n', 'underscore', 'jquery-ui-button', 'jquery-ui-timepicker-slider'], RWMB_VER, true ); - wp_register_script( 'rwmb-date', RWMB_JS_URL . 'date.js', ['jquery-ui-datepicker', 'underscore'], RWMB_VER, true ); - wp_register_script( 'rwmb-time', RWMB_JS_URL . 'time.js', ['jquery-ui-timepicker-i18n', 'jquery-ui-button', 'jquery-ui-timepicker-slider'], RWMB_VER, true ); + wp_register_script( 'rwmb-datetime', RWMB_JS_URL . 'datetime.js', [ 'jquery-ui-datepicker', 'jquery-ui-timepicker-i18n', 'underscore', 'jquery-ui-button', 'jquery-ui-timepicker-slider', 'rwmb' ], RWMB_VER, true ); + wp_register_script( 'rwmb-date', RWMB_JS_URL . 'date.js', [ 'jquery-ui-datepicker', 'underscore', 'rwmb' ], RWMB_VER, true ); + wp_register_script( 'rwmb-time', RWMB_JS_URL . 'time.js', [ 'jquery-ui-timepicker-i18n', 'jquery-ui-button', 'jquery-ui-timepicker-slider', 'rwmb' ], RWMB_VER, true ); - $handles = ['datetime', 'time']; + $handles = [ 'datetime', 'time' ]; $locale = str_replace( '_', '-', get_locale() ); $locale_short = substr( $locale, 0, 2 ); - $data = array( + $data = [ 'locale' => $locale, 'localeShort' => $locale_short, - ); + ]; foreach ( $handles as $handle ) { RWMB_Helpers_Field::localize_script_once( "rwmb-$handle", 'RWMB_' . ucfirst( $handle ), $data ); } @@ -106,19 +104,16 @@ public static function html( $meta, $field ) { $output = ''; if ( $field['timestamp'] ) { - $name = $field['field_name']; - $field = wp_parse_args( - array( - 'field_name' => $name . '[formatted]', - ), - $field - ); - $output .= sprintf( + $name = $field['field_name']; + $field = wp_parse_args( [ 'field_name' => $name . '[formatted]' ], $field ); + $timestamp = $meta['timestamp'] ?? 0; + $output .= sprintf( '', esc_attr( $name . '[timestamp]' ), - isset( $meta['timestamp'] ) ? intval( $meta['timestamp'] ) : '' + (int) $timestamp ); - $meta = isset( $meta['formatted'] ) ? $meta['formatted'] : ''; + + $meta = $meta['formatted'] ?? ''; } $output .= parent::html( $meta, $field ); @@ -144,15 +139,18 @@ public static function value( $new, $old, $post_id, $field ) { if ( $field['timestamp'] ) { if ( is_array( $new ) ) { return $new['timestamp']; - } elseif ( ! is_numeric( $new ) ) { + } + if ( ! is_numeric( $new ) ) { return strtotime( $new ); } return $new; } if ( $field['save_format'] ) { - $date = DateTime::createFromFormat( $field['php_format'], $new ); - $new = false === $date ? $new : $date->format( $field['save_format'] ); + // Fix 'c' and 'r' formats not containing WordPress timezone. + $timezone = in_array( $field['save_format'], [ 'c', 'r' ], true ) ? wp_timezone() : null; + $date = DateTimeImmutable::createFromFormat( $field['php_format'], $new, $timezone ); + return $date === false ? $new : $date->format( $field['save_format'] ); } return $new; @@ -171,11 +169,11 @@ public static function meta( $post_id, $saved, $field ) { $meta = parent::meta( $post_id, $saved, $field ); if ( $field['timestamp'] ) { - return RWMB_Helpers_Array::map( $meta, __CLASS__ . '::from_timestamp', $field ); + return Arr::map( $meta, __CLASS__ . '::from_timestamp', $field ); } if ( $field['save_format'] && $meta ) { - return RWMB_Helpers_Array::map( $meta, __CLASS__ . '::from_save_format', $field ); + return Arr::map( $meta, __CLASS__ . '::from_save_format', $field ); } return $meta; @@ -183,27 +181,29 @@ public static function meta( $post_id, $saved, $field ) { /** * Format meta value if set 'timestamp'. - * - * @param string $meta The meta value. - * @param array $field Field parameters. - * @return array */ - public static function from_timestamp( $meta, $field ) { - return array( - 'timestamp' => $meta ? $meta : null, + public static function from_timestamp( $meta, array $field ): array { + return [ + 'timestamp' => $meta ?: null, 'formatted' => $meta ? gmdate( $field['php_format'], intval( $meta ) ) : '', - ); + ]; } /** * Transform meta value from save format to the JS format. - * - * @param string $meta The meta value. - * @param array $field Field parameters. - * @return array */ - public static function from_save_format( $meta, $field ) { - $date = DateTime::createFromFormat( $field['save_format'], $meta ); + public static function from_save_format( $meta, array $field ): string { + $formats = array_merge( + [ + $field['save_format'] => $field['save_format'], + ], + [ + 'c' => DateTimeInterface::ATOM, + 'r' => DateTimeInterface::RFC2822, + ] + ); + $format = $formats[ $field['save_format'] ]; + $date = DateTimeImmutable::createFromFormat( $format, $meta ); return false === $date ? $meta : $date->format( $field['php_format'] ); } @@ -214,46 +214,34 @@ public static function from_save_format( $meta, $field ) { * @return array */ public static function normalize( $field ) { - $field = wp_parse_args( - $field, - array( - 'timestamp' => false, - 'inline' => false, - 'js_options' => array(), - 'save_format' => '', - 'autocomplete' => 'off', - ) - ); + $field = wp_parse_args( $field, [ + 'timestamp' => false, + 'inline' => false, + 'js_options' => [], + 'save_format' => '', + 'autocomplete' => 'off', + ] ); // Deprecate 'format', but keep it for backward compatible. // Use 'js_options' instead. - $field['js_options'] = wp_parse_args( - $field['js_options'], - array( - 'timeFormat' => 'HH:mm', - 'separator' => ' ', - 'dateFormat' => empty( $field['format'] ) ? 'yy-mm-dd' : $field['format'], - 'showButtonPanel' => true, - 'changeYear' => true, - 'yearRange' => '-100:+100', - 'changeMonth' => true, - 'showButtonPanel' => true, - 'oneLine' => true, - 'controlType' => 'select', // select or slider - 'addSliderAccess' => true, - 'sliderAccessArgs' => [ - 'touchonly' => true, // To show sliderAccess only on touch devices - ], - ) - ); + $field['js_options'] = wp_parse_args( $field['js_options'], [ + 'timeFormat' => 'HH:mm', + 'separator' => ' ', + 'dateFormat' => $field['format'] ?? 'yy-mm-dd', + 'showButtonPanel' => true, + 'changeYear' => true, + 'yearRange' => '-100:+100', + 'changeMonth' => true, + 'oneLine' => true, + 'controlType' => 'select', // select or slider + 'addSliderAccess' => true, + 'sliderAccessArgs' => [ + 'touchonly' => true, // To show sliderAccess only on touch devices + ], + ] ); if ( $field['inline'] ) { - $field['js_options'] = wp_parse_args( - $field['js_options'], - array( - 'altFieldTimeOnly' => false, - ) - ); + $field['js_options'] = wp_parse_args( $field['js_options'], [ 'altFieldTimeOnly' => false ] ); } $field['php_format'] = static::get_php_format( $field['js_options'] ); @@ -273,12 +261,7 @@ public static function normalize( $field ) { */ public static function get_attributes( $field, $value = null ) { $attributes = parent::get_attributes( $field, $value ); - $attributes = wp_parse_args( - $attributes, - array( - 'data-options' => wp_json_encode( $field['js_options'] ), - ) - ); + $attributes = wp_parse_args( $attributes, [ 'data-options' => wp_json_encode( $field['js_options'] ) ] ); $attributes['type'] = 'text'; return $attributes; @@ -286,13 +269,9 @@ public static function get_attributes( $field, $value = null ) { /** * Returns a date() compatible format string from the JavaScript format. - * * @link http://www.php.net/manual/en/function.date.php - * @param array $js_options JavaScript options. - * - * @return string */ - protected static function get_php_format( $js_options ) { + protected static function get_php_format( array $js_options ): string { return strtr( $js_options['dateFormat'], self::$date_formats ) . $js_options['separator'] . strtr( $js_options['timeFormat'], self::$time_formats ); @@ -312,10 +291,10 @@ public static function format_single_value( $field, $value, $args, $post_id ) { if ( $field['timestamp'] ) { $value = self::from_timestamp( $value, $field ); } else { - $value = array( + $value = [ 'timestamp' => strtotime( $value ), 'formatted' => $value, - ); + ]; } return empty( $args['format'] ) ? $value['formatted'] : gmdate( $args['format'], $value['timestamp'] ); } diff --git a/vendor/wpmetabox/meta-box/inc/fields/divider.php b/vendor/wpmetabox/meta-box/inc/fields/divider.php index 545b6ed53..c8b8a61ee 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/divider.php +++ b/vendor/wpmetabox/meta-box/inc/fields/divider.php @@ -1,43 +1,20 @@ "; } - /** - * Show end HTML markup for fields. - * - * @param mixed $meta Meta value. - * @param array $field Field parameters. - * - * @return string - */ - public static function end_html( $meta, $field ) { + public static function end_html( array $field ) : string { return ''; } } diff --git a/vendor/wpmetabox/meta-box/inc/fields/fieldset-text.php b/vendor/wpmetabox/meta-box/inc/fields/fieldset-text.php index 751f3889b..fe9b921e5 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/fieldset-text.php +++ b/vendor/wpmetabox/meta-box/inc/fields/fieldset-text.php @@ -1,19 +1,12 @@ %s

                    '; foreach ( $field['options'] as $key => $label ) { @@ -39,25 +32,11 @@ public static function html( $meta, $field ) { return $out; } - /** - * Do not show field description. - * - * @param array $field Field parameters. - * - * @return string - */ - public static function input_description( $field ) { + protected static function input_description( array $field ) : string { return ''; } - /** - * Do not show field description. - * - * @param array $field Field parameters. - * - * @return string - */ - public static function label_description( $field ) { + protected static function label_description( array $field ) : string { return ''; } diff --git a/vendor/wpmetabox/meta-box/inc/fields/file-input.php b/vendor/wpmetabox/meta-box/inc/fields/file-input.php index c2c055e61..2ce150512 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/file-input.php +++ b/vendor/wpmetabox/meta-box/inc/fields/file-input.php @@ -1,12 +1,8 @@ esc_html__( 'Select File', 'meta-box' ), - ) - ); + wp_enqueue_style( 'rwmb-file-input', RWMB_CSS_URL . 'file-input.css', [], RWMB_VER ); + wp_enqueue_script( 'rwmb-file-input', RWMB_JS_URL . 'file-input.js', [ 'jquery' ], RWMB_VER, true ); + RWMB_Helpers_Field::localize_script_once( 'rwmb-file-input', 'rwmbFileInput', [ + 'frameTitle' => esc_html__( 'Select File', 'meta-box' ), + ] ); } /** @@ -47,7 +39,7 @@ public static function html( $meta, $field ) { %s %s
                    ', - in_array( $file_ext, $extensions ) ? '' : 'rwmb-file-input-hidden', + in_array( $file_ext, $extensions, true ) ? '' : 'rwmb-file-input-hidden', $meta, self::render_attributes( $attributes ), esc_html__( 'Select', 'meta-box' ), diff --git a/vendor/wpmetabox/meta-box/inc/fields/file-upload.php b/vendor/wpmetabox/meta-box/inc/fields/file-upload.php index f86b53ce4..5c2099806 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/file-upload.php +++ b/vendor/wpmetabox/meta-box/inc/fields/file-upload.php @@ -1,21 +1,14 @@ 0, - ) - ); + $field = wp_parse_args( $field, [ + 'max_file_size' => 0, + ] ); - $field['js_options'] = wp_parse_args( - $field['js_options'], - array( - 'maxFileSize' => $field['max_file_size'], - ) - ); + $field['js_options'] = wp_parse_args( $field['js_options'], [ + 'maxFileSize' => $field['max_file_size'], + ] ); return $field; } @@ -49,6 +36,6 @@ public static function normalize( $field ) { */ public static function print_templates() { parent::print_templates(); - require_once RWMB_INC_DIR . 'templates/upload.php'; + require RWMB_INC_DIR . 'templates/upload.php'; } } diff --git a/vendor/wpmetabox/meta-box/inc/fields/file.php b/vendor/wpmetabox/meta-box/inc/fields/file.php index e79a8e353..e0f5307f3 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/file.php +++ b/vendor/wpmetabox/meta-box/inc/fields/file.php @@ -1,66 +1,46 @@ . - * - * @package Meta Box - */ +defined( 'ABSPATH' ) || die; /** - * File field class which uses HTML to upload file. + * The file upload file which allows users to upload files via the default HTML . */ class RWMB_File_Field extends RWMB_Field { - /** - * Enqueue scripts and styles. - */ public static function admin_enqueue_scripts() { - wp_enqueue_style( 'rwmb-file', RWMB_CSS_URL . 'file.css', array(), RWMB_VER ); - wp_enqueue_script( 'rwmb-file', RWMB_JS_URL . 'file.js', array( 'jquery-ui-sortable' ), RWMB_VER, true ); - - RWMB_Helpers_Field::localize_script_once( - 'rwmb-file', - 'rwmbFile', - array( - // Translators: %d is the number of files in singular form. - 'maxFileUploadsSingle' => __( 'You may only upload maximum %d file', 'meta-box' ), - // Translators: %d is the number of files in plural form. - 'maxFileUploadsPlural' => __( 'You may only upload maximum %d files', 'meta-box' ), - ) - ); + wp_enqueue_style( 'rwmb-file', RWMB_CSS_URL . 'file.css', [], RWMB_VER ); + wp_enqueue_script( 'rwmb-file', RWMB_JS_URL . 'file.js', [ 'jquery-ui-sortable' ], RWMB_VER, true ); + + RWMB_Helpers_Field::localize_script_once( 'rwmb-file', 'rwmbFile', [ + // Translators: %d is the number of files in singular form. + 'maxFileUploadsSingle' => __( 'You may only upload maximum %d file', 'meta-box' ), + // Translators: %d is the number of files in plural form. + 'maxFileUploadsPlural' => __( 'You may only upload maximum %d files', 'meta-box' ), + ] ); } - /** - * Add custom actions. - */ public static function add_actions() { - add_action( 'post_edit_form_tag', array( __CLASS__, 'post_edit_form_tag' ) ); - add_action( 'wp_ajax_rwmb_delete_file', array( __CLASS__, 'ajax_delete_file' ) ); + add_action( 'post_edit_form_tag', [ __CLASS__, 'post_edit_form_tag' ] ); + add_action( 'wp_ajax_rwmb_delete_file', [ __CLASS__, 'ajax_delete_file' ] ); } - /** - * Add data encoding type for file uploading - */ public static function post_edit_form_tag() { echo ' enctype="multipart/form-data"'; } - /** - * Ajax callback for deleting files. - */ public static function ajax_delete_file() { - $request = rwmb_request(); + $request = rwmb_request(); $field_id = (string) $request->filter_post( 'field_id' ); - $type = false !== strpos( $request->filter_post( 'field_name' ), '[' ) ? 'child' : 'top'; + $type = str_contains( $request->filter_post( 'field_name' ), '[' ) ? 'child' : 'top'; check_ajax_referer( "rwmb-delete-file_{$field_id}" ); if ( 'child' === $type ) { $field_group = explode( '[', $request->filter_post( 'field_name' ) ); - $field_id = $field_group[0]; //this is top parent field_id + $field_id = $field_group[0]; // This is top parent field_id. } // Make sure the file to delete is in the custom field. $attachment = $request->post( 'attachment_id' ); $object_id = $request->filter_post( 'object_id' ); $object_type = (string) $request->filter_post( 'object_type' ); - $field = rwmb_get_field_settings( $field_id, array( 'object_type' => $object_type ), $object_id ); + $field = rwmb_get_field_settings( $field_id, [ 'object_type' => $object_type ], $object_id ); $field_value = self::raw_meta( $object_id, $field ); if ( ! self::in_array_r( $attachment, $field_value ) ) { @@ -82,10 +62,8 @@ public static function ajax_delete_file() { /** * Recursively search needle in haystack - * - * @return boolean */ - protected static function in_array_r( $needle, $haystack, $strict = false ) { + protected static function in_array_r( $needle, $haystack, $strict = false ) : bool { foreach ( $haystack as $item ) { if ( ( $strict ? $item === $needle : $item == $needle ) || ( is_array( $item ) && self::in_array_r( $needle, $item, $strict ) ) ) { return true; @@ -153,13 +131,13 @@ public static function html( $meta, $field ) { * @return string */ protected static function get_uploaded_files( $files, $field ) { - $delete_nonce = wp_create_nonce( "rwmb-delete-file_{$field['id']}" ); - $output = ''; + $delete_nonce = wp_create_nonce( "rwmb-delete-file_{$field['id']}" ); + $output = ''; foreach ( (array) $files as $k => $file ) { // Ignore deleted files (if users accidentally deleted files or uses `force_delete` without saving post). if ( get_attached_file( $file ) || $field['upload_dir'] ) { - $output .= self::call( $field, 'file_html', $file, $k ); + $output .= static::file_html( $file, $k, $field ); } } @@ -196,7 +174,7 @@ protected static function file_html( $file, $index, $field ) { $data = self::file_info_custom_dir( $file, $field ); } else { $data = [ - 'icon' => wp_get_attachment_image( $file, [48, 64], true ), + 'icon' => wp_get_attachment_image( $file, [ 48, 64 ], true ), 'name' => basename( get_attached_file( $file ) ), 'url' => wp_get_attachment_url( $file ), 'title' => get_the_title( $file ), @@ -234,25 +212,18 @@ protected static function file_html( $file, $index, $field ) { ); } - /** - * Get file data uploaded to custom directory. - * - * @param string $file URL to uploaded file. - * @param array $field Field settings. - * @return string - */ - protected static function file_info_custom_dir( $file, $field ) { + protected static function file_info_custom_dir( string $file, array $field ) : array { $path = wp_normalize_path( trailingslashit( $field['upload_dir'] ) . basename( $file ) ); $ext = pathinfo( $path, PATHINFO_EXTENSION ); $icon_url = wp_mime_type_icon( wp_ext2type( $ext ) ); - $data = array( + $data = [ 'icon' => '', 'name' => basename( $path ), 'path' => $path, 'url' => $file, 'title' => preg_replace( '/\.[^.]+$/', '', basename( $path ) ), 'edit_link' => '', - ); + ]; return $data; } @@ -267,7 +238,7 @@ protected static function file_info_custom_dir( $file, $field ) { * @return array|mixed */ public static function value( $new, $old, $post_id, $field ) { - $input = isset( $field['index'] ) ? $field['index'] : $field['input_name']; + $input = $field['index'] ?? $field['input_name']; // @codingStandardsIgnoreLine if ( empty( $input ) || empty( $_FILES[ $input ] ) ) { @@ -304,13 +275,12 @@ public static function clone_value( $new, $old, $object_id, $field, $data_source $data_source = $_POST; } - // @codingStandardsIgnoreLine - $indexes = isset( $data_source[ "_index_{$field['id']}" ] ) ? $data_source[ "_index_{$field['id']}" ] : array(); + $indexes = $data_source[ "_index_{$field['id']}" ] ?? []; foreach ( $indexes as $key => $index ) { $field['index'] = $index; - $old_value = isset( $old[ $key ] ) ? $old[ $key ] : array(); - $value = isset( $new[ $key ] ) ? $new[ $key ] : array(); + $old_value = $old[ $key ] ?? []; + $value = $new[ $key ] ?? []; $value = self::value( $value, $old_value, $object_id, $field ); $new[ $key ] = self::filter( 'sanitize', $value, $field, $old_value, $object_id ); } @@ -345,7 +315,7 @@ protected static function transform( $input_name ) { foreach ( $list as $index => $value ) { $file_key = "{$input_name}_{$index}"; if ( ! isset( $_FILES[ $file_key ] ) ) { - $_FILES[ $file_key ] = array(); + $_FILES[ $file_key ] = []; } $_FILES[ $file_key ][ $key ] = $value; } @@ -388,14 +358,14 @@ public static function normalize( $field ) { * * @return mixed Full info of uploaded files */ - public static function get_value( $field, $args = array(), $post_id = null ) { + public static function get_value( $field, $args = [], $post_id = null ) { $value = parent::get_value( $field, $args, $post_id ); if ( ! $field['clone'] ) { - $value = self::call( 'files_info', $field, $value, $args ); + $value = static::files_info( $field, $value, $args ); } else { - $return = array(); + $return = []; foreach ( $value as $subvalue ) { - $return[] = self::call( 'files_info', $field, $subvalue, $args ); + $return[] = static::files_info( $field, $subvalue, $args ); } $value = $return; } @@ -414,9 +384,9 @@ public static function get_value( $field, $args = array(), $post_id = null ) { * @return array */ public static function files_info( $field, $files, $args ) { - $return = array(); + $return = []; foreach ( (array) $files as $file ) { - $info = self::call( $field, 'file_info', $file, $args ); + $info = static::file_info( $file, $args, $field ); if ( $info ) { $return[ $file ] = $info; } @@ -433,8 +403,8 @@ public static function files_info( $field, $files, $args ) { * * @return array|bool False if file not found. Array of (id, name, path, url) on success. */ - public static function file_info( $file, $args = array(), $field = array() ) { - if ( $field['upload_dir'] ) { + public static function file_info( $file, $args = [], $field = [] ) { + if ( ! empty( $field['upload_dir'] ) ) { return self::file_info_custom_dir( $file, $field ); } @@ -444,13 +414,13 @@ public static function file_info( $file, $args = array(), $field = array() ) { } return wp_parse_args( - array( + [ 'ID' => $file, 'name' => basename( $path ), 'path' => $path, 'url' => wp_get_attachment_url( $file ), 'title' => get_the_title( $file ), - ), + ], wp_get_attachment_metadata( $file ) ); } @@ -498,7 +468,7 @@ public static function handle_upload_custom_dir( $file_id, $field ) { // Make sure upload dir is inside WordPress. $upload_dir = wp_normalize_path( untrailingslashit( $field['upload_dir'] ) ); $root = wp_normalize_path( untrailingslashit( ABSPATH ) ); - if ( 0 !== strpos( $upload_dir, $root ) ) { + if ( ! str_starts_with( $upload_dir, $root ) ) { return; } @@ -514,13 +484,7 @@ public static function handle_upload_custom_dir( $file_id, $field ) { return empty( $file_info['url'] ) ? null : $file_info['url']; } - /** - * Convert a path to an URL. - * - * @param string $path Full path to a file or a directory. - * @return string URL to the file or directory. - */ - public static function convert_path_to_url( $path ) { + public static function convert_path_to_url( string $path ) : string { $path = wp_normalize_path( untrailingslashit( $path ) ); $root = wp_normalize_path( untrailingslashit( ABSPATH ) ); $relative_path = str_replace( $root, '', $path ); diff --git a/vendor/wpmetabox/meta-box/inc/fields/heading.php b/vendor/wpmetabox/meta-box/inc/fields/heading.php index 2b3040246..64beb0862 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/heading.php +++ b/vendor/wpmetabox/meta-box/inc/fields/heading.php @@ -1,43 +1,20 @@ %s
                  • ', $attributes, $field['name'] ); } - /** - * Show end HTML markup for fields. - * - * @param mixed $meta Meta value. - * @param array $field Field parameters. - * - * @return string - */ - public static function end_html( $meta, $field ) { + protected static function end_html( array $field ) : string { return self::input_description( $field ); } } diff --git a/vendor/wpmetabox/meta-box/inc/fields/image-advanced.php b/vendor/wpmetabox/meta-box/inc/fields/image-advanced.php index 57a4c2b38..77140bd0d 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/image-advanced.php +++ b/vendor/wpmetabox/meta-box/inc/fields/image-advanced.php @@ -1,21 +1,14 @@ 'thumbnail', - ) - ); + $field = wp_parse_args( $field, [ + 'image_size' => 'thumbnail', + ] ); $field = parent::normalize( $field ); - $field['js_options'] = wp_parse_args( - $field['js_options'], - array( - 'imageSize' => $field['image_size'], - ) - ); + $field['js_options'] = wp_parse_args( $field['js_options'], [ + 'imageSize' => $field['image_size'], + ] ); return $field; } @@ -51,10 +38,10 @@ public static function normalize( $field ) { * * @param array $field Field parameters. * @param array $args Additional arguments. - * @param null $post_id Post ID. + * @param ?int $post_id Post ID. * @return mixed */ - public static function get_value( $field, $args = array(), $post_id = null ) { + public static function get_value( $field, $args = [], $post_id = null ) { return RWMB_Image_Field::get_value( $field, $args, $post_id ); } @@ -67,7 +54,7 @@ public static function get_value( $field, $args = array(), $post_id = null ) { * * @return array|bool False if file not found. Array of image info on success. */ - public static function file_info( $file, $args = array(), $field = array() ) { + public static function file_info( $file, $args = [], $field = [] ) { return RWMB_Image_Field::file_info( $file, $args, $field ); } @@ -75,7 +62,7 @@ public static function file_info( $file, $args = array(), $field = array() ) { * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. * * @param array $field Field parameters. - * @param string $value The value. + * @param array $value The value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * @@ -90,6 +77,6 @@ public static function format_single_value( $field, $value, $args, $post_id ) { */ public static function print_templates() { parent::print_templates(); - require_once RWMB_INC_DIR . 'templates/image-advanced.php'; + require RWMB_INC_DIR . 'templates/image-advanced.php'; } } diff --git a/vendor/wpmetabox/meta-box/inc/fields/image-select.php b/vendor/wpmetabox/meta-box/inc/fields/image-select.php index 0c942e7b4..12e0e839b 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/image-select.php +++ b/vendor/wpmetabox/meta-box/inc/fields/image-select.php @@ -1,20 +1,13 @@ $image ) { $attributes = self::get_attributes( $field, $value ); - $html[] = sprintf( + $html[] = sprintf( '', $image, self::render_attributes( $attributes ), @@ -48,6 +41,7 @@ public static function html( $meta, $field ) { */ public static function normalize( $field ) { $field = parent::normalize( $field ); + $field['options'] = $field['options'] ?? []; $field['field_name'] .= $field['multiple'] ? '[]' : ''; return $field; @@ -61,13 +55,14 @@ public static function normalize( $field ) { * @return array */ public static function get_attributes( $field, $value = null ) { - $attributes = parent::get_attributes( $field, $value ); + $attributes = parent::get_attributes( $field, $value ); $attributes['id'] = false; $attributes['type'] = $field['multiple'] ? 'checkbox' : 'radio'; $attributes['value'] = $value; return $attributes; } + /** * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. * diff --git a/vendor/wpmetabox/meta-box/inc/fields/image-upload.php b/vendor/wpmetabox/meta-box/inc/fields/image-upload.php index 7484f1a38..9ecd045e2 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/image-upload.php +++ b/vendor/wpmetabox/meta-box/inc/fields/image-upload.php @@ -1,21 +1,14 @@ . - * - * @package Meta Box - */ +defined( 'ABSPATH' ) || die; /** - * Image field class which uses to upload. + * The image field which uploads images via HTML . */ class RWMB_Image_Field extends RWMB_File_Field { - /** - * Enqueue scripts and styles. - */ public static function admin_enqueue_scripts() { parent::admin_enqueue_scripts(); wp_enqueue_media(); - wp_enqueue_style( 'rwmb-image', RWMB_CSS_URL . 'image.css', array(), RWMB_VER ); + wp_enqueue_style( 'rwmb-image', RWMB_CSS_URL . 'image.css', [], RWMB_VER ); } /** @@ -35,6 +28,8 @@ protected static function file_html( $file, $index, $field ) { $edit_link = sprintf( '', $edit_link ); } + $attachment_image = is_numeric( $file ) ? wp_get_attachment_image( $file, $field['image_size'] ) : ''; + return sprintf( '
                  • %s
                    @@ -45,7 +40,7 @@ protected static function file_html( $file, $index, $field ) {
                  • ', - wp_get_attachment_image( $file, $field['image_size'] ), + $attachment_image, $edit_link, esc_attr( $file ), esc_attr( $attributes['name'] ), @@ -62,19 +57,9 @@ protected static function file_html( $file, $index, $field ) { * @return array */ public static function normalize( $field ) { - $field = parent::normalize( $field ); - $field = wp_parse_args( - $field, - array( - 'image_size' => 'thumbnail', - ) - ); - $field['attributes'] = wp_parse_args( - $field['attributes'], - array( - 'accept' => 'image/*', - ) - ); + $field = parent::normalize( $field ); + $field = wp_parse_args( $field, [ 'image_size' => 'thumbnail' ] ); + $field['attributes'] = wp_parse_args( $field['attributes'], [ 'accept' => 'image/*' ] ); return $field; } @@ -108,21 +93,19 @@ public static function format_single_value( $field, $value, $args, $post_id ) { * * @return array|bool False if file not found. Array of image info on success. */ - public static function file_info( $file, $args = array(), $field = array() ) { + public static function file_info( $file, $args = [], $field = [] ) { $path = get_attached_file( $file ); if ( ! $path ) { return false; } - $args = wp_parse_args( - $args, - array( - 'size' => 'thumbnail', - ) - ); - $image = wp_get_attachment_image_src( $file, $args['size'] ); + $args = wp_parse_args( $args, [ 'size' => 'thumbnail' ] ); + $image = wp_get_attachment_image_src( $file, $args['size'] ); + if ( ! $image ) { + return false; + } $attachment = get_post( $file ); - $info = array( + $info = [ 'ID' => $file, 'name' => basename( $path ), 'path' => $path, @@ -132,7 +115,7 @@ public static function file_info( $file, $args = array(), $field = array() ) { 'caption' => $attachment->post_excerpt, 'description' => $attachment->post_content, 'alt' => get_post_meta( $file, '_wp_attachment_image_alt', true ), - ); + ]; if ( function_exists( 'wp_get_attachment_image_srcset' ) ) { $info['srcset'] = wp_get_attachment_image_srcset( $file, $args['size'] ); } @@ -158,7 +141,7 @@ protected static function get_image_meta_data( $attachment_id ) { return $metadata; } - $dir_url = dirname( wp_get_attachment_url( $attachment_id ) ); + $dir_url = dirname( wp_get_attachment_url( $attachment_id ) ); foreach ( $metadata['sizes'] as &$size ) { $size['url'] = "{$dir_url}/{$size['file']}"; } diff --git a/vendor/wpmetabox/meta-box/inc/fields/input-list.php b/vendor/wpmetabox/meta-box/inc/fields/input-list.php index 4531bc648..52f977380 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/input-list.php +++ b/vendor/wpmetabox/meta-box/inc/fields/input-list.php @@ -1,20 +1,13 @@ ', + '
                    ', $field['collapse'] ? ' rwmb-collapse' : '', $field['inline'] ? ' rwmb-inline' : '' ); $output .= $walker->walk( $options, $field['flatten'] ? -1 : 0 ); - $output .= ''; + $output .= '
                    '; return $output; } @@ -49,14 +42,11 @@ public static function normalize( $field ) { $field = $field['multiple'] ? RWMB_Multiple_Values_Field::normalize( $field ) : $field; $field = RWMB_Input_Field::normalize( $field ); $field = parent::normalize( $field ); - $field = wp_parse_args( - $field, - array( - 'collapse' => true, - 'inline' => null, - 'select_all_none' => false, - ) - ); + $field = wp_parse_args( $field, [ + 'collapse' => true, + 'inline' => null, + 'select_all_none' => false, + ] ); $field['flatten'] = $field['multiple'] ? $field['flatten'] : true; $field['inline'] = ! $field['multiple'] && ! isset( $field['inline'] ) ? true : $field['inline']; diff --git a/vendor/wpmetabox/meta-box/inc/fields/input.php b/vendor/wpmetabox/meta-box/inc/fields/input.php index 03060f1e7..1d5440f52 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/input.php +++ b/vendor/wpmetabox/meta-box/inc/fields/input.php @@ -1,19 +1,12 @@ fields. - * - * @package Meta Box - */ +defined( 'ABSPATH' ) || die; /** - * Abstract input field class. + * The abstract input field which is used for all fields. */ abstract class RWMB_Input_Field extends RWMB_Field { - /** - * Enqueue scripts and styles. - */ public static function admin_enqueue_scripts() { - wp_enqueue_style( 'rwmb-input', RWMB_CSS_URL . 'input.css', '', RWMB_VER ); + wp_enqueue_style( 'rwmb-input', RWMB_CSS_URL . 'input.css', [], RWMB_VER ); } /** @@ -34,11 +27,11 @@ public static function html( $meta, $field ) { $output .= '' . $field['prepend'] . ''; } - $attributes = self::call( 'get_attributes', $field, $meta ); + $attributes = static::get_attributes( $field, $meta ); $output .= sprintf( '%s', self::render_attributes( $attributes ), self::datalist( $field ) ); if ( $field['append'] ) { - $output .= '' . $field['append']. ''; + $output .= '' . $field['append'] . ''; } if ( $field['prepend'] || $field['append'] ) { @@ -56,27 +49,21 @@ public static function html( $meta, $field ) { */ public static function normalize( $field ) { $field = parent::normalize( $field ); - $field = wp_parse_args( - $field, - array( - 'autocomplete' => false, - 'datalist' => false, - 'readonly' => false, - 'maxlength' => false, - 'minlength' => false, - 'pattern' => false, - 'prepend' => '', - 'append' => '', - ) - ); + $field = wp_parse_args( $field, [ + 'autocomplete' => false, + 'datalist' => false, + 'readonly' => false, + 'maxlength' => false, + 'minlength' => false, + 'pattern' => false, + 'prepend' => '', + 'append' => '', + ] ); if ( $field['datalist'] ) { - $field['datalist'] = wp_parse_args( - $field['datalist'], - array( - 'id' => $field['id'] . '_list', - 'options' => array(), - ) - ); + $field['datalist'] = wp_parse_args( $field['datalist'], [ + 'id' => $field['id'] . '_list', + 'options' => [], + ] ); } return $field; } @@ -90,20 +77,17 @@ public static function normalize( $field ) { */ public static function get_attributes( $field, $value = null ) { $attributes = parent::get_attributes( $field, $value ); - $attributes = wp_parse_args( - $attributes, - array( - 'autocomplete' => $field['autocomplete'], - 'list' => $field['datalist'] ? $field['datalist']['id'] : false, - 'readonly' => $field['readonly'], - 'maxlength' => $field['maxlength'], - 'minlength' => $field['minlength'], - 'pattern' => $field['pattern'], - 'value' => $value, - 'placeholder' => $field['placeholder'], - 'type' => $field['type'], - ) - ); + $attributes = wp_parse_args( $attributes, [ + 'autocomplete' => $field['autocomplete'], + 'list' => $field['datalist'] ? $field['datalist']['id'] : false, + 'readonly' => $field['readonly'], + 'maxlength' => $field['maxlength'], + 'minlength' => $field['minlength'], + 'pattern' => $field['pattern'], + 'value' => $value, + 'placeholder' => $field['placeholder'], + 'type' => $field['type'], + ] ); if ( isset( $field['size'] ) ) { $attributes['size'] = $field['size']; } @@ -111,13 +95,7 @@ public static function get_attributes( $field, $value = null ) { return $attributes; } - /** - * Create datalist, if any. - * - * @param array $field Field parameters. - * @return string - */ - protected static function datalist( $field ) { + protected static function datalist( array $field ) : string { if ( empty( $field['datalist'] ) ) { return ''; } diff --git a/vendor/wpmetabox/meta-box/inc/fields/key-value.php b/vendor/wpmetabox/meta-box/inc/fields/key-value.php index 50dbf7c47..7fe4baaaa 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/key-value.php +++ b/vendor/wpmetabox/meta-box/inc/fields/key-value.php @@ -1,16 +1,12 @@ {$field['desc']}

                    " : ''; if ( empty( $field['name'] ) ) { @@ -64,14 +52,7 @@ public static function begin_html( $meta, $field ) { ); } - /** - * Do not show field description. - * - * @param array $field Field parameters. - * - * @return string - */ - public static function input_description( $field ) { + protected static function input_description( array $field ) : string { return ''; } @@ -108,13 +89,10 @@ public static function normalize( $field ) { $field = parent::normalize( $field ); $field['attributes']['type'] = 'text'; - $field['placeholder'] = wp_parse_args( - (array) $field['placeholder'], - array( - 'key' => __( 'Key', 'meta-box' ), - 'value' => __( 'Value', 'meta-box' ), - ) - ); + $field['placeholder'] = wp_parse_args( (array) $field['placeholder'], [ + 'key' => __( 'Key', 'meta-box' ), + 'value' => __( 'Value', 'meta-box' ), + ] ); return $field; } diff --git a/vendor/wpmetabox/meta-box/inc/fields/map.php b/vendor/wpmetabox/meta-box/inc/fields/map.php index 83b032632..8b33365cb 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/map.php +++ b/vendor/wpmetabox/meta-box/inc/fields/map.php @@ -1,61 +1,32 @@ $field['api_key'], - 'language' => $field['language'], - 'libraries' => 'places' - ), - 'https://maps.google.com/maps/api/js' - ); + $google_maps_url = add_query_arg( [ + 'key' => $field['api_key'], + 'language' => $field['language'], + 'libraries' => 'places', + ], 'https://maps.google.com/maps/api/js' ); /** * Allows developers load more libraries via a filter. - * * @link https://developers.google.com/maps/documentation/javascript/libraries */ $google_maps_url = apply_filters( 'rwmb_google_maps_url', $google_maps_url ); - wp_register_script( 'google-maps', esc_url_raw( $google_maps_url ), array(), RWMB_VER, true ); - wp_enqueue_script( - 'rwmb-map', - RWMB_JS_URL . 'map.js', - array( - 'jquery-ui-autocomplete', - 'google-maps', - ), - RWMB_VER, - true - ); - RWMB_Helpers_Field::localize_script_once( - 'rwmb-map', - 'RWMB_Map', - array( - 'no_results_string' => __( 'No results found', 'meta-box' ), - ) - ); + + wp_register_script( 'google-maps', esc_url_raw( $google_maps_url ), [], RWMB_VER, true ); + wp_enqueue_script( 'rwmb-map', RWMB_JS_URL . 'map.js', [ 'jquery-ui-autocomplete', 'google-maps' ], RWMB_VER, true ); + RWMB_Helpers_Field::localize_script_once( 'rwmb-map', 'RWMB_Map', [ + 'no_results_string' => __( 'No results found', 'meta-box' ), + ] ); } /** @@ -99,19 +70,16 @@ public static function html( $meta, $field ) { */ public static function normalize( $field ) { $field = parent::normalize( $field ); - $field = wp_parse_args( - $field, - array( - 'std' => '', - 'address_field' => '', - 'language' => '', - 'region' => '', - - // Default API key, required by Google Maps since June 2016. - // Users should overwrite this key with their own key. - 'api_key' => 'AIzaSyC1mUh87SGFyf133tpZQJa-s96p0tgnraQ', - ) - ); + $field = wp_parse_args( $field, [ + 'std' => '', + 'address_field' => '', + 'language' => '', + 'region' => '', + + // Default API key, required by Google Maps since June 2016. + // Users should overwrite this key with their own key. + 'api_key' => 'AIzaSyC1mUh87SGFyf133tpZQJa-s96p0tgnraQ', + ] ); return $field; } @@ -127,7 +95,7 @@ public static function normalize( $field ) { * * @return mixed Array(latitude, longitude, zoom) */ - public static function get_value( $field, $args = array(), $post_id = null ) { + public static function get_value( $field, $args = [], $post_id = null ) { $value = parent::get_value( $field, $args, $post_id ); list( $latitude, $longitude, $zoom ) = explode( ',', $value . ',,' ); return compact( 'latitude', 'longitude', 'zoom' ); @@ -143,49 +111,43 @@ public static function get_value( $field, $args = array(), $post_id = null ) { * * @return string HTML output of the field */ - public static function the_value( $field, $args = array(), $post_id = null ) { + public static function the_value( $field, $args = [], $post_id = null ) { $value = parent::get_value( $field, $args, $post_id ); - $args = wp_parse_args( - $args, - array( - 'api_key' => isset( $field['api_key'] ) ? $field['api_key'] : '', - ) - ); + $args = wp_parse_args( $args, [ + 'api_key' => $field['api_key'] ?? '', + ] ); return self::render_map( $value, $args ); } /** * Render a map in the frontend. * - * @param array $location The [latitude, longitude[, zoom]] location. - * @param array $args Additional arguments for the map. + * @param string $location The "latitude,longitude[,zoom]" location. + * @param array $args Additional arguments for the map. * * @return string */ - public static function render_map( $location, $args = array() ) { + public static function render_map( $location, $args = [] ) { list( $latitude, $longitude, $zoom ) = explode( ',', $location . ',,' ); if ( ! $latitude || ! $longitude ) { return ''; } - $args = wp_parse_args( - $args, - array( - 'latitude' => $latitude, - 'longitude' => $longitude, - 'width' => '100%', - 'height' => '480px', - 'marker' => true, // Display marker? - 'marker_title' => '', // Marker title, when hover. - 'info_window' => '', // Content of info window (when click on marker). HTML allowed. - 'js_options' => array(), - 'zoom' => $zoom, - - // Default API key, required by Google Maps since June 2016. - // Users should overwrite this key with their own key. - 'api_key' => 'AIzaSyC1mUh87SGFyf133tpZQJa-s96p0tgnraQ', - ) - ); + $args = wp_parse_args( $args, [ + 'latitude' => $latitude, + 'longitude' => $longitude, + 'width' => '100%', + 'height' => '480px', + 'marker' => true, // Display marker? + 'marker_title' => '', // Marker title, when hover. + 'info_window' => '', // Content of info window (when click on marker). HTML allowed. + 'js_options' => [], + 'zoom' => $zoom, + + // Default API key, required by Google Maps since June 2016. + // Users should overwrite this key with their own key. + 'api_key' => 'AIzaSyC1mUh87SGFyf133tpZQJa-s96p0tgnraQ', + ] ); $google_maps_url = add_query_arg( 'key', $args['api_key'], 'https://maps.google.com/maps/api/js' ); @@ -194,8 +156,8 @@ public static function render_map( $location, $args = array() ) { * @link https://developers.google.com/maps/documentation/javascript/libraries */ $google_maps_url = apply_filters( 'rwmb_google_maps_url', $google_maps_url ); - wp_register_script( 'google-maps', esc_url_raw( $google_maps_url ), array(), RWMB_VER, true ); - wp_enqueue_script( 'rwmb-map-frontend', RWMB_JS_URL . 'map-frontend.js', array( 'google-maps', 'jquery' ), RWMB_VER, true ); + wp_register_script( 'google-maps', esc_url_raw( $google_maps_url ), [], RWMB_VER, true ); + wp_enqueue_script( 'rwmb-map-frontend', RWMB_JS_URL . 'map-frontend.js', [ 'google-maps', 'jquery' ], RWMB_VER, true ); /* * Google Maps options. @@ -203,19 +165,16 @@ public static function render_map( $location, $args = array() ) { * This array will be convert to Javascript Object and pass as map options. * @link https://developers.google.com/maps/documentation/javascript/reference */ - $args['js_options'] = wp_parse_args( - $args['js_options'], - array( - // Default to 'zoom' level set in admin, but can be overwritten. - 'zoom' => $args['zoom'], - - // Map type, see https://developers.google.com/maps/documentation/javascript/reference#MapTypeId. - 'mapTypeId' => 'ROADMAP', - - // Open Info Window - 'openInfoWindow' => false, - ) - ); + $args['js_options'] = wp_parse_args( $args['js_options'], [ + // Default to 'zoom' level set in admin, but can be overwritten. + 'zoom' => $args['zoom'], + + // Map type, see https://developers.google.com/maps/documentation/javascript/reference#MapTypeId. + 'mapTypeId' => 'ROADMAP', + + // Open Info Window + 'openInfoWindow' => false, + ] ); $output = sprintf( '
                    ', diff --git a/vendor/wpmetabox/meta-box/inc/fields/media.php b/vendor/wpmetabox/meta-box/inc/fields/media.php index 113fe0a9f..a0c3d22bb 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/media.php +++ b/vendor/wpmetabox/meta-box/inc/fields/media.php @@ -1,54 +1,38 @@ apply_filters( 'rwmb_media_add_string', _x( '+ Add Media', 'media', 'meta-box' ) ), - 'single' => apply_filters( 'rwmb_media_single_files_string', _x( ' file', 'media', 'meta-box' ) ), - 'multiple' => apply_filters( 'rwmb_media_multiple_files_string', _x( ' files', 'media', 'meta-box' ) ), - 'remove' => apply_filters( 'rwmb_media_remove_string', _x( 'Remove', 'media', 'meta-box' ) ), - 'edit' => apply_filters( 'rwmb_media_edit_string', _x( 'Edit', 'media', 'meta-box' ) ), - 'view' => apply_filters( 'rwmb_media_view_string', _x( 'View', 'media', 'meta-box' ) ), - 'noTitle' => _x( 'No Title', 'media', 'meta-box' ), - 'loadingUrl' => admin_url( 'images/spinner.gif' ), - 'extensions' => self::get_mime_extensions(), - 'select' => apply_filters( 'rwmb_media_select_string', _x( 'Select Files', 'media', 'meta-box' ) ), - 'or' => apply_filters( 'rwmb_media_or_string', _x( 'or', 'media', 'meta-box' ) ), - 'uploadInstructions' => apply_filters( 'rwmb_media_upload_instructions_string', _x( 'Drop files here to upload', 'media', 'meta-box' ) ), - ) - ); + wp_enqueue_style( 'rwmb-media', RWMB_CSS_URL . 'media.css', [], RWMB_VER ); + wp_enqueue_script( 'rwmb-media', RWMB_JS_URL . 'media.js', [ 'jquery-ui-sortable', 'underscore', 'backbone', 'media-grid' ], RWMB_VER, true ); + + RWMB_Helpers_Field::localize_script_once( 'rwmb-media', 'i18nRwmbMedia', [ + 'add' => apply_filters( 'rwmb_media_add_string', _x( '+ Add Media', 'media', 'meta-box' ) ), + 'single' => apply_filters( 'rwmb_media_single_files_string', _x( ' file', 'media', 'meta-box' ) ), + 'multiple' => apply_filters( 'rwmb_media_multiple_files_string', _x( ' files', 'media', 'meta-box' ) ), + 'remove' => apply_filters( 'rwmb_media_remove_string', _x( 'Remove', 'media', 'meta-box' ) ), + 'edit' => apply_filters( 'rwmb_media_edit_string', _x( 'Edit', 'media', 'meta-box' ) ), + 'view' => apply_filters( 'rwmb_media_view_string', _x( 'View', 'media', 'meta-box' ) ), + 'noTitle' => _x( 'No Title', 'media', 'meta-box' ), + 'loadingUrl' => admin_url( 'images/spinner.gif' ), + 'extensions' => static::get_mime_extensions(), + 'select' => apply_filters( 'rwmb_media_select_string', _x( 'Select Files', 'media', 'meta-box' ) ), + 'or' => apply_filters( 'rwmb_media_or_string', _x( 'or', 'media', 'meta-box' ) ), + 'uploadInstructions' => apply_filters( 'rwmb_media_upload_instructions_string', _x( 'Drop files here to upload', 'media', 'meta-box' ) ), + ] ); } - /** - * Add actions. - */ public static function add_actions() { - $args = func_get_args(); - $field = reset( $args ); - add_action( 'print_media_templates', array( RWMB_Helpers_Field::get_class( $field ), 'print_templates' ) ); + add_action( 'print_media_templates', [ get_called_class(), 'print_templates' ] ); } /** @@ -89,7 +73,7 @@ public static function meta( $post_id, $saved, $field ) { * @return string */ public static function html( $meta, $field ) { - $attributes = self::call( 'get_attributes', $field, $meta ); + $attributes = static::get_attributes( $field, $meta ); $html = sprintf( '', @@ -109,29 +93,23 @@ public static function html( $meta, $field ) { */ public static function normalize( $field ) { $field = parent::normalize( $field ); - $field = wp_parse_args( - $field, - array( - 'std' => array(), - 'mime_type' => '', - 'max_file_uploads' => 0, - 'force_delete' => false, - 'max_status' => true, - 'js_options' => array(), - 'add_to' => 'end', - ) - ); - - $field['js_options'] = wp_parse_args( - $field['js_options'], - array( - 'mimeType' => $field['mime_type'], - 'maxFiles' => $field['max_file_uploads'], - 'forceDelete' => $field['force_delete'] ? true : false, - 'maxStatus' => $field['max_status'], - 'addTo' => $field['add_to'], - ) - ); + $field = wp_parse_args( $field, [ + 'std' => [], + 'mime_type' => '', + 'max_file_uploads' => 0, + 'force_delete' => false, + 'max_status' => true, + 'js_options' => [], + 'add_to' => 'end', + ] ); + + $field['js_options'] = wp_parse_args( $field['js_options'], [ + 'mimeType' => $field['mime_type'], + 'maxFiles' => $field['max_file_uploads'], + 'forceDelete' => $field['force_delete'], + 'maxStatus' => $field['max_status'], + 'addTo' => $field['add_to'], + ] ); $field['multiple'] = true; @@ -157,38 +135,26 @@ public static function get_attributes( $field, $value = null ) { $attributes['class'] .= ' rwmb-media'; // Add attachment details. - $attachments = array(); - foreach ( $value as $media ) { - $media = wp_prepare_attachment_for_js( $media ); - // Some themes/plugins add HTML, shortcodes to "compat" attrbute which break JSON validity. - if ( isset( $media['compat'] ) ) { - unset( $media['compat'] ); - } - if ( ! empty( $media ) ) { - $attachments[] = $media; - } + $attachments = array_values( array_filter( array_map( 'wp_prepare_attachment_for_js', $value ) ) ); + $attributes['data-attachments'] = wp_json_encode( $attachments ); + + if ( empty( $attachments ) ) { + unset( $attributes['value'] ); } - $attachments = array_values( $attachments ); - $attributes['data-attachments'] = json_encode( $attachments ); return $attributes; } - /** - * Get supported mime extensions. - * - * @return array - */ - protected static function get_mime_extensions() { + protected static function get_mime_extensions() : array { $mime_types = wp_get_mime_types(); - $extensions = array(); + $extensions = []; foreach ( $mime_types as $ext => $mime ) { $ext = explode( '|', $ext ); $extensions[ $mime ] = $ext; $mime_parts = explode( '/', $mime ); if ( empty( $extensions[ $mime_parts[0] ] ) ) { - $extensions[ $mime_parts[0] ] = array(); + $extensions[ $mime_parts[0] ] = []; } $extensions[ $mime_parts[0] ] = array_merge( $extensions[ $mime_parts[0] ], $ext ); $extensions[ $mime_parts[0] . '/*' ] = $extensions[ $mime_parts[0] ]; @@ -205,11 +171,21 @@ protected static function get_mime_extensions() { * @param int $post_id The post ID. * @param array $field The field parameters. * - * @return array|mixed + * @return array */ public static function value( $new, $old, $post_id, $field ) { - $new = RWMB_Helpers_Array::from_csv( $new ); - return array_filter( array_unique( array_map( 'absint', $new ) ) ); + $new = wp_parse_id_list( $new ); + + if ( empty( $new ) ) { + return []; + } + + // Attach the uploaded images to the post if needed. + global $wpdb; + $ids = implode( ',', $new ); + $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_parent=%d WHERE post_parent=0 AND ID IN ($ids)", $post_id ) ); + + return $new; } /** @@ -226,13 +202,13 @@ public static function save( $new, $old, $post_id, $field ) { } $storage = $field['storage']; $storage->delete( $post_id, $field['id'] ); - parent::save( $new, array(), $post_id, $field ); + parent::save( $new, [], $post_id, $field ); } /** * Template for media item. */ public static function print_templates() { - require_once RWMB_INC_DIR . 'templates/media.php'; + require RWMB_INC_DIR . 'templates/media.php'; } } diff --git a/vendor/wpmetabox/meta-box/inc/fields/multiple-values.php b/vendor/wpmetabox/meta-box/inc/fields/multiple-values.php index e69544cb1..4307ea7a5 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/multiple-values.php +++ b/vendor/wpmetabox/meta-box/inc/fields/multiple-values.php @@ -1,4 +1,6 @@ . - * - * @package Meta Box - */ +defined( 'ABSPATH' ) || die; /** - * Number field class. + * The number field which uses HTML . */ class RWMB_Number_Field extends RWMB_Input_Field { /** @@ -18,15 +14,11 @@ class RWMB_Number_Field extends RWMB_Input_Field { */ public static function normalize( $field ) { $field = parent::normalize( $field ); - - $field = wp_parse_args( - $field, - array( - 'step' => 1, - 'min' => 0, - 'max' => false, - ) - ); + $field = wp_parse_args( $field, [ + 'step' => 1, + 'min' => 0, + 'max' => false, + ] ); return $field; } @@ -41,14 +33,11 @@ public static function normalize( $field ) { */ public static function get_attributes( $field, $value = null ) { $attributes = parent::get_attributes( $field, $value ); - $attributes = wp_parse_args( - $attributes, - array( - 'step' => $field['step'], - 'max' => $field['max'], - 'min' => $field['min'], - ) - ); + $attributes = wp_parse_args( $attributes, [ + 'step' => $field['step'], + 'max' => $field['max'], + 'min' => $field['min'], + ] ); return $attributes; } } diff --git a/vendor/wpmetabox/meta-box/inc/fields/object-choice.php b/vendor/wpmetabox/meta-box/inc/fields/object-choice.php index 14cb69960..c79effaac 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/object-choice.php +++ b/vendor/wpmetabox/meta-box/inc/fields/object-choice.php @@ -1,12 +1,10 @@ true, - 'query_args' => array(), - 'field_type' => 'select_advanced', - 'add_new' => false, - 'ajax' => true, - ) - ); + $field = wp_parse_args( $field, [ + 'flatten' => true, + 'query_args' => [], + 'field_type' => 'select_advanced', + 'add_new' => false, + 'ajax' => true, + ] ); if ( 'select_advanced' !== $field['field_type'] ) { $field['ajax'] = false; } @@ -86,7 +77,7 @@ public static function normalize( $field ) { if ( 'radio_list' === $field['field_type'] ) { $field['field_type'] = 'radio'; } - $field = call_user_func( array( self::get_type_class( $field ), 'normalize' ), $field ); + $field = call_user_func( [ self::get_type_class( $field ), 'normalize' ], $field ); return $field; } @@ -102,22 +93,22 @@ protected static function set_ajax_params( &$field ) { } if ( empty( $field['js_options']['ajax'] ) ) { - $field['js_options']['ajax'] = array(); + $field['js_options']['ajax'] = []; } $field['js_options']['ajax'] = wp_parse_args( - array( + [ 'url' => admin_url( 'admin-ajax.php' ), - ), + ], $field['js_options']['ajax'] ); - $field['js_options']['ajax_data'] = array( - 'field' => array( + $field['js_options']['ajax_data'] = [ + 'field' => [ 'id' => $field['id'], 'type' => $field['type'], 'query_args' => $field['query_args'], - ), + ], '_wpnonce' => wp_create_nonce( 'query' ), - ); + ]; } /** @@ -129,7 +120,7 @@ protected static function set_ajax_params( &$field ) { * @return array */ public static function get_attributes( $field, $value = null ) { - $attributes = call_user_func( array( self::get_type_class( $field ), 'get_attributes' ), $field, $value ); + $attributes = call_user_func( [ self::get_type_class( $field ), 'get_attributes' ], $field, $value ); if ( 'select_advanced' === $field['field_type'] ) { $attributes['class'] .= ' rwmb-select_advanced'; } elseif ( 'select' === $field['field_type'] ) { @@ -138,27 +129,29 @@ public static function get_attributes( $field, $value = null ) { return $attributes; } - /** - * Enqueue scripts and styles. - */ public static function admin_enqueue_scripts() { RWMB_Input_List_Field::admin_enqueue_scripts(); RWMB_Select_Field::admin_enqueue_scripts(); RWMB_Select_Tree_Field::admin_enqueue_scripts(); RWMB_Select_Advanced_Field::admin_enqueue_scripts(); + + // Field is the 1st param. + $field = func_get_arg( 0 ); + if ( empty( $field['add_new'] ) ) { + return; + } + + wp_enqueue_style( 'rwmb-modal', RWMB_CSS_URL . 'modal.css', [], RWMB_VER ); + wp_enqueue_script( 'rwmb-modal', RWMB_JS_URL . 'modal.js', [ 'jquery' ], RWMB_VER, true ); + + $type = $field['type'] === 'taxonomy_advanced' ? 'taxonomy' : $field['type']; + wp_enqueue_script( "rwmb-$type", RWMB_JS_URL . "$type.js", [ 'jquery', 'rwmb-modal' ], RWMB_VER, true ); } /** * Get correct rendering class for the field. - * - * @param array $field Field parameters. - * @return string */ - protected static function get_type_class( $field ) { - return RWMB_Helpers_Field::get_class( - array( - 'type' => $field['field_type'], - ) - ); + protected static function get_type_class( array $field ) : string { + return RWMB_Helpers_Field::get_class( [ 'type' => $field['field_type'] ] ); } } diff --git a/vendor/wpmetabox/meta-box/inc/fields/oembed.php b/vendor/wpmetabox/meta-box/inc/fields/oembed.php index e77bbf83d..192cf0c36 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/oembed.php +++ b/vendor/wpmetabox/meta-box/inc/fields/oembed.php @@ -1,12 +1,8 @@ __( 'Embed HTML not available.', 'meta-box' ), - ) - ); - $field['attributes'] = wp_parse_args( - $field['attributes'], - array( - 'data-not-available' => $field['not_available_string'], - ) - ); + $field = wp_parse_args( $field, [ + 'not_available_string' => __( 'Embed HTML not available.', 'meta-box' ), + ] ); + $field['attributes'] = wp_parse_args( $field['attributes'], [ + 'data-not-available' => $field['not_available_string'], + ] ); return $field; } - /** - * Enqueue scripts and styles. - */ public static function admin_enqueue_scripts() { - wp_enqueue_style( 'rwmb-oembed', RWMB_CSS_URL . 'oembed.css', '', RWMB_VER ); - wp_enqueue_script( 'rwmb-oembed', RWMB_JS_URL . 'oembed.js', array( 'jquery', 'underscore' ), RWMB_VER, true ); + wp_enqueue_style( 'rwmb-oembed', RWMB_CSS_URL . 'oembed.css', [], RWMB_VER ); + wp_enqueue_script( 'rwmb-oembed', RWMB_JS_URL . 'oembed.js', [ 'jquery', 'underscore', 'rwmb' ], RWMB_VER, true ); + wp_localize_script( 'rwmb-oembed', 'rwmbOembed', [ + 'nonce' => wp_create_nonce( 'oembed_get' ), + ] ); } - /** - * Add actions. - */ public static function add_actions() { - add_action( 'wp_ajax_rwmb_get_embed', array( __CLASS__, 'wp_ajax_get_embed' ) ); + add_action( 'wp_ajax_rwmb_get_embed', [ __CLASS__, 'ajax_get_embed' ] ); } - /** - * Ajax callback for returning oEmbed HTML. - */ - public static function wp_ajax_get_embed() { + public static function ajax_get_embed() { + check_ajax_referer( 'oembed_get' ); + $request = rwmb_request(); $url = (string) $request->filter_post( 'url', FILTER_SANITIZE_URL ); $not_available = (string) $request->post( 'not_available' ); @@ -76,7 +62,7 @@ public static function get_embed( $url, $not_available = '' ) { * @see WP_Embed::shortcode() * @see wp_embed_defaults() */ - $args = array(); + $args = []; if ( is_admin() ) { $args['width'] = 360; } diff --git a/vendor/wpmetabox/meta-box/inc/fields/osm.php b/vendor/wpmetabox/meta-box/inc/fields/osm.php index 2fd01f1ab..55e840b49 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/osm.php +++ b/vendor/wpmetabox/meta-box/inc/fields/osm.php @@ -1,33 +1,19 @@ __( 'No results found', 'meta-box' ), - ) - ); + self::enqueue_map_assets(); + + wp_enqueue_style( 'rwmb-osm', RWMB_CSS_URL . 'osm.css', [ 'leaflet' ], RWMB_VER ); + wp_enqueue_script( 'rwmb-osm', RWMB_JS_URL . 'osm.js', [ 'jquery', 'jquery-ui-autocomplete', 'leaflet' ], RWMB_VER, true ); + + RWMB_Helpers_Field::localize_script_once( 'rwmb-osm', 'RWMB_Osm', [ + 'no_results_string' => __( 'No results found', 'meta-box' ), + ] ); } /** @@ -72,15 +58,12 @@ public static function html( $meta, $field ) { */ public static function normalize( $field ) { $field = parent::normalize( $field ); - $field = wp_parse_args( - $field, - array( - 'std' => '', - 'address_field' => '', - 'language' => '', - 'region' => '', - ) - ); + $field = wp_parse_args( $field, [ + 'std' => '', + 'address_field' => '', + 'language' => '', + 'region' => '', + ] ); return $field; } @@ -96,7 +79,7 @@ public static function normalize( $field ) { * * @return mixed Array(latitude, longitude, zoom) */ - public static function get_value( $field, $args = array(), $post_id = null ) { + public static function get_value( $field, $args = [], $post_id = null ) { $value = parent::get_value( $field, $args, $post_id ); list( $latitude, $longitude, $zoom ) = explode( ',', $value . ',,' ); return compact( 'latitude', 'longitude', 'zoom' ); @@ -112,7 +95,7 @@ public static function get_value( $field, $args = array(), $post_id = null ) { * * @return string HTML output of the field */ - public static function the_value( $field, $args = array(), $post_id = null ) { + public static function the_value( $field, $args = [], $post_id = null ) { $value = parent::get_value( $field, $args, $post_id ); return self::render_map( $value, $args ); } @@ -120,47 +103,41 @@ public static function the_value( $field, $args = array(), $post_id = null ) { /** * Render a map in the frontend. * - * @param array $location The [latitude, longitude[, zoom]] location. - * @param array $args Additional arguments for the map. + * @param string $location The "latitude,longitude[,zoom]" location. + * @param array $args Additional arguments for the map. * * @return string */ - public static function render_map( $location, $args = array() ) { + public static function render_map( $location, $args = [] ) { list( $latitude, $longitude, $zoom ) = explode( ',', $location . ',,' ); if ( ! $latitude || ! $longitude ) { return ''; } - $args = wp_parse_args( - $args, - array( - 'latitude' => $latitude, - 'longitude' => $longitude, - 'width' => '100%', - 'height' => '480px', - 'marker' => true, // Display marker? - 'marker_title' => '', // Marker title, when hover. - 'info_window' => '', // Content of info window (when click on marker). HTML allowed. - 'js_options' => array(), - 'zoom' => $zoom, - ) - ); - - wp_enqueue_style( 'leaflet', 'https://unpkg.com/leaflet@1.5.1/dist/leaflet.css', array(), '1.5.1' ); - wp_enqueue_script( 'leaflet', 'https://unpkg.com/leaflet@1.5.1/dist/leaflet.js', array(), '1.5.1', true ); - wp_enqueue_script( 'rwmb-osm-frontend', RWMB_JS_URL . 'osm-frontend.js', array( 'jquery', 'leaflet' ), RWMB_VER, true ); + $args = wp_parse_args( $args, [ + 'latitude' => $latitude, + 'longitude' => $longitude, + 'width' => '100%', + 'height' => '480px', + 'marker' => true, // Display marker? + 'marker_title' => '', // Marker title, when hover. + 'info_window' => '', // Content of info window (when click on marker). HTML allowed. + 'js_options' => [], + 'zoom' => $zoom, + ] ); + + self::enqueue_map_assets(); + wp_enqueue_script( 'rwmb-osm-frontend', RWMB_JS_URL . 'osm-frontend.js', [ 'jquery', 'leaflet' ], RWMB_VER, true ); + wp_enqueue_style( 'rwmb-osm-frontend', RWMB_CSS_URL . 'osm-frontend.css', [], RWMB_VER ); /* * More Open Street Map options * @link https://leafletjs.com/reference-1.5.0.html#map-option */ - $args['js_options'] = wp_parse_args( - $args['js_options'], - array( - // Default to 'zoom' level set in admin, but can be overwritten. - 'zoom' => $args['zoom'], - ) - ); + $args['js_options'] = wp_parse_args( $args['js_options'], [ + // Default to 'zoom' level set in admin, but can be overwritten. + 'zoom' => $args['zoom'], + ] ); $output = sprintf( '
                    ', @@ -170,4 +147,9 @@ public static function render_map( $location, $args = array() ) { ); return $output; } + + private static function enqueue_map_assets() { + wp_enqueue_style( 'leaflet', 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css', [], '1.9.4' ); + wp_enqueue_script( 'leaflet', 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js', [], '1.9.4', true ); + } } diff --git a/vendor/wpmetabox/meta-box/inc/fields/password.php b/vendor/wpmetabox/meta-box/inc/fields/password.php index 3dec35242..0cc729e1e 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/password.php +++ b/vendor/wpmetabox/meta-box/inc/fields/password.php @@ -1,12 +1,8 @@ $items ); + $items = apply_filters( 'rwmb_ajax_get_posts', $items, $field, $request ); + + $data = [ 'items' => $items ]; // More items for pagination. $limit = (int) $field['query_args']['posts_per_page']; @@ -61,14 +53,11 @@ public static function ajax_get_posts() { * @return array */ public static function normalize( $field ) { - $field = wp_parse_args( - $field, - array( - 'post_type' => 'post', - 'parent' => false, - 'query_args' => array(), - ) - ); + $field = wp_parse_args( $field, [ + 'post_type' => 'post', + 'parent' => false, + 'query_args' => [], + ] ); $field['post_type'] = (array) $field['post_type']; @@ -82,16 +71,13 @@ public static function normalize( $field ) { $post_type = reset( $field['post_type'] ); $post_type_object = get_post_type_object( $post_type ); if ( ! empty( $post_type_object ) ) { - // Translators: %s is the taxonomy singular label. + // Translators: %s is the post singular label. $placeholder = sprintf( __( 'Select a %s', 'meta-box' ), strtolower( $post_type_object->labels->singular_name ) ); } } - $field = wp_parse_args( - $field, - array( - 'placeholder' => $placeholder, - ) - ); + $field = wp_parse_args( $field, [ + 'placeholder' => $placeholder, + ] ); // Set parent option, which will change field name to `parent_id` to save as post parent. if ( $field['parent'] ) { @@ -103,36 +89,26 @@ public static function normalize( $field ) { // Set default query args. $posts_per_page = $field['ajax'] ? 10 : -1; - $field['query_args'] = wp_parse_args( - $field['query_args'], - array( - 'post_type' => $field['post_type'], - 'post_status' => 'publish', - 'posts_per_page' => $posts_per_page, - ) - ); + $field['query_args'] = wp_parse_args( $field['query_args'], [ + 'post_type' => $field['post_type'], + 'post_status' => 'publish', + 'posts_per_page' => $posts_per_page, + ] ); parent::set_ajax_params( $field ); return $field; } - /** - * Query posts for field options. - * - * @param array $meta Saved meta value. - * @param array $field Field settings. - * @return array Field options array. - */ - public static function query( $meta, $field ) { - $args = wp_parse_args( - $field['query_args'], - array( - 'no_found_rows' => true, - 'update_post_meta_cache' => false, - 'update_post_term_cache' => false, - ) - ); + public static function query( $meta, array $field ): array { + $args = wp_parse_args( $field['query_args'], [ + 'no_found_rows' => true, + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'mb_field_id' => $field['id'], + ] ); + + $meta = wp_parse_id_list( (array) $meta ); // Query only selected items. if ( ! empty( $field['ajax'] ) && ! empty( $meta ) ) { @@ -155,15 +131,15 @@ public static function query( $meta, $field ) { $query = new WP_Query( $args ); remove_filter( 'posts_search', [ __CLASS__, 'search_by_title' ] ); - $options = array(); + $options = []; foreach ( $query->posts as $post ) { $label = $post->post_title ? $post->post_title : __( '(No title)', 'meta-box' ); $label = self::filter( 'choice_label', $label, $field, $post ); - $options[ $post->ID ] = array( + $options[ $post->ID ] = [ 'value' => $post->ID, 'label' => $label, 'parent' => $post->post_parent, - ); + ]; } // Cache the query. @@ -185,7 +161,7 @@ public static function search_by_title( $search, $wp_query ) { } $q = $wp_query->query_vars; $n = ! empty( $q['exact'] ) ? '' : '%'; - $search = array(); + $search = []; foreach ( (array) $q['search_terms'] as $term ) { $term = esc_sql( $wpdb->esc_like( $term ) ); $search[] = "($wpdb->posts.post_title LIKE '{$n}{$term}{$n}')"; @@ -220,10 +196,10 @@ public static function meta( $post_id, $saved, $field ) { /** * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. * - * @param array $field Field parameters. - * @param string $value The value. - * @param array $args Additional arguments. Rarely used. See specific fields for details. - * @param ?int $post_id Post ID. null for current post. Optional. + * @param array $field Field parameters. + * @param int $value The value. + * @param array $args Additional arguments. Rarely used. See specific fields for details. + * @param ?int $post_id Post ID. null for current post. Optional. * * @return string */ @@ -232,19 +208,40 @@ public static function format_single_value( $field, $value, $args, $post_id ) { return ''; } - $link = isset( $args['link'] ) ? $args['link'] : 'view'; + $link = $args['link'] ?? 'view'; $text = get_the_title( $value ); if ( false === $link ) { return $text; } - if ( 'view' === $link ) { - $url = get_permalink( $value ); - } + $url = get_permalink( $value ); if ( 'edit' === $link ) { $url = get_edit_post_link( $value ); } return sprintf( '%s', esc_url( $url ), wp_kses_post( $text ) ); } + + public static function add_new_form( array $field ): string { + if ( ! current_user_can( 'edit_posts' ) ) { + return ''; + } + + if ( 1 !== count( $field['post_type'] ) ) { + return ''; + } + + $post_type = reset( $field['post_type'] ); + if ( ! post_type_exists( $post_type ) ) { + return ''; + } + + $post_type_object = get_post_type_object( $post_type ); + + return sprintf( + '%s', + admin_url( $post_type === 'post' ? 'post-new.php' : 'post-new.php?post_type=' . $post_type ), + esc_html( $post_type_object->labels->add_new_item ) + ); + } } diff --git a/vendor/wpmetabox/meta-box/inc/fields/radio.php b/vendor/wpmetabox/meta-box/inc/fields/radio.php index 0b56de1c4..0ec35bcba 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/radio.php +++ b/vendor/wpmetabox/meta-box/inc/fields/radio.php @@ -1,20 +1,10 @@ 10, - ) - ); + $field = wp_parse_args( $field, [ + 'max' => 10, + ] ); $field = parent::normalize( $field ); return $field; } diff --git a/vendor/wpmetabox/meta-box/inc/fields/select-advanced.php b/vendor/wpmetabox/meta-box/inc/fields/select-advanced.php index ef09bedc4..83d728180 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/select-advanced.php +++ b/vendor/wpmetabox/meta-box/inc/fields/select-advanced.php @@ -1,36 +1,32 @@ is_admin(), + ]); } /** @@ -40,25 +36,19 @@ public static function admin_enqueue_scripts() { * @return array */ public static function normalize( $field ) { - $field = wp_parse_args( - $field, - array( - 'js_options' => array(), - 'placeholder' => __( 'Select an item', 'meta-box' ), - ) - ); + $field = wp_parse_args( $field, [ + 'js_options' => [], + 'placeholder' => __( 'Select an item', 'meta-box' ), + ] ); $field = parent::normalize( $field ); - $field['js_options'] = wp_parse_args( - $field['js_options'], - array( - 'allowClear' => true, - 'dropdownAutoWidth' => true, - 'placeholder' => $field['placeholder'], - 'width' => 'style', - ) - ); + $field['js_options'] = wp_parse_args( $field['js_options'], [ + 'allowClear' => true, + 'dropdownAutoWidth' => true, + 'placeholder' => $field['placeholder'], + 'width' => 'style', + ] ); return $field; } @@ -72,12 +62,9 @@ public static function normalize( $field ) { */ public static function get_attributes( $field, $value = null ) { $attributes = parent::get_attributes( $field, $value ); - $attributes = wp_parse_args( - $attributes, - array( - 'data-options' => wp_json_encode( $field['js_options'] ), - ) - ); + $attributes = wp_parse_args( $attributes, [ + 'data-options' => wp_json_encode( $field['js_options'] ), + ] ); return $attributes; } diff --git a/vendor/wpmetabox/meta-box/inc/fields/select-tree.php b/vendor/wpmetabox/meta-box/inc/fields/select-tree.php index ceb3ad343..9bcce29ad 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/select-tree.php +++ b/vendor/wpmetabox/meta-box/inc/fields/select-tree.php @@ -1,12 +1,8 @@ walk( $options ) : ''; } - /** - * Enqueue scripts and styles. - */ public static function admin_enqueue_scripts() { parent::admin_enqueue_scripts(); - wp_enqueue_style( 'rwmb-select-tree', RWMB_CSS_URL . 'select-tree.css', array( 'rwmb-select' ), RWMB_VER ); - wp_enqueue_script( 'rwmb-select-tree', RWMB_JS_URL . 'select-tree.js', array( 'rwmb-select' ), RWMB_VER, true ); + wp_enqueue_style( 'rwmb-select-tree', RWMB_CSS_URL . 'select-tree.css', [ 'rwmb-select' ], RWMB_VER ); + wp_enqueue_script( 'rwmb-select-tree', RWMB_JS_URL . 'select-tree.js', [ 'rwmb-select' ], RWMB_VER, true ); } /** diff --git a/vendor/wpmetabox/meta-box/inc/fields/select.php b/vendor/wpmetabox/meta-box/inc/fields/select.php index d72dea28d..05c88f167 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/select.php +++ b/vendor/wpmetabox/meta-box/inc/fields/select.php @@ -1,20 +1,13 @@ false, - ) - ); + $field = wp_parse_args( $field, [ + 'select_all_none' => false, + ] ); return $field; } @@ -71,12 +61,9 @@ public static function normalize( $field ) { */ public static function get_attributes( $field, $value = null ) { $attributes = parent::get_attributes( $field, $value ); - $attributes = wp_parse_args( - $attributes, - array( - 'multiple' => $field['multiple'], - ) - ); + $attributes = wp_parse_args( $attributes, [ + 'multiple' => $field['multiple'], + ] ); return $attributes; } diff --git a/vendor/wpmetabox/meta-box/inc/fields/sidebar.php b/vendor/wpmetabox/meta-box/inc/fields/sidebar.php index 946d8dc6b..77a9672d7 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/sidebar.php +++ b/vendor/wpmetabox/meta-box/inc/fields/sidebar.php @@ -1,48 +1,28 @@ __( 'Select a sidebar', 'meta-box' ), - ) - ); + $field = wp_parse_args( $field, [ + 'placeholder' => __( 'Select a sidebar', 'meta-box' ), + ] ); $field = parent::normalize( $field ); return $field; } - /** - * Get sidebars for field options. - * - * @param array $field Field settings. - * @return array Field options array. - */ - public static function query( $field ) { + public static function query( $meta, array $field ) : array { global $wp_registered_sidebars; - $options = array(); + $options = []; foreach ( $wp_registered_sidebars as $sidebar ) { - $options[ $sidebar['id'] ] = array( + $options[ $sidebar['id'] ] = [ 'value' => $sidebar['id'], 'label' => $sidebar['name'], - ); + ]; } return $options; } diff --git a/vendor/wpmetabox/meta-box/inc/fields/single-image.php b/vendor/wpmetabox/meta-box/inc/fields/single-image.php index 4ff05f1de..8aafe1b65 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/single-image.php +++ b/vendor/wpmetabox/meta-box/inc/fields/single-image.php @@ -1,12 +1,8 @@ '', - 'data-single-image' => 1, - ) - ); + $field['attributes'] = wp_parse_args( $field['attributes'], [ + 'class' => '', + 'data-single-image' => 1, + ] ); $field['attributes']['class'] .= ' rwmb-image_advanced'; $field['multiple'] = false; @@ -59,14 +52,14 @@ public static function value( $new, $old, $post_id, $field ) { * * @return mixed Full info of uploaded files */ - public static function get_value( $field, $args = array(), $post_id = null ) { + public static function get_value( $field, $args = [], $post_id = null ) { $value = RWMB_Field::get_value( $field, $args, $post_id ); if ( ! is_array( $value ) ) { return RWMB_Image_Field::file_info( $value, $args, $field ); } - $return = array(); + $return = []; foreach ( $value as $image_id ) { $return[] = RWMB_Image_Field::file_info( $image_id, $args, $field ); } diff --git a/vendor/wpmetabox/meta-box/inc/fields/slider.php b/vendor/wpmetabox/meta-box/inc/fields/slider.php index 41c850d71..2987078b7 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/slider.php +++ b/vendor/wpmetabox/meta-box/inc/fields/slider.php @@ -1,25 +1,18 @@ '', - 'suffix' => '', - 'std' => '', - 'js_options' => array(), - ) - ); - $field['js_options'] = wp_parse_args( - $field['js_options'], - array( - 'range' => 'min', // range = 'min' will add a dark background to sliding part, better UI. - 'value' => $field['std'], - ) - ); + $field = wp_parse_args( $field, [ + 'prefix' => '', + 'suffix' => '', + 'std' => '', + 'js_options' => [], + ] ); + $field['js_options'] = wp_parse_args( $field['js_options'], [ + 'range' => 'min', // range = 'min' will add a dark background to sliding part, better UI. + 'value' => $field['std'], + ] ); return $field; } diff --git a/vendor/wpmetabox/meta-box/inc/fields/switch.php b/vendor/wpmetabox/meta-box/inc/fields/switch.php index 83c7cdf3e..18bb79dbf 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/switch.php +++ b/vendor/wpmetabox/meta-box/inc/fields/switch.php @@ -1,19 +1,12 @@ 'rounded', - 'on_label' => '', - 'off_label' => '', - ) - ); + $field = wp_parse_args( $field, [ + 'style' => 'rounded', + 'on_label' => '', + 'off_label' => '', + ] ); return $field; } diff --git a/vendor/wpmetabox/meta-box/inc/fields/taxonomy-advanced.php b/vendor/wpmetabox/meta-box/inc/fields/taxonomy-advanced.php index 008582b74..8f6bb6d01 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/taxonomy-advanced.php +++ b/vendor/wpmetabox/meta-box/inc/fields/taxonomy-advanced.php @@ -1,12 +1,8 @@ $term_ids, - 'hide_empty' => false, - ), - $args - ); + $args = wp_parse_args( [ + 'include' => $term_ids, + 'hide_empty' => false, + ], $args ); $info = get_terms( $field['taxonomy'], $args ); - $info = is_array( $info ) ? $info : array(); + $info = is_array( $info ) ? $info : []; return $field['multiple'] ? $info : reset( $info ); } } diff --git a/vendor/wpmetabox/meta-box/inc/fields/taxonomy.php b/vendor/wpmetabox/meta-box/inc/fields/taxonomy.php index b1304b64d..5cb654642 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/taxonomy.php +++ b/vendor/wpmetabox/meta-box/inc/fields/taxonomy.php @@ -1,25 +1,15 @@ filter_post( 'term' ); // Pagination. - $limit = isset( $field['query_args']['number'] ) ? (int) $field['query_args']['number'] : 0; + $limit = $field['query_args']['number'] ?? 0; + $limit = (int) $limit; if ( 'query:append' === $request->filter_post( '_type' ) ) { $page = $request->filter_post( 'page', FILTER_SANITIZE_NUMBER_INT ); $field['query_args']['offset'] = $limit * ( $page - 1 ); @@ -45,7 +36,9 @@ public static function ajax_get_terms() { $items = self::query( null, $field ); $items = array_values( $items ); - $data = array( 'items' => $items ); + $items = apply_filters( 'rwmb_ajax_get_terms', $items, $field, $request ); + + $data = [ 'items' => $items ]; // More items for pagination. if ( $limit && count( $items ) === $limit ) { @@ -74,14 +67,11 @@ public static function normalize( $field ) { } // Set default field args. - $field = wp_parse_args( - $field, - array( - 'taxonomy' => 'category', - 'query_args' => array(), - 'remove_default' => false, - ) - ); + $field = wp_parse_args( $field, [ + 'taxonomy' => 'category', + 'query_args' => [], + 'remove_default' => false, + ] ); // Force taxonomy to be an array. $field['taxonomy'] = (array) $field['taxonomy']; @@ -97,24 +87,18 @@ public static function normalize( $field ) { // Translators: %s is the taxonomy singular label. $placeholder = sprintf( __( 'Select a %s', 'meta-box' ), strtolower( $taxonomy_name ) ); } - $field = wp_parse_args( - $field, - array( - 'placeholder' => $placeholder, - ) - ); + $field = wp_parse_args( $field, [ + 'placeholder' => $placeholder, + ] ); $field = parent::normalize( $field ); // Set default query args. $limit = $field['ajax'] ? 10 : 0; - $field['query_args'] = wp_parse_args( - $field['query_args'], - array( - 'taxonomy' => $field['taxonomy'], - 'number' => $limit, - ) - ); + $field['query_args'] = wp_parse_args( $field['query_args'], [ + 'taxonomy' => $field['taxonomy'], + 'number' => $limit, + ] ); parent::set_ajax_params( $field ); @@ -126,22 +110,14 @@ public static function normalize( $field ) { return $field; } - /** - * Query terms for field options. - * - * @param array $meta Saved meta value. - * @param array $field Field settings. - * @return array Field options array. - */ - public static function query( $meta, $field ) { - $args = wp_parse_args( - $field['query_args'], - array( - 'hide_empty' => false, - 'count' => false, - 'update_term_meta_cache' => false, - ) - ); + public static function query( $meta, array $field ): array { + $args = wp_parse_args( $field['query_args'], [ + 'hide_empty' => false, + 'count' => false, + 'update_term_meta_cache' => false, + ] ); + + $meta = wp_parse_id_list( (array) $meta ); // Query only selected items. if ( ! empty( $field['ajax'] ) && ! empty( $meta ) ) { @@ -150,17 +126,18 @@ public static function query( $meta, $field ) { $terms = get_terms( $args ); if ( ! is_array( $terms ) ) { - return array(); + return []; } - $options = array(); + $options = []; foreach ( $terms as $term ) { $label = $term->name ? $term->name : __( '(No title)', 'meta-box' ); $label = self::filter( 'choice_label', $label, $field, $term ); - $options[ $term->term_id ] = array( + + $options[ $term->term_id ] = [ 'value' => $term->term_id, 'label' => $label, 'parent' => $term->parent, - ); + ]; } return $options; } @@ -178,7 +155,7 @@ public static function query( $meta, $field ) { public static function value( $new, $old, $post_id, $field ) { $new = (array) $new; $new[] = self::add_term( $field ); - $new = array_unique( array_map( 'intval', array_filter( $new ) ) ); + $new = array_filter( wp_parse_id_list( $new ) ); return $new; } @@ -218,7 +195,7 @@ protected static function add_term( $field ) { if ( is_wp_error( $term ) ) { return null; } - return isset( $term['term_id'] ) ? $term['term_id'] : null; + return $term['term_id'] ?? null; } /** @@ -230,21 +207,14 @@ protected static function add_term( $field ) { * * @return mixed */ - public static function raw_meta( $object_id, $field, $args = array() ) { + public static function raw_meta( $object_id, $field, $args = [] ) { if ( empty( $field['id'] ) ) { return ''; } - $meta = wp_get_object_terms( - $object_id, - $field['taxonomy'], - array( - 'orderby' => 'term_order', - ) - ); - if ( is_wp_error( $meta ) ) { - return ''; - } + $meta = wp_get_object_terms( $object_id, $field['taxonomy'], [ + 'orderby' => 'term_order', + ] ); $meta = wp_list_pluck( $meta, 'term_id' ); return $field['multiple'] ? $meta : reset( $meta ); @@ -254,38 +224,34 @@ public static function raw_meta( $object_id, $field, $args = array() ) { * Get the field value. * Return list of post term objects. * - * @param array $field Field parameters. - * @param array $args Additional arguments. - * @param int|null $post_id Post ID. null for current post. Optional. + * @param array $field Field parameters. + * @param array $args Additional arguments. + * @param ?int $post_id Post ID. * * @return array List of post term objects. */ - public static function get_value( $field, $args = array(), $post_id = null ) { + public static function get_value( $field, $args = [], $post_id = null ) { if ( ! $post_id ) { $post_id = get_the_ID(); } - $value = wp_get_object_terms( - $post_id, - $field['taxonomy'], - array( - 'orderby' => 'term_order', - ) - ); + $value = wp_get_object_terms( $post_id, $field['taxonomy'], [ + 'orderby' => 'term_order', + ] ); // Get single value if necessary. - if ( ! $field['clone'] && ! $field['multiple'] && is_array( $value ) ) { + if ( ! $field['clone'] && ! $field['multiple'] ) { $value = reset( $value ); } return $value; } /** - * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. + * Format a single value for the helper functions. * - * @param array $field Field parameters. - * @param object|array $value The value. - * @param array $args Additional arguments. Rarely used. See specific fields for details. - * @param ?int $post_id Post ID. null for current post. Optional. + * @param array $field Field parameters. + * @param WP_Term $value The term object. + * @param array $args Additional arguments. Rarely used. See specific fields for details. + * @param ?int $post_id Post ID. null for current post. Optional. * * @return string */ @@ -294,15 +260,13 @@ public static function format_single_value( $field, $value, $args, $post_id ) { return ''; } - $link = isset( $args['link'] ) ? $args['link'] : 'view'; + $link = $args['link'] ?? 'view'; $text = $value->name; if ( false === $link ) { return $text; } - if ( 'view' === $link ) { - $url = get_term_link( $value ); - } + $url = get_term_link( $value ); if ( 'edit' === $link ) { $url = get_edit_term_link( $value ); } @@ -310,13 +274,11 @@ public static function format_single_value( $field, $value, $args, $post_id ) { return sprintf( '%s', esc_url( $url ), esc_html( $text ) ); } - /** - * Render "Add New" form - * - * @param array $field Field settings. - * @return string - */ - public static function add_new_form( $field ) { + public static function add_new_form( array $field ): string { + if ( ! current_user_can( 'edit_posts' ) ) { + return ''; + } + // Only add new term if field has only one taxonomy. if ( 1 !== count( $field['taxonomy'] ) ) { return ''; @@ -328,45 +290,21 @@ public static function add_new_form( $field ) { return ''; } - $html = ' -
                    - -
                    - -
                    -
                    '; - - $html = sprintf( - $html, - esc_html( $taxonomy_object->labels->add_new_item ), - esc_attr( $field['id'] ), - esc_attr( $taxonomy_object->labels->new_item_name ) + return sprintf( + '%s', + admin_url( 'edit-tags.php?taxonomy=' . $taxonomy_object->name ), + esc_html( $taxonomy_object->labels->add_new_item ) ); - - return $html; } - /** - * Enqueue scripts and styles. - */ public static function admin_enqueue_scripts() { - parent::admin_enqueue_scripts(); - wp_enqueue_style( 'rwmb-taxonomy', RWMB_CSS_URL . 'taxonomy.css', array(), RWMB_VER ); - wp_enqueue_script( 'rwmb-taxonomy', RWMB_JS_URL . 'taxonomy.js', array( 'jquery' ), RWMB_VER, true ); - - // Field is the 1st param. - $args = func_get_args(); - $field = $args[0]; - self::remove_default_meta_box( $field ); + $field = func_get_arg( 0 ); + parent::admin_enqueue_scripts( $field ); + static::remove_default_meta_box( $field ); } - /** - * Remove default WordPress taxonomy meta box. - * - * @param array $field Field settings. - */ - protected static function remove_default_meta_box( $field ) { - if ( empty( $field['remove_default'] ) || ! is_admin() || ! function_exists( 'remove_meta_box' ) ) { + protected static function remove_default_meta_box( array $field ) { + if ( empty( $field['remove_default'] ) || ! function_exists( 'remove_meta_box' ) ) { return; } foreach ( $field['taxonomy'] as $taxonomy ) { @@ -375,13 +313,7 @@ protected static function remove_default_meta_box( $field ) { } } - /** - * Get taxonomy singular name. - * - * @param array $field Field settings. - * @return string - */ - protected static function get_taxonomy_singular_name( $field ) { + protected static function get_taxonomy_singular_name( array $field ): string { if ( 1 !== count( $field['taxonomy'] ) ) { return ''; } diff --git a/vendor/wpmetabox/meta-box/inc/fields/text-list.php b/vendor/wpmetabox/meta-box/inc/fields/text-list.php index aff77557e..010bde480 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/text-list.php +++ b/vendor/wpmetabox/meta-box/inc/fields/text-list.php @@ -1,19 +1,12 @@ %s '; - $attributes = self::get_attributes( $field, $meta ); + $attributes = self::get_attributes( $field, $meta ); $attributes['type'] = 'text'; $count = 0; foreach ( $field['options'] as $placeholder => $label ) { - $attributes['value'] = isset( $meta[ $count ] ) ? esc_attr( $meta[ $count ] ) : ''; + $attributes['value'] = $meta[ $count ] ?? ''; $attributes['placeholder'] = $placeholder; $html[] = sprintf( @@ -78,7 +71,7 @@ public static function normalize( $field ) { */ public static function value( $new, $old, $post_id, $field ) { $filtered = array_filter( $new ); - return count( $filtered ) ? $new : array(); + return count( $filtered ) ? $new : []; } /** diff --git a/vendor/wpmetabox/meta-box/inc/fields/textarea.php b/vendor/wpmetabox/meta-box/inc/fields/textarea.php index e672cc3a2..b0c2ca44d 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/textarea.php +++ b/vendor/wpmetabox/meta-box/inc/fields/textarea.php @@ -1,12 +1,8 @@ false, - 'cols' => false, - 'rows' => 3, - 'maxlength' => false, - 'minlength' => false, - 'wrap' => false, - 'readonly' => false, - ) - ); + $field = wp_parse_args( $field, [ + 'autocomplete' => false, + 'cols' => false, + 'rows' => 3, + 'maxlength' => false, + 'minlength' => false, + 'wrap' => false, + 'readonly' => false, + ] ); return $field; } @@ -59,20 +52,17 @@ public static function normalize( $field ) { * @return array */ public static function get_attributes( $field, $value = null ) { - $attributes = parent::get_attributes( $field, $value ); - $attributes = wp_parse_args( - $attributes, - array( - 'autocomplete' => $field['autocomplete'], - 'cols' => $field['cols'], - 'rows' => $field['rows'], - 'maxlength' => $field['maxlength'], - 'minlength' => $field['minlength'], - 'wrap' => $field['wrap'], - 'readonly' => $field['readonly'], - 'placeholder' => $field['placeholder'], - ) - ); + $attributes = parent::get_attributes( $field, $value ); + $attributes = wp_parse_args( $attributes, [ + 'autocomplete' => $field['autocomplete'], + 'cols' => $field['cols'], + 'rows' => $field['rows'], + 'maxlength' => $field['maxlength'], + 'minlength' => $field['minlength'], + 'wrap' => $field['wrap'], + 'readonly' => $field['readonly'], + 'placeholder' => $field['placeholder'], + ] ); return $attributes; } diff --git a/vendor/wpmetabox/meta-box/inc/fields/time.php b/vendor/wpmetabox/meta-box/inc/fields/time.php index c4877f6d7..2654a9cc4 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/time.php +++ b/vendor/wpmetabox/meta-box/inc/fields/time.php @@ -1,17 +1,10 @@ filter_post( '_type' ) ) { $field['query_args']['paged'] = $request->filter_post( 'page', FILTER_SANITIZE_NUMBER_INT ); } @@ -48,7 +39,9 @@ public static function ajax_get_users() { $items = self::query( null, $field ); $items = array_values( $items ); - $data = array( 'items' => $items ); + $items = apply_filters( 'rwmb_ajax_get_users', $items, $field, $request ); + + $data = [ 'items' => $items ]; // More items for pagination. if ( $limit && count( $items ) === $limit ) { @@ -78,25 +71,19 @@ public static function update_cache() { */ public static function normalize( $field ) { // Set default field args. - $field = wp_parse_args( - $field, - array( - 'placeholder' => __( 'Select a user', 'meta-box' ), - 'query_args' => array(), - 'display_field' => 'display_name', - ) - ); + $field = wp_parse_args( $field, [ + 'placeholder' => __( 'Select a user', 'meta-box' ), + 'query_args' => [], + 'display_field' => 'display_name', + ] ); $field = parent::normalize( $field ); // Set default query args. $limit = $field['ajax'] ? 10 : 0; - $field['query_args'] = wp_parse_args( - $field['query_args'], - array( - 'number' => $limit, - ) - ); + $field['query_args'] = wp_parse_args( $field['query_args'], [ + 'number' => $limit, + ] ); parent::set_ajax_params( $field ); @@ -107,22 +94,25 @@ public static function normalize( $field ) { return $field; } - /** - * Query users for field options. - * - * @param array $meta Saved meta value. - * @param array $field Field settings. - * @return array Field options array. - */ - public static function query( $meta, $field ) { + public static function query( $meta, array $field ): array { $display_field = $field['display_field']; - $args = wp_parse_args( - $field['query_args'], - array( - 'orderby' => $display_field, - 'order' => 'asc', - ) - ); + $args = wp_parse_args( $field['query_args'], [ + 'orderby' => $display_field, + 'order' => 'asc', + 'fields' => [ + 'ID', + 'user_login', + 'user_pass', + 'user_nicename', + 'user_email', + 'user_url', + 'user_registered', + 'user_status', + 'display_name', + ], + ] ); + + $meta = wp_parse_id_list( (array) $meta ); // Query only selected items. if ( ! empty( $field['ajax'] ) && ! empty( $meta ) ) { @@ -139,14 +129,15 @@ public static function query( $meta, $field ) { } $users = get_users( $args ); - $options = array(); + $options = []; foreach ( $users as $user ) { $label = $user->$display_field ? $user->$display_field : __( '(No title)', 'meta-box' ); $label = self::filter( 'choice_label', $label, $field, $user ); - $options[ $user->ID ] = array( + + $options[ $user->ID ] = [ 'value' => $user->ID, 'label' => $label, - ); + ]; } // Cache the query. @@ -159,7 +150,7 @@ public static function query( $meta, $field ) { * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. * * @param array $field Field parameters. - * @param string $value The value. + * @param int $value User ID. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * @@ -170,7 +161,7 @@ public static function format_single_value( $field, $value, $args, $post_id ) { return ''; } - $link = isset( $args['link'] ) ? $args['link'] : 'view'; + $link = $args['link'] ?? 'view'; $user = get_userdata( $value ); $display_field = $field['display_field']; $text = $user->$display_field; @@ -178,13 +169,23 @@ public static function format_single_value( $field, $value, $args, $post_id ) { if ( false === $link ) { return $text; } - if ( 'view' === $link ) { - $url = get_author_posts_url( $value ); - } + $url = get_author_posts_url( $value ); if ( 'edit' === $link ) { $url = get_edit_user_link( $value ); } return sprintf( '%s', esc_url( $url ), esc_html( $text ) ); } + + public static function add_new_form( array $field ): string { + if ( ! current_user_can( 'create_users' ) ) { + return ''; + } + + return sprintf( + '%s', + admin_url( 'user-new.php' ), + esc_html__( 'Add New User', 'meta-box' ) + ); + } } diff --git a/vendor/wpmetabox/meta-box/inc/fields/video.php b/vendor/wpmetabox/meta-box/inc/fields/video.php index cc81c6831..48f708dcf 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/video.php +++ b/vendor/wpmetabox/meta-box/inc/fields/video.php @@ -1,29 +1,17 @@ wp_get_video_extensions(), - ) - ); + wp_enqueue_style( 'rwmb-video', RWMB_CSS_URL . 'video.css', [ 'rwmb-media' ], RWMB_VER ); + wp_enqueue_script( 'rwmb-video', RWMB_JS_URL . 'video.js', [ 'rwmb-media' ], RWMB_VER, true ); + RWMB_Helpers_Field::localize_script_once( 'rwmb-video', 'i18nRwmbVideo', [ + 'extensions' => wp_get_video_extensions(), + ] ); } /** @@ -49,23 +37,23 @@ public static function normalize( $field ) { * * @return array|bool False if file not found. Array of image info on success. */ - public static function file_info( $file_id, $args = array(), $field = array() ) { + public static function file_info( $file_id, $args = [], $field = [] ) { if ( ! get_attached_file( $file_id ) ) { return false; } $attachment = get_post( $file_id ); $url = wp_get_attachment_url( $attachment->ID ); $file_type = wp_check_filetype( $url, wp_get_mime_types() ); - $data = array( + $data = [ 'ID' => $file_id, 'src' => $url, 'type' => $file_type['type'], 'title' => $attachment->post_title, 'caption' => $attachment->post_excerpt, 'description' => $attachment->post_content, - ); + ]; - $data['meta'] = array(); + $data['meta'] = []; $meta = wp_get_attachment_metadata( $attachment->ID ); if ( ! empty( $meta ) ) { foreach ( wp_get_attachment_id3_keys( $attachment ) as $key => $label ) { @@ -75,15 +63,15 @@ public static function file_info( $file_id, $args = array(), $field = array() ) } if ( ! empty( $meta['width'] ) && ! empty( $meta['height'] ) ) { - $data['dimensions'] = array( + $data['dimensions'] = [ 'width' => $meta['width'], 'height' => $meta['height'], - ); + ]; } else { - $data['dimensions'] = array( + $data['dimensions'] = [ 'width' => 640, 'height' => 360, - ); + ]; } } @@ -120,22 +108,18 @@ public static function format_clone_value( $field, $value, $args, $post_id ) { // Display single video. if ( 1 === count( $value ) ) { $video = reset( $value ); - return wp_video_shortcode( - array( - 'src' => $video['src'], - 'width' => $video['dimensions']['width'], - 'height' => $video['dimensions']['height'], - ) - ); + return wp_video_shortcode( [ + 'src' => $video['src'], + 'width' => $video['dimensions']['width'], + 'height' => $video['dimensions']['height'], + ] ); } // Display multiple videos in a playlist. - return wp_playlist_shortcode( - array( - 'ids' => $ids, - 'type' => 'video', - ) - ); + return wp_playlist_shortcode( [ + 'ids' => $ids, + 'type' => 'video', + ] ); } /** @@ -143,6 +127,6 @@ public static function format_clone_value( $field, $value, $args, $post_id ) { */ public static function print_templates() { parent::print_templates(); - require_once RWMB_INC_DIR . 'templates/video.php'; + require RWMB_INC_DIR . 'templates/video.php'; } } diff --git a/vendor/wpmetabox/meta-box/inc/fields/wysiwyg.php b/vendor/wpmetabox/meta-box/inc/fields/wysiwyg.php index 642b8c28a..91ba57b9b 100644 --- a/vendor/wpmetabox/meta-box/inc/fields/wysiwyg.php +++ b/vendor/wpmetabox/meta-box/inc/fields/wysiwyg.php @@ -1,21 +1,14 @@ false, - 'options' => array(), - ) - ); + $field = wp_parse_args( $field, [ + 'raw' => false, + 'options' => [], + ] ); - $field['options'] = wp_parse_args( - $field['options'], - array( - 'editor_class' => 'rwmb-wysiwyg', - 'dfw' => true, // Use default WordPress full screen UI. - ) - ); + $field['options'] = wp_parse_args( $field['options'], [ + 'editor_class' => 'rwmb-wysiwyg', + 'dfw' => true, // Use default WordPress full screen UI. + ] ); // Keep the filter to be compatible with previous versions. $field['options'] = apply_filters( 'rwmb_wysiwyg_settings', $field['options'] ); diff --git a/vendor/wpmetabox/meta-box/inc/functions.php b/vendor/wpmetabox/meta-box/inc/functions.php index 2d6776d12..a4f855f61 100644 --- a/vendor/wpmetabox/meta-box/inc/functions.php +++ b/vendor/wpmetabox/meta-box/inc/functions.php @@ -1,8 +1,6 @@ 'post', - 'type' => '', - ) - ); + function rwmb_get_field_settings( $key, $args = [], $object_id = null ) { + $args = wp_parse_args( $args, [ + 'object_type' => 'post', + 'type' => '', + ] ); /** * Filter meta type from object type and object id. @@ -101,21 +100,18 @@ function rwmb_get_field_settings( $key, $args = array(), $object_id = null ) { * * @return mixed */ - function rwmb_meta_legacy( $key, $args = array(), $post_id = null ) { - $args = wp_parse_args( - $args, - array( - 'type' => 'text', - 'multiple' => false, - 'clone' => false, - ) - ); - $field = array( + function rwmb_meta_legacy( $key, $args = [], $post_id = null ) { + $args = wp_parse_args( $args, [ + 'type' => 'text', + 'multiple' => false, + 'clone' => false, + ] ); + $field = [ 'id' => $key, 'type' => $args['type'], 'clone' => $args['clone'], 'multiple' => $args['multiple'], - ); + ]; $method = 'get_value'; switch ( $args['type'] ) { @@ -146,7 +142,7 @@ function rwmb_meta_legacy( $key, $args = array(), $post_id = null ) { * * @return mixed false if field doesn't exist. Field value otherwise. */ - function rwmb_get_value( $field_id, $args = array(), $post_id = null ) { + function rwmb_get_value( $field_id, $args = [], $post_id = null ) { $args = wp_parse_args( $args ); $field = rwmb_get_field_settings( $field_id, $args, $post_id ); @@ -179,7 +175,7 @@ function rwmb_get_value( $field_id, $args = array(), $post_id = null ) { * * @return string */ - function rwmb_the_value( $field_id, $args = array(), $post_id = null, $echo = true ) { + function rwmb_the_value( $field_id, $args = [], $post_id = null, $echo = true ) { $args = wp_parse_args( $args ); $field = rwmb_get_field_settings( $field_id, $args, $post_id ); @@ -201,7 +197,7 @@ function rwmb_the_value( $field_id, $args = array(), $post_id = null, $echo = tr $output = apply_filters( 'rwmb_the_value', $output, $field, $args, $post_id ); if ( $echo ) { - echo $output; // WPCS: XSS OK. + echo $output; // phpcs:ignore WordPress.Security.EscapeOutput } return $output; @@ -218,11 +214,11 @@ function rwmb_the_value( $field_id, $args = array(), $post_id = null, $echo = tr * @return array */ function rwmb_get_object_fields( $type_or_id, $object_type = 'post' ) { - $meta_boxes = rwmb_get_registry( 'meta_box' )->get_by( array( 'object_type' => $object_type ) ); - array_walk( $meta_boxes, 'rwmb_check_meta_box_supports', array( $object_type, $type_or_id ) ); + $meta_boxes = rwmb_get_registry( 'meta_box' )->get_by( [ 'object_type' => $object_type ] ); + array_walk( $meta_boxes, 'rwmb_check_meta_box_supports', [ $object_type, $type_or_id ] ); $meta_boxes = array_filter( $meta_boxes ); - $fields = array(); + $fields = []; foreach ( $meta_boxes as $meta_box ) { foreach ( $meta_box->fields as $field ) { $fields[ $field['id'] ] = $field; @@ -255,7 +251,7 @@ function rwmb_check_meta_box_supports( &$meta_box, $key, $object_data ) { $type = $type_or_id; if ( is_numeric( $type_or_id ) ) { $term = get_term( $type_or_id ); - $type = is_array( $term ) ? $term->taxonomy : null; + $type = is_wp_error( $term ) || ! $term ? null : $term->taxonomy; } $prop = 'taxonomies'; break; @@ -288,7 +284,7 @@ function rwmb_check_meta_box_supports( &$meta_box, $key, $object_data ) { * @return object */ function rwmb_get_registry( $type ) { - static $data = array(); + static $data = []; $class = 'RWMB_' . RWMB_Helpers_String::title_case( $type ) . '_Registry'; if ( ! isset( $data[ $type ] ) ) { diff --git a/vendor/wpmetabox/meta-box/inc/helpers/array.php b/vendor/wpmetabox/meta-box/inc/helpers/array.php index 6eda94e6a..93f1ee02c 100644 --- a/vendor/wpmetabox/meta-box/inc/helpers/array.php +++ b/vendor/wpmetabox/meta-box/inc/helpers/array.php @@ -1,90 +1,9 @@ get_data( $handle, 'data' ) ) { wp_localize_script( $handle, $name, $data ); } } - public static function add_inline_script_once( $handle, $text ) { + public static function add_inline_script_once( string $handle, string $text ) { if ( ! wp_scripts()->get_data( $handle, 'after' ) ) { wp_add_inline_script( $handle, $text ); } } - /** - * Get field class name. - * - * @param array $field Field settings. - * @return string - */ - public static function get_class( $field ) { + public static function get_class( $field ) : string { $type = self::get_type( $field ); $class = 'RWMB_' . RWMB_Helpers_String::title_case( $type ) . '_Field'; + $class = apply_filters( 'rwmb_field_class', $class, $type ); return class_exists( $class ) ? $class : 'RWMB_Input_Field'; } - /** - * Get field type. - * - * @param array $field Field settings. - * @return string - */ - private static function get_type( $field ) { - $type = isset( $field['type'] ) ? $field['type'] : 'text'; + private static function get_type( $field ) : string { + $type = $field['type'] ?? 'text'; $map = array_merge( - array( + [ $type => $type, - ), - array( + ], + [ 'file_advanced' => 'media', 'plupload_image' => 'image_upload', 'url' => 'text', - ) + ] ); return $map[ $type ]; diff --git a/vendor/wpmetabox/meta-box/inc/helpers/string.php b/vendor/wpmetabox/meta-box/inc/helpers/string.php index 2f88ad68b..fc90d50c5 100644 --- a/vendor/wpmetabox/meta-box/inc/helpers/string.php +++ b/vendor/wpmetabox/meta-box/inc/helpers/string.php @@ -1,24 +1,10 @@ constants(); + // PSR-4 autoload. + $psr4_autoload = dirname( __DIR__ ) . '/vendor/autoload.php'; + if ( file_exists( $psr4_autoload ) ) { + require $psr4_autoload; + } + // Register autoload for classes. require_once RWMB_INC_DIR . 'autoloader.php'; $autoloader = new RWMB_Autoloader(); @@ -105,23 +100,29 @@ public function init() { $wpml->init(); // Update. - $update_option = new RWMB_Update_Option(); - $update_checker = new RWMB_Update_Checker( $update_option ); + $update_option = new \MetaBox\Updater\Option(); + $update_checker = new \MetaBox\Updater\Checker( $update_option ); $update_checker->init(); - $update_settings = new RWMB_Update_Settings( $update_checker, $update_option ); + $update_settings = new \MetaBox\Updater\Settings( $update_checker, $update_option ); $update_settings->init(); - $update_notification = new RWMB_Update_Notification( $update_checker, $update_option ); + $update_notification = new \MetaBox\Updater\Notification( $update_checker, $update_option ); $update_notification->init(); + // Register categories for page builders. + new \MetaBox\Block\Register(); + new \MetaBox\Oxygen\Register(); + new \MetaBox\Elementor\Register(); + new \MetaBox\Bricks\Register(); + if ( is_admin() ) { $about = new RWMB_About( $update_checker ); $about->init(); - new RWMB_Dashboard( 'http://feeds.feedburner.com/metaboxio', 'https://metabox.io/blog/', array( + new RWMB_Dashboard( 'http://feeds.feedburner.com/metaboxio', 'https://metabox.io/blog/', [ 'title' => 'Meta Box', 'dismiss_tooltip' => esc_html__( 'Dismiss all Meta Box news', 'meta-box' ), 'dismiss_confirm' => esc_html__( 'Are you sure to dismiss all Meta Box news?', 'meta-box' ), - ) ); + ] ); } // Public functions. diff --git a/vendor/wpmetabox/meta-box/inc/media-modal.php b/vendor/wpmetabox/meta-box/inc/media-modal.php index 98b175a0e..285b7428a 100644 --- a/vendor/wpmetabox/meta-box/inc/media-modal.php +++ b/vendor/wpmetabox/meta-box/inc/media-modal.php @@ -1,13 +1,6 @@ post_type === 'attachment' ) { - wp_enqueue_style( 'rwmb', RWMB_CSS_URL . 'media-modal.css', array(), RWMB_VER ); - } - } - - /** - * Get list of custom fields and store in the current object for future use. - */ public function get_fields() { $meta_boxes = rwmb_get_registry( 'meta_box' )->all(); foreach ( $meta_boxes as $meta_box ) { @@ -61,7 +35,14 @@ public function get_fields() { * * @return mixed */ - public function add_fields( $form_fields, WP_Post $post ) { + public function add_fields( $form_fields, ?WP_Post $post ) { + if (is_null($post)) { + return $form_fields; + } + if ( $this->is_attachment_edit_screen() ) { + return $form_fields; + } + foreach ( $this->fields as $field ) { $form_field = $field; $form_field['label'] = $field['name']; @@ -75,8 +56,12 @@ public function add_fields( $form_fields, WP_Post $post ) { ob_start(); $field['name'] = ''; // Don't show field label as it's already handled by WordPress. - + RWMB_Field::call( 'show', $field, true, $post->ID ); + + // For MB Custom Table to flush data from the cache to the database. + do_action( 'rwmb_flush_data', $post->ID, $field, [] ); + $form_field['html'] = ob_get_clean(); $form_fields[ $field['id'] ] = $form_field; @@ -104,42 +89,25 @@ public function save_fields( $post, $attachment ) { // Call defined method to save meta value, if there's no methods, call common one. RWMB_Field::call( $field, 'save', $new, $old, $post['ID'] ); + + // For MB Custom Table to flush data from the cache to the database. + do_action( 'rwmb_flush_data', $post['ID'], $field, [] ); } return $post; } - /** - * Whether or not show the meta box when editing custom fields in the normal mode. - * - * @param bool $show Whether to show the meta box in normal editing mode. - * @param array $meta_box Meta Box parameters. - * - * @return bool - */ - public function is_in_normal_mode( $show, $meta_box ) { - if ( ! $show ) { - return $show; - } + private function is_in_modal( array $meta_box ): bool { + return in_array( 'attachment', $meta_box['post_types'], true ) && ! empty( $meta_box['media_modal'] ); + } - // Show the meta box in the modal on Media screen. - global $pagenow; - if ( $pagenow === 'upload.php' ) { - return $this->is_in_modal( $meta_box ); + private function is_attachment_edit_screen(): bool { + if ( ! function_exists( 'get_current_screen' ) ) { + return false; } - // Show the meta box only if not in the modal on the post edit screen. - return ! $this->is_in_modal( $meta_box ); - } + $screen = get_current_screen(); - /** - * Check if the meta box is for editing custom fields in the media modal. - * - * @param array $meta_box Meta Box parameters. - * - * @return bool - */ - protected function is_in_modal( $meta_box ) { - return in_array( 'attachment', $meta_box['post_types'], true ) && ! empty( $meta_box['media_modal'] ); + return $screen && $screen->id === 'attachment'; } } diff --git a/vendor/wpmetabox/meta-box/inc/meta-box-registry.php b/vendor/wpmetabox/meta-box/inc/meta-box-registry.php index 1557bc66d..92ee5ee38 100644 --- a/vendor/wpmetabox/meta-box/inc/meta-box-registry.php +++ b/vendor/wpmetabox/meta-box/inc/meta-box-registry.php @@ -2,20 +2,10 @@ /** * A registry for storing all meta boxes. * - * @link https://designpatternsphp.readthedocs.io/en/latest/Structural/Registry/README.html - * @package Meta Box - */ - -/** - * Meta box registry class. + * @link https://designpatternsphp.readthedocs.io/en/latest/Structural/Registry/README.html */ class RWMB_Meta_Box_Registry { - /** - * Internal data storage. - * - * @var array - */ - private $data = array(); + private $data = []; /** * Create a meta box object. @@ -23,7 +13,7 @@ class RWMB_Meta_Box_Registry { * @param array $settings Meta box settings. * @return \RW_Meta_Box */ - public function make( $settings ) { + public function make( array $settings ) { $class_name = apply_filters( 'rwmb_meta_box_class_name', 'RW_Meta_Box', $settings ); $meta_box = new $class_name( $settings ); @@ -31,34 +21,20 @@ public function make( $settings ) { return $meta_box; } - /** - * Add a meta box to the registry. - * - * @param RW_Meta_Box $meta_box Meta box instance. - */ public function add( RW_Meta_Box $meta_box ) { $this->data[ $meta_box->id ] = $meta_box; } - /** - * Retrieve a meta box by id. - * - * @param string $id Meta box id. - * - * @return RW_Meta_Box|bool False or meta box object. - */ public function get( $id ) { - return isset( $this->data[ $id ] ) ? $this->data[ $id ] : false; + return $this->data[ $id ] ?? false; } /** * Get meta boxes under some conditions. * * @param array $args Custom argument to get meta boxes by. - * - * @return array */ - public function get_by( $args ) { + public function get_by( array $args ) : array { $meta_boxes = $this->data; foreach ( $meta_boxes as $index => $meta_box ) { foreach ( $args as $key => $value ) { @@ -73,11 +49,6 @@ public function get_by( $args ) { return $meta_boxes; } - /** - * Retrieve all meta boxes. - * - * @return array - */ public function all() { return $this->data; } diff --git a/vendor/wpmetabox/meta-box/inc/meta-box.php b/vendor/wpmetabox/meta-box/inc/meta-box.php index 222c7bb7d..12a9c4828 100644 --- a/vendor/wpmetabox/meta-box/inc/meta-box.php +++ b/vendor/wpmetabox/meta-box/inc/meta-box.php @@ -1,15 +1,8 @@ - * @license GNU GPL2+ - * @package Meta Box - */ +use MetaBox\Support\Arr; /** - * The main meta box class. + * A class to rapid develop meta boxes for custom & built in content types * * @property string $id Meta Box ID. * @property string $title Meta Box title. @@ -22,8 +15,6 @@ * @property bool $default_hidden Whether the meta box is hidden by default. * @property bool $autosave Whether the meta box auto saves. * @property bool $media_modal Add custom fields to media modal when viewing/editing an attachment. - * - * @package Meta Box */ class RW_Meta_Box { /** @@ -55,12 +46,7 @@ class RW_Meta_Box { */ protected $object_type = 'post'; - /** - * Create meta box based on given data. - * - * @param array $meta_box Meta box definition. - */ - public function __construct( $meta_box ) { + public function __construct( array $meta_box ) { $meta_box = static::normalize( $meta_box ); $this->meta_box = $meta_box; @@ -74,9 +60,6 @@ public function __construct( $meta_box ) { } } - /** - * Add fields to field registry. - */ public function register_fields() { $field_registry = rwmb_get_registry( 'field' ); @@ -87,26 +70,14 @@ public function register_fields() { } } - /** - * Conditional check for whether initializing meta box. - * - * - 1st filter applies to all meta boxes. - * - 2nd filter applies to only current meta box. - * - * @return bool - */ - public function is_shown() { + public function is_shown() : bool { $show = apply_filters( 'rwmb_show', true, $this->meta_box ); - return apply_filters( "rwmb_show_{$this->id}", $show, $this->meta_box ); } - /** - * Add global hooks. - */ protected function global_hooks() { // Enqueue common styles and scripts. - add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ) ); + add_action( 'admin_enqueue_scripts', [ $this, 'enqueue' ] ); // Add additional actions for fields. foreach ( $this->fields as $field ) { @@ -116,47 +87,44 @@ protected function global_hooks() { /** * Specific hooks for meta box object. Default is 'post'. - * This should be extended in sub-classes to support meta fields for terms, user, settings pages, etc. + * This should be extended in subclasses to support meta fields for terms, user, settings pages, etc. */ protected function object_hooks() { // Add meta box. - add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) ); + add_action( 'add_meta_boxes', [ $this, 'add_meta_boxes' ] ); // Hide meta box if it's set 'default_hidden'. - add_filter( 'default_hidden_meta_boxes', array( $this, 'hide' ), 10, 2 ); + add_filter( 'default_hidden_meta_boxes', [ $this, 'hide' ], 10, 2 ); // Save post meta. foreach ( $this->post_types as $post_type ) { if ( 'attachment' === $post_type ) { // Attachment uses other hooks. // @see wp_update_post(), wp_insert_attachment(). - add_action( 'edit_attachment', array( $this, 'save_post' ) ); - add_action( 'add_attachment', array( $this, 'save_post' ) ); + add_action( 'edit_attachment', [ $this, 'save_post' ] ); + add_action( 'add_attachment', [ $this, 'save_post' ] ); } else { - add_action( "save_post_{$post_type}", array( $this, 'save_post' ) ); + add_action( "save_post_{$post_type}", [ $this, 'save_post' ] ); } } } - /** - * Enqueue common scripts and styles. - */ public function enqueue() { if ( is_admin() && ! $this->is_edit_screen() ) { return; } - wp_enqueue_style( 'rwmb', RWMB_CSS_URL . 'style.css', array(), RWMB_VER ); + wp_enqueue_style( 'rwmb', RWMB_CSS_URL . 'style.css', [], RWMB_VER ); if ( is_rtl() ) { - wp_enqueue_style( 'rwmb-rtl', RWMB_CSS_URL . 'style-rtl.css', array(), RWMB_VER ); + wp_enqueue_style( 'rwmb-rtl', RWMB_CSS_URL . 'style-rtl.css', [], RWMB_VER ); } - wp_enqueue_script( 'rwmb', RWMB_JS_URL . 'script.js', array( 'jquery' ), RWMB_VER, true ); + wp_enqueue_script( 'rwmb', RWMB_JS_URL . 'script.js', [ 'jquery' ], RWMB_VER, true ); // Load clone script conditionally. foreach ( $this->fields as $field ) { if ( $field['clone'] ) { - wp_enqueue_script( 'rwmb-clone', RWMB_JS_URL . 'clone.js', array( 'jquery-ui-sortable' ), RWMB_VER, true ); + wp_enqueue_script( 'rwmb-clone', RWMB_JS_URL . 'clone.js', [ 'jquery-ui-sortable' ], RWMB_VER, true ); break; } } @@ -168,7 +136,7 @@ public function enqueue() { // Auto save. if ( $this->autosave ) { - wp_enqueue_script( 'rwmb-autosave', RWMB_JS_URL . 'autosave.js', array( 'jquery' ), RWMB_VER, true ); + wp_enqueue_script( 'rwmb-autosave', RWMB_JS_URL . 'autosave.js', [ 'jquery' ], RWMB_VER, true ); } /** @@ -184,13 +152,13 @@ public function enqueue() { */ public function add_meta_boxes() { $screen = get_current_screen(); - add_filter( "postbox_classes_{$screen->id}_{$this->id}", array( $this, 'postbox_classes' ) ); + add_filter( "postbox_classes_{$screen->id}_{$this->id}", [ $this, 'postbox_classes' ] ); foreach ( $this->post_types as $post_type ) { add_meta_box( $this->id, $this->title, - array( $this, 'show' ), + [ $this, 'show' ], $post_type, $this->context, $this->priority @@ -198,13 +166,7 @@ public function add_meta_boxes() { } } - /** - * Modify meta box postbox classes. - * - * @param array $classes Array of classes. - * @return array - */ - public function postbox_classes( $classes ) { + public function postbox_classes( array $classes ) : array { if ( $this->closed ) { $classes[] = 'closed'; } @@ -213,15 +175,7 @@ public function postbox_classes( $classes ) { return $classes; } - /** - * Hide meta box if it's set 'default_hidden' - * - * @param array $hidden Array of default hidden meta boxes. - * @param object $screen Current screen information. - * - * @return array - */ - public function hide( $hidden, $screen ) { + public function hide( array $hidden, $screen ) : array { if ( $this->is_edit_screen( $screen ) && $this->default_hidden ) { $hidden[] = $this->id; } @@ -229,9 +183,6 @@ public function hide( $hidden, $screen ) { return $hidden; } - /** - * Callback function to show fields in meta box - */ public function show() { if ( null === $this->object_id ) { $this->object_id = $this->get_current_object_id(); @@ -287,21 +238,16 @@ public function save_post( $object_id ) { do_action( 'rwmb_before_save_post', $object_id ); do_action( "rwmb_{$this->id}_before_save_post", $object_id ); - array_map( array( $this, 'save_field' ), $this->fields ); + array_map( [ $this, 'save_field' ], $this->fields ); // After save action. do_action( 'rwmb_after_save_post', $object_id ); do_action( "rwmb_{$this->id}_after_save_post", $object_id ); } - /** - * Save field. - * - * @param array $field Field settings. - */ - public function save_field( $field ) { + public function save_field( array $field ) { $single = $field['clone'] || ! $field['multiple']; - $default = $single ? '' : array(); + $default = $single ? '' : []; $old = RWMB_Field::call( $field, 'raw_meta', $this->object_id ); $new = rwmb_request()->post( $field['id'], $default ); $new = RWMB_Field::process_value( $new, $this->object_id, $field ); @@ -315,15 +261,7 @@ public function save_field( $field ) { RWMB_Field::filter( 'after_save_field', null, $field, $new, $old, $this->object_id ); } - /** - * Validate form when submit. Check: - * - If this function is called to prevent duplicated calls like revisions, manual hook to wp_insert_post, etc. - * - Autosave - * - If form is submitted properly - * - * @return bool - */ - public function validate() { + public function validate() : bool { $nonce = rwmb_request()->filter_post( "nonce_{$this->id}" ); return ! $this->saved @@ -331,54 +269,34 @@ public function validate() { && wp_verify_nonce( $nonce, "rwmb-save-{$this->id}" ); } - /** - * Normalize parameters for meta box - * - * @param array $meta_box Meta box definition. - * - * @return array $meta_box Normalized meta box. - */ public static function normalize( $meta_box ) { $default_title = __( 'Meta Box Title', 'meta-box' ); - // Set default values for meta box. - $meta_box = wp_parse_args( - $meta_box, - array( - 'title' => $default_title, - 'id' => ! empty( $meta_box['title'] ) ? sanitize_title( $meta_box['title'] ) : sanitize_title( $default_title ), - 'context' => 'normal', - 'priority' => 'high', - 'post_types' => 'post', - 'autosave' => false, - 'default_hidden' => false, - 'style' => 'default', - 'class' => '', - 'fields' => array(), - ) - ); + $meta_box = wp_parse_args( $meta_box, [ + 'title' => $default_title, + 'id' => ! empty( $meta_box['title'] ) ? sanitize_title( $meta_box['title'] ) : sanitize_title( $default_title ), + 'context' => 'normal', + 'priority' => 'high', + 'post_types' => 'post', + 'autosave' => false, + 'default_hidden' => false, + 'style' => 'default', + 'class' => '', + 'fields' => [], + ] ); /** * Use 'post_types' for better understanding and fallback to 'pages' for previous versions. - * * @since 4.4.1 */ - RWMB_Helpers_Array::change_key( $meta_box, 'pages', 'post_types' ); + Arr::change_key( $meta_box, 'pages', 'post_types' ); // Make sure the post type is an array and is sanitized. - $meta_box['post_types'] = array_map( 'sanitize_key', RWMB_Helpers_Array::from_csv( $meta_box['post_types'] ) ); + $meta_box['post_types'] = array_filter( array_map( 'sanitize_key', Arr::from_csv( $meta_box['post_types'] ) ) ); return $meta_box; } - /** - * Normalize an array of fields - * - * @param array $fields Array of fields. - * @param RWMB_Storage_Interface $storage Storage object. Optional. - * - * @return array $fields Normalized fields. - */ - public static function normalize_fields( $fields, $storage = null ) { + public static function normalize_fields( array $fields, $storage = null ) : array { foreach ( $fields as $k => $field ) { $field = RWMB_Field::call( 'normalize', $field ); @@ -397,9 +315,7 @@ public static function normalize_fields( $fields, $storage = null ) { /** * Check if meta box is saved before. - * This helps saving empty value in meta fields (text, check box, etc.) and set the correct default values. - * - * @return bool + * This helps to save empty value in meta fields (text, check box, etc.) and set the correct default values. */ public function is_saved() { foreach ( $this->fields as $field ) { @@ -419,7 +335,7 @@ public function is_saved() { if ( ( $single && '' !== $value ) - || ( ! $single && is_array( $value ) && array() !== $value ) + || ( ! $single && is_array( $value ) && [] !== $value ) ) { return true; } @@ -431,27 +347,18 @@ public function is_saved() { /** * Check if we're on the right edit screen. * - * @param WP_Screen $screen Screen object. Optional. Use current screen object by default. - * - * @return bool + * @param ?WP_Screen $screen Screen object. */ public function is_edit_screen( $screen = null ) { if ( ! ( $screen instanceof WP_Screen ) ) { $screen = get_current_screen(); } - return in_array( $screen->base, array( 'post', 'upload' ), true ) && in_array( $screen->post_type, $this->post_types, true ); + return in_array( $screen->base, [ 'post', 'upload' ], true ) && in_array( $screen->post_type, $this->post_types, true ); } - /** - * Magic function to get meta box property. - * - * @param string $key Meta box property name. - * - * @return mixed - */ - public function __get( $key ) { - return isset( $this->meta_box[ $key ] ) ? $this->meta_box[ $key ] : false; + public function __get( string $key ) { + return $this->meta_box[ $key ] ?? false; } /** @@ -463,12 +370,7 @@ public function set_object_id( $id = null ) { $this->object_id = $id; } - /** - * Get object type. - * - * @return string - */ - public function get_object_type() { + public function get_object_type() : string { return $this->object_type; } @@ -503,6 +405,6 @@ protected function get_real_object_id( $object_id ) { } $parent = wp_is_post_revision( $object_id ); - return $parent ? $parent : $object_id; + return $parent ?: $object_id; } } diff --git a/vendor/wpmetabox/meta-box/inc/request.php b/vendor/wpmetabox/meta-box/inc/request.php index 88e1bcd0c..37b19ed18 100644 --- a/vendor/wpmetabox/meta-box/inc/request.php +++ b/vendor/wpmetabox/meta-box/inc/request.php @@ -5,33 +5,11 @@ * * @link https://github.com/laravel/framework/blob/6.x/src/Illuminate/Http/Request.php * @link https://github.com/symfony/symfony/blob/4.4/src/Symfony/Component/HttpFoundation/ParameterBag.php - * - * @package Meta Box - */ - -/** - * A very simple request class that handles form inputs. - * - * @package Meta Box */ class RWMB_Request { - /** - * GET data. - * - * @var array - */ - private $get_data = array(); + private $get_data = []; + private $post_data = []; - /** - * POST data. - * - * @var array - */ - private $post_data = array(); - - /** - * Constructor. - */ public function __construct() { // @codingStandardsIgnoreLine $this->get_data = $_GET; @@ -39,44 +17,20 @@ public function __construct() { $this->post_data = $_POST; } - /** - * Set GET data. - * - * @param array $get_data Data. - */ - public function set_get_data( $get_data ) { - $this->get_data = array_merge( $this->get_data, $get_data ); + public function set_get_data( array $data ) { + $this->get_data = array_merge( $this->get_data, $data ); } - /** - * Set POST data. - * - * @param array $post_data Data. - */ - public function set_post_data( $post_data ) { - $this->post_data = array_merge( $this->post_data, $post_data ); + public function set_post_data( array $data ) { + $this->post_data = array_merge( $this->post_data, $data ); } - /** - * Return a GET parameter by name. - * - * @param string $name Parameter name. - * @param mixed $default Default value. - * @return mixed - */ - public function get( $name, $default = null ) { - return isset( $this->get_data[ $name ] ) ? $this->get_data[ $name ] : $default; + public function get( string $name, $default = null ) { + return $this->get_data[ $name ] ?? $default; } - /** - * Return a POST parameter by name. - * - * @param string $name Parameter name. - * @param mixed $default Default value. - * @return mixed - */ - public function post( $name, $default = null ) { - return isset( $this->post_data[ $name ] ) ? $this->post_data[ $name ] : $default; + public function post( string $name, $default = null ) { + return $this->post_data[ $name ] ?? $default; } /** @@ -88,7 +42,7 @@ public function post( $name, $default = null ) { * * @return mixed */ - public function filter_get( $name, $filter = FILTER_DEFAULT, $options = array() ) { + public function filter_get( string $name, $filter = FILTER_DEFAULT, $options = [] ) { $value = $this->get( $name ); return filter_var( $value, $filter, $options ); } @@ -102,7 +56,7 @@ public function filter_get( $name, $filter = FILTER_DEFAULT, $options = array() * * @return mixed */ - public function filter_post( $name, $filter = FILTER_DEFAULT, $options = array() ) { + public function filter_post( string $name, $filter = FILTER_DEFAULT, $options = [] ) { $value = $this->post( $name ); return filter_var( $value, $filter, $options ); } diff --git a/vendor/wpmetabox/meta-box/inc/sanitizer.php b/vendor/wpmetabox/meta-box/inc/sanitizer.php index 4b781e999..33ddb0f16 100644 --- a/vendor/wpmetabox/meta-box/inc/sanitizer.php +++ b/vendor/wpmetabox/meta-box/inc/sanitizer.php @@ -1,19 +1,10 @@ array( $this, 'sanitize_choice' ), - 'background' => array( $this, 'sanitize_background' ), - 'button_group' => array( $this, 'sanitize_choice' ), - 'checkbox' => array( $this, 'sanitize_checkbox' ), - 'checkbox_list' => array( $this, 'sanitize_choice' ), - 'color' => array( $this, 'sanitize_color' ), - 'date' => array( $this, 'sanitize_datetime' ), - 'datetime' => array( $this, 'sanitize_datetime' ), + $callbacks = [ + 'autocomplete' => [ $this, 'sanitize_choice' ], + 'background' => [ $this, 'sanitize_background' ], + 'button_group' => [ $this, 'sanitize_choice' ], + 'checkbox' => [ $this, 'sanitize_checkbox' ], + 'checkbox_list' => [ $this, 'sanitize_choice' ], + 'color' => [ $this, 'sanitize_color' ], + 'date' => [ $this, 'sanitize_datetime' ], + 'datetime' => [ $this, 'sanitize_datetime' ], 'email' => 'sanitize_email', - 'fieldset_text' => array( $this, 'sanitize_text' ), - 'file' => array( $this, 'sanitize_file' ), - 'file_advanced' => array( $this, 'sanitize_object' ), - 'file_input' => array( $this, 'sanitize_url' ), - 'file_upload' => array( $this, 'sanitize_object' ), + 'fieldset_text' => [ $this, 'sanitize_text' ], + 'file' => [ $this, 'sanitize_file' ], + 'file_advanced' => [ $this, 'sanitize_object' ], + 'file_input' => [ $this, 'sanitize_url' ], + 'file_upload' => [ $this, 'sanitize_object' ], 'hidden' => 'sanitize_text_field', - 'image' => array( $this, 'sanitize_file' ), - 'image_advanced' => array( $this, 'sanitize_object' ), - 'image_select' => array( $this, 'sanitize_choice' ), - 'image_upload' => array( $this, 'sanitize_object' ), - 'key_value' => array( $this, 'sanitize_text' ), - 'map' => array( $this, 'sanitize_map' ), - 'number' => array( $this, 'sanitize_number' ), - 'oembed' => array( $this, 'sanitize_url' ), - 'osm' => array( $this, 'sanitize_map' ), + 'image' => [ $this, 'sanitize_file' ], + 'image_advanced' => [ $this, 'sanitize_object' ], + 'image_select' => [ $this, 'sanitize_choice' ], + 'image_upload' => [ $this, 'sanitize_object' ], + 'key_value' => [ $this, 'sanitize_text' ], + 'map' => [ $this, 'sanitize_map' ], + 'number' => [ $this, 'sanitize_number' ], + 'oembed' => [ $this, 'sanitize_url' ], + 'osm' => [ $this, 'sanitize_map' ], 'password' => 'sanitize_text_field', - 'post' => array( $this, 'sanitize_object' ), - 'radio' => array( $this, 'sanitize_choice' ), - 'range' => array( $this, 'sanitize_number' ), - 'select' => array( $this, 'sanitize_choice' ), - 'select_advanced' => array( $this, 'sanitize_choice' ), - 'sidebar' => array( $this, 'sanitize_text' ), + 'post' => [ $this, 'sanitize_object' ], + 'radio' => [ $this, 'sanitize_choice' ], + 'range' => [ $this, 'sanitize_number' ], + 'select' => [ $this, 'sanitize_choice' ], + 'select_advanced' => [ $this, 'sanitize_choice' ], + 'sidebar' => [ $this, 'sanitize_text' ], 'single_image' => 'absint', - 'slider' => array( $this, 'sanitize_slider' ), - 'switch' => array( $this, 'sanitize_checkbox' ), - 'taxonomy' => array( $this, 'sanitize_object' ), - 'taxonomy_advanced' => array( $this, 'sanitize_taxonomy_advanced' ), + 'slider' => [ $this, 'sanitize_slider' ], + 'switch' => [ $this, 'sanitize_checkbox' ], + 'taxonomy' => [ $this, 'sanitize_object' ], + 'taxonomy_advanced' => [ $this, 'sanitize_taxonomy_advanced' ], 'text' => 'sanitize_text_field', - 'text_list' => array( $this, 'sanitize_text' ), + 'text_list' => [ $this, 'sanitize_text' ], 'textarea' => 'wp_kses_post', 'time' => 'sanitize_text_field', - 'url' => array( $this, 'sanitize_url' ), - 'user' => array( $this, 'sanitize_object' ), - 'video' => array( $this, 'sanitize_object' ), + 'url' => [ $this, 'sanitize_url' ], + 'user' => [ $this, 'sanitize_object' ], + 'video' => [ $this, 'sanitize_object' ], 'wysiwyg' => 'wp_kses_post', - ); + ]; $type = $field['type']; - return isset( $callbacks[ $type ] ) ? $callbacks[ $type ] : null; + return $callbacks[ $type ] ?? null; } /** @@ -105,9 +96,8 @@ private function get_callback( $field ) { * * @link https://github.com/rilwis/meta-box/issues/6 * @param string $value Checkbox value. - * @return int */ - private function sanitize_checkbox( $value ) { + private function sanitize_checkbox( $value ): int { return (int) ! empty( $value ); } @@ -121,14 +111,12 @@ private function sanitize_number( $value ) { return is_numeric( $value ) ? $value : ''; } - /** - * Sanitize color value. - * - * @param string $value The color value. - * @return string - */ - private function sanitize_color( $value ) { - if ( false === strpos( $value, 'rgba' ) ) { + private function sanitize_color( string $value ): string { + if ( str_contains( $value, 'hsl' ) ) { + return wp_unslash( $value ); + } + + if ( ! str_contains( $value, 'rgb' ) ) { return sanitize_hex_color( $value ); } @@ -136,8 +124,13 @@ private function sanitize_color( $value ) { $red = ''; $green = ''; $blue = ''; - $alpha = ''; - sscanf( $value, 'rgba(%d,%d,%d,%f)', $red, $green, $blue, $alpha ); + $alpha = 1; + + if ( str_contains( $value, 'rgba' ) ) { + sscanf( $value, 'rgba(%d,%d,%d,%f)', $red, $green, $blue, $alpha ); + } else { + sscanf( $value, 'rgb(%d,%d,%d)', $red, $green, $blue ); + } return 'rgba(' . $red . ',' . $green . ',' . $blue . ',' . $alpha . ')'; } @@ -152,7 +145,7 @@ private function sanitize_color( $value ) { private function sanitize_choice( $value, $field ) { $options = RWMB_Choice_Field::transform_options( $field['options'] ); $options = wp_list_pluck( $options, 'value' ); - $value = wp_unslash( $value ); + $value = wp_unslash( $value ); return is_array( $value ) ? array_intersect( $value, $options ) : ( in_array( $value, $options ) ? $value : '' ); } @@ -173,24 +166,21 @@ private function sanitize_object( $value ) { * @return array */ private function sanitize_background( $value ) { - $value = wp_parse_args( - $value, - array( - 'color' => '', - 'image' => '', - 'repeat' => '', - 'attachment' => '', - 'position' => '', - 'size' => '', - ) - ); + $value = wp_parse_args( $value, [ + 'color' => '', + 'image' => '', + 'repeat' => '', + 'attachment' => '', + 'position' => '', + 'size' => '', + ] ); $value['color'] = $this->sanitize_color( $value['color'] ); $value['image'] = esc_url_raw( $value['image'] ); - $value['repeat'] = in_array( $value['repeat'], array( 'no-repeat', 'repeat', 'repeat-x', 'repeat-y', 'inherit' ), true ) ? $value['repeat'] : ''; - $value['position'] = in_array( $value['position'], array( 'top left', 'top center', 'top right', 'center left', 'center center', 'center right', 'bottom left', 'bottom center', 'bottom right' ), true ) ? $value['position'] : ''; - $value['attachment'] = in_array( $value['attachment'], array( 'fixed', 'scroll', 'inherit' ), true ) ? $value['attachment'] : ''; - $value['size'] = in_array( $value['size'], array( 'inherit', 'cover', 'contain' ), true ) ? $value['size'] : ''; + $value['repeat'] = in_array( $value['repeat'], [ 'no-repeat', 'repeat', 'repeat-x', 'repeat-y', 'inherit' ], true ) ? $value['repeat'] : ''; + $value['position'] = in_array( $value['position'], [ 'top left', 'top center', 'top right', 'center left', 'center center', 'center right', 'bottom left', 'bottom center', 'bottom right' ], true ) ? $value['position'] : ''; + $value['attachment'] = in_array( $value['attachment'], [ 'fixed', 'scroll', 'inherit' ], true ) ? $value['attachment'] : ''; + $value['size'] = in_array( $value['size'], [ 'inherit', 'cover', 'contain' ], true ) ? $value['size'] : ''; return $value; } @@ -235,16 +225,10 @@ private function sanitize_slider( $value, $field ) { * @return float|string */ private function sanitize_datetime( $value, $field ) { - return $field['timestamp'] ? floor( abs( (float) $value ) ) : sanitize_text_field( $value ); + return $field['timestamp'] ? (float) $value : sanitize_text_field( $value ); } - /** - * Sanitize map field. - * - * @param mixed $value The submitted value. - * @return string - */ - private function sanitize_map( $value ) { + private function sanitize_map( $value ): string { $value = sanitize_text_field( $value ); list( $latitude, $longitude, $zoom ) = explode( ',', $value . ',,' ); @@ -255,26 +239,11 @@ private function sanitize_map( $value ) { return "$latitude,$longitude,$zoom"; } - /** - * Sanitize taxonomy advanced field. - * - * @param mixed $value The submitted value. - * @return string - */ - private function sanitize_taxonomy_advanced( $value ) { - $value = RWMB_Helpers_Array::from_csv( $value ); - $value = array_filter( array_map( 'absint', $value ) ); - - return implode( ',', $value ); + private function sanitize_taxonomy_advanced( $value ): string { + return implode( ',', wp_parse_id_list( $value ) ); } - /** - * Sanitize URL field. - * - * @param string $value The submitted value. - * @return string - */ - private function sanitize_url( $value ) { + private function sanitize_url( string $value ): string { return esc_url_raw( $value ); } } diff --git a/vendor/wpmetabox/meta-box/inc/shortcode.php b/vendor/wpmetabox/meta-box/inc/shortcode.php index 278b2fdff..c29b3bbea 100644 --- a/vendor/wpmetabox/meta-box/inc/shortcode.php +++ b/vendor/wpmetabox/meta-box/inc/shortcode.php @@ -1,4 +1,6 @@ '', 'render_shortcodes' => 'true', ] ); - RWMB_Helpers_Array::change_key( $atts, 'post_id', 'object_id' ); - RWMB_Helpers_Array::change_key( $atts, 'meta_key', 'id' ); + Arr::change_key( $atts, 'post_id', 'object_id' ); + Arr::change_key( $atts, 'meta_key', 'id' ); if ( empty( $atts['id'] ) ) { return ''; @@ -53,4 +55,4 @@ private function get_value( $field_id, $object_id, $atts ) { return $value; } -} \ No newline at end of file +} diff --git a/vendor/wpmetabox/meta-box/inc/storage-registry.php b/vendor/wpmetabox/meta-box/inc/storage-registry.php index 785dc7452..46648560d 100644 --- a/vendor/wpmetabox/meta-box/inc/storage-registry.php +++ b/vendor/wpmetabox/meta-box/inc/storage-registry.php @@ -1,21 +1,9 @@ + '; + public function rules( RW_Meta_Box $meta_box_object ) { + if ( empty( $meta_box_object->meta_box['validation'] ) ) { + return; } + + // Get field ID prefix from the builder. + $prefix = $meta_box_object->meta_box['prefix'] ?? ''; + + // Add prefix for validation rules. + $fields = $meta_box_object->meta_box['fields']; + foreach ( $meta_box_object->meta_box['validation'] as &$rules ) { + $rules = array_combine( + array_map( function ( $key ) use ( $fields, $prefix ) { + $id = $prefix . $key; + $index = array_search( $id, array_column( $fields, 'id' ), true ); + + if ( $index === false ) { + return $id; + } + + if ( in_array( $fields[ $index ]['type'], [ 'file', 'image' ], true ) ) { + return $fields[ $index ]['clone'] ? $fields[ $index ]['index_name'] : $fields[ $index ]['input_name']; + } + + return $id; + }, array_keys( $rules ) ), + $rules + ); + } + + echo ''; } - /** - * Enqueue scripts for validation. - */ public function enqueue() { - wp_enqueue_script( 'rwmb-validation', RWMB_JS_URL . 'validation.min.js', array( 'jquery', 'rwmb' ), RWMB_VER, true ); - - RWMB_Helpers_Field::localize_script_once( - 'rwmb-validation', - 'rwmbValidation', - array( - 'message' => esc_html__( 'Please correct the errors highlighted below and try again.', 'meta-box' ), - ) - ); + wp_enqueue_script( 'jquery-validation', RWMB_JS_URL . 'validation/jquery.validate.js', [ 'jquery' ], '1.19.5', true ); + wp_enqueue_script( 'jquery-validation-additional-methods', RWMB_JS_URL . 'validation/additional-methods.js', [ 'jquery-validation' ], '1.19.5', true ); + wp_enqueue_script( 'rwmb-validation', RWMB_JS_URL . 'validation/validation.js', [ 'jquery-validation-additional-methods', 'rwmb' ], RWMB_VER, true ); + + $locale = determine_locale(); + $locale_short = substr( $locale, 0, 2 ); + $locale = file_exists( RWMB_DIR . "js/validation/i18n/messages_$locale.js" ) ? $locale : $locale_short; + + if ( file_exists( RWMB_DIR . "js/validation/i18n/messages_$locale.js" ) ) { + wp_enqueue_script( 'jquery-validation-i18n', RWMB_JS_URL . "validation/i18n/messages_$locale.js", [ 'jquery-validation-additional-methods' ], '1.19.5', true ); + } + + RWMB_Helpers_Field::localize_script_once( 'rwmb-validation', 'rwmbValidation', [ + 'message' => esc_html( apply_filters( 'rwmb_validation_message_string', __( 'Please correct the errors highlighted below and try again.', 'meta-box' ) ) ), + ] ); } } diff --git a/vendor/wpmetabox/meta-box/inc/walkers/base.php b/vendor/wpmetabox/meta-box/inc/walkers/base.php index bda410bd2..32dc735a6 100644 --- a/vendor/wpmetabox/meta-box/inc/walkers/base.php +++ b/vendor/wpmetabox/meta-box/inc/walkers/base.php @@ -1,13 +1,9 @@ db_fields = array( + $this->db_fields = [ 'id' => 'value', 'parent' => 'parent', - ); + ]; $this->field = $field; $this->meta = (array) $meta; diff --git a/vendor/wpmetabox/meta-box/inc/walkers/input-list.php b/vendor/wpmetabox/meta-box/inc/walkers/input-list.php index 4c700e4f5..6e7991c5a 100644 --- a/vendor/wpmetabox/meta-box/inc/walkers/input-list.php +++ b/vendor/wpmetabox/meta-box/inc/walkers/input-list.php @@ -1,12 +1,8 @@ '; + public function start_lvl( &$output, $depth = 0, $args = [] ) { + $output .= '
                    '; } /** @@ -27,8 +23,8 @@ public function start_lvl( &$output, $depth = 0, $args = array() ) { * @param int $depth Depth of the item. * @param array $args An array of additional arguments. */ - public function end_lvl( &$output, $depth = 0, $args = array() ) { - $output .= ''; + public function end_lvl( &$output, $depth = 0, $args = [] ) { + $output .= '
                    '; } /** @@ -40,26 +36,14 @@ public function end_lvl( &$output, $depth = 0, $args = array() ) { * @param array $args An array of additional arguments. * @param int $current_object_id ID of the current item. */ - public function start_el( &$output, $object, $depth = 0, $args = array(), $current_object_id = 0 ) { + public function start_el( &$output, $object, $depth = 0, $args = [], $current_object_id = 0 ) { $attributes = RWMB_Field::call( 'get_attributes', $this->field, $object->value ); $output .= sprintf( - '
                  • ', + '', RWMB_Field::render_attributes( $attributes ), checked( in_array( $object->value, $this->meta ), true, false ), $object->label ); } - - /** - * Ends the element output, if needed. - * - * @param string $output Passed by reference. Used to append additional content. - * @param object $object The data object. - * @param int $depth Depth of the item. - * @param array $args An array of additional arguments. - */ - public function end_el( &$output, $object, $depth = 0, $args = array() ) { - $output .= '
                  • '; - } } diff --git a/vendor/wpmetabox/meta-box/inc/walkers/select-tree.php b/vendor/wpmetabox/meta-box/inc/walkers/select-tree.php index 1fd775ff9..c12c690db 100644 --- a/vendor/wpmetabox/meta-box/inc/walkers/select-tree.php +++ b/vendor/wpmetabox/meta-box/inc/walkers/select-tree.php @@ -1,18 +1,14 @@ parent ) ? $option->parent : 0; + $parent = $option->parent ?? 0; $children[ $parent ][] = $option; } diff --git a/vendor/wpmetabox/meta-box/inc/walkers/select.php b/vendor/wpmetabox/meta-box/inc/walkers/select.php index a0468d26d..727877840 100644 --- a/vendor/wpmetabox/meta-box/inc/walkers/select.php +++ b/vendor/wpmetabox/meta-box/inc/walkers/select.php @@ -1,12 +1,8 @@ { + $( e.target ).find( '.rwmb-date' ).each( transform ); + }, 0 ); } rwmb.$document diff --git a/vendor/wpmetabox/meta-box/js/datetime.js b/vendor/wpmetabox/meta-box/js/datetime.js index e4e94140c..a97a39427 100644 --- a/vendor/wpmetabox/meta-box/js/datetime.js +++ b/vendor/wpmetabox/meta-box/js/datetime.js @@ -79,7 +79,14 @@ } function init( e ) { - $( e.target ).find( '.rwmb-datetime' ).each( transform ); + /** + * WordPress sets localized data for jQuery UI datepicker at document ready. + * Using setTimeout to ensure the code runs after the localized data is set. + * @link https://wordpress.org/support/topic/inline-date-field-not-localization/ + */ + setTimeout( () => { + $( e.target ).find( '.rwmb-datetime' ).each( transform ); + }, 0 ); } setTimeI18n(); diff --git a/vendor/wpmetabox/meta-box/js/file.js b/vendor/wpmetabox/meta-box/js/file.js index 03b62df32..743240142 100644 --- a/vendor/wpmetabox/meta-box/js/file.js +++ b/vendor/wpmetabox/meta-box/js/file.js @@ -54,7 +54,7 @@ object_id: $metaBox.data( 'object-id' ), attachment_id: $this.data( 'attachment_id' ) }, function ( response ) { - if ( ! response.success ) { + if ( !response.success ) { alert( response.data ); } }, 'json' ); @@ -71,7 +71,7 @@ ui.placeholder.height( ui.helper.outerHeight() ); ui.placeholder.width( ui.helper.outerWidth() ); }, - update: function( event, ui ) { + update: function ( event, ui ) { ui.item.find( rwmb.inputSelectors ).first().trigger( 'mb_change' ); } } ); @@ -98,23 +98,25 @@ }; // Reset field when cloning. - file.resetClone = function() { + file.resetClone = function () { var $this = $( this ), $clone = $this.closest( '.rwmb-clone' ), - $list = $clone.find( '.rwmb-files' ), - $key = $clone.find( '.rwmb-file-index' ), - inputName = '_file_' + rwmb.uniqid(); + $list = $clone.find( '.rwmb-files' ); $list.empty(); - $clone.find( '.rwmb-file-input' ).attr( 'name', inputName + '[]' ).not( ':first' ).remove(); - $key.val( inputName ); + $clone.find( '.rwmb-file-new' ).each( function () { + var inputName = '_file_' + rwmb.uniqid(), + $key = $( this ).siblings( '.rwmb-file-index' ); + $( this ).find( '.rwmb-file-input' ).attr( 'name', inputName + '[]' ).not( ':first' ).remove(); + $key.val( inputName ); + } ); file.updateVisibility.call( $list ); }; // Set 'required' attribute. 'this' is the wrapper field input. - file.setRequired = function() { + file.setRequired = function () { var $this = $( this ), $uploaded = $this.find( '.rwmb-files' ), $inputs = $this.find( '.rwmb-file-new input' ); diff --git a/vendor/wpmetabox/meta-box/js/input-list.js b/vendor/wpmetabox/meta-box/js/input-list.js index d13fdd78b..ad9545c8c 100644 --- a/vendor/wpmetabox/meta-box/js/input-list.js +++ b/vendor/wpmetabox/meta-box/js/input-list.js @@ -24,7 +24,7 @@ $this.parent().siblings( '.rwmb-input-list' ).find( 'input' ).prop( 'checked', checked ).trigger( 'change' ); - checked = ! checked; + checked = !checked; $this.data( 'checked', checked ); } diff --git a/vendor/wpmetabox/meta-box/js/map.js b/vendor/wpmetabox/meta-box/js/map.js index ed54eed29..62002664c 100644 --- a/vendor/wpmetabox/meta-box/js/map.js +++ b/vendor/wpmetabox/meta-box/js/map.js @@ -25,41 +25,65 @@ // Initialize DOM elements initDomElements: function () { this.$canvas = this.$container.find( '.rwmb-map-canvas' ); - this.canvas = this.$canvas[0]; + this.canvas = this.$canvas[ 0 ]; this.$coordinate = this.$container.find( '.rwmb-map' ); this.addressField = this.$container.data( 'address-field' ); }, - // Initialize map elements - initMapElements: function () { - var defaultLoc = this.$canvas.data( 'default-loc' ), - latLng; + setCenter: function ( location ) { + if ( !( location instanceof google.maps.LatLng ) ) { + location = new google.maps.LatLng( parseFloat( location.lat ), parseFloat( location.lng ) ); + } + this.map.setCenter( location ); + if ( this.marker ) { + this.marker.setPosition( location ); + return; + } - defaultLoc = defaultLoc ? defaultLoc.split( ',' ) : [53.346881, - 6.258860]; - latLng = new google.maps.LatLng( defaultLoc[0], defaultLoc[1] ); // Initial position for map + this.marker = new google.maps.Marker( { + position: location, + map: this.map, + draggable: true, + } ); + }, + initMapElements: function () { this.map = new google.maps.Map( this.canvas, { - center: latLng, zoom: 14, streetViewControl: 0, mapTypeId: google.maps.MapTypeId.ROADMAP } ); - this.marker = new google.maps.Marker( {position: latLng, map: this.map, draggable: true} ); + + // If there is a saved location, don't set the default location. + if ( this.$coordinate.val() ) { + return; + } + + // Load default location if it's set. + let defaultLoc = this.$canvas.data( 'default-loc' ); + if ( defaultLoc ) { + const [ lat, lng ] = defaultLoc.split( ',' ); + return this.setCenter( { lat, lng } ); + } + + // Set default location to Dublin as a start. + const dublin = { lat: 53.346881, lng: -6.258860 }; + this.setCenter( dublin ); + + // Try to load current user location. Note that Geolocation API works only on HTTPS. + if ( location.protocol.includes( 'https' ) && navigator.geolocation ) { + navigator.geolocation.getCurrentPosition( position => this.setCenter( { lat: position.coords.latitude, lng: position.coords.longitude } ) ); + } }, - // Initialize marker position initMarkerPosition: function () { - var coordinate = this.$coordinate.val(), - location, - zoom; + const coordinate = this.$coordinate.val(); if ( coordinate ) { - location = coordinate.split( ',' ); - this.marker.setPosition( new google.maps.LatLng( location[0], location[1] ) ); - - zoom = location.length > 2 ? parseInt( location[2], 10 ) : 14; + const location = coordinate.split( ',' ); + this.setCenter( { lat: location[ 0 ], lng: location[ 1 ] } ); - this.map.setCenter( this.marker.position ); + const zoom = location.length > 2 ? parseInt( location[ 2 ], 10 ) : 14; this.map.setZoom( zoom ); } else if ( this.addressField ) { this.geocodeAddress( false ); @@ -76,7 +100,7 @@ */ if ( this.addressField.split( ',' ).length > 1 ) { var geocodeAddress = that.geocodeAddress.bind( that ); - var addressFields = this.addressField.split( ',' ).forEach( function( part ) { + var addressFields = this.addressField.split( ',' ).forEach( function ( part ) { var $field = that.findAddressField( part ); if ( null !== $field ) { $field.on( 'change', geocodeAddress ); @@ -111,7 +135,7 @@ }, refresh: function () { - if ( ! this.map ) { + if ( !this.map ) { return; } var zoom = this.map.getZoom(), @@ -142,12 +166,12 @@ source: function ( request, response ) { // if add region only search in that region var options = { - 'input': request.term, + 'input': request.term, 'componentRestrictions': { country: that.$canvas.data( 'region' ) } }; // Change Geocode to getPlacePredictions . autocomplete.getPlacePredictions( options, function ( results ) { - if ( results == null || ! results.length ) { + if ( results == null || !results.length ) { response( [ { value: '', label: i18n.no_results_string @@ -164,17 +188,16 @@ } ); }, select: function ( event, ui ) { - geocoder.geocode( { - 'placeId': ui.item.placeid - }, - function( responses, status ) { - if ( status == 'OK' ) { - var latLng = new google.maps.LatLng( responses[0].geometry.location.lat(), responses[0].geometry.location.lng() ); - that.map.setCenter( latLng ); - that.marker.setPosition( latLng ); - that.updateCoordinate( latLng ); - } - } ); + geocoder.geocode( { + 'placeId': ui.item.placeid + }, + function ( responses, status ) { + if ( status == 'OK' ) { + const latLng = new google.maps.LatLng( responses[ 0 ].geometry.location.lat(), responses[ 0 ].geometry.location.lng() ); + that.setCenter( latLng ); + that.updateCoordinate( latLng ); + } + } ); } } ); }, @@ -189,41 +212,40 @@ geocodeAddress: function ( notify ) { var address = this.getAddress(), that = this; - if ( ! address ) { + if ( !address ) { return; } if ( false !== notify ) { notify = true; } - geocoder.geocode( {'address': address}, function ( results, status ) { + geocoder.geocode( { 'address': address }, function ( results, status ) { if ( status !== google.maps.GeocoderStatus.OK ) { if ( notify ) { alert( i18n.no_results_string ); } return; } - that.map.setCenter( results[0].geometry.location ); - that.marker.setPosition( results[0].geometry.location ); - that.updateCoordinate( results[0].geometry.location ); + that.setCenter( results[ 0 ].geometry.location ); + that.updateCoordinate( results[ 0 ].geometry.location ); } ); }, // Get the address field. - getAddressField: function() { + getAddressField: function () { // No address field or more than 1 address fields, ignore - if ( ! this.addressField || this.addressField.split( ',' ).length > 1 ) { + if ( !this.addressField || this.addressField.split( ',' ).length > 1 ) { return null; } return this.findAddressField( this.addressField ); }, // Get the address value for geocoding. - getAddress: function() { + getAddress: function () { var that = this; return this.addressField.split( ',' ) - .map( function( part ) { + .map( function ( part ) { part = that.findAddressField( part ); return null === part ? '' : part.val(); } ) @@ -231,9 +253,9 @@ }, // Find address field based on its name attribute. Auto search inside groups when needed. - findAddressField: function( fieldName ) { + findAddressField: function ( fieldName ) { // Not in a group. - var $address = $( 'input[name="' + fieldName + '"]'); + var $address = $( 'input[name="' + fieldName + '"]' ); if ( $address.length ) { return $address; } diff --git a/vendor/wpmetabox/meta-box/js/media.js b/vendor/wpmetabox/meta-box/js/media.js index e983d08ed..60a961c1c 100644 --- a/vendor/wpmetabox/meta-box/js/media.js +++ b/vendor/wpmetabox/meta-box/js/media.js @@ -135,7 +135,7 @@ collection.reset(); } ); - collection.on( 'add remove reset', _.debounce( function () { + collection.on( 'all', _.debounce( function() { var ids = collection.pluck( 'id' ).join( ',' ); that.$input.val( ids ).trigger( 'change', [that.$( '.rwmb-media-input' )] ); }, 500 ) ); diff --git a/vendor/wpmetabox/meta-box/js/modal.js b/vendor/wpmetabox/meta-box/js/modal.js new file mode 100644 index 000000000..aff158833 --- /dev/null +++ b/vendor/wpmetabox/meta-box/js/modal.js @@ -0,0 +1,132 @@ +( function ( $, rwmb ) { + 'use strict'; + + const $body = $( 'body' ); + + const defaultOptions = { + wrapper: `
                    +
                    +

                    + +
                    +
                    +
                    `, + markupIframe: '', + markupOverlay: '
                    ', + removeElement: '', + removeElementDefault: '#adminmenumain, #wpadminbar, #wpfooter, .row-actions, .form-wrap.edit-term-notes, #screen-meta-links, .wp-heading-inline, .wp-header-end', + callback: null, + closeModalCallback: null, + isBlockEditor: false, + $objectId: null, + $objectDisplay: null + }; + + $.fn.rwmbModal = function ( options = {} ) { + options = { + ...defaultOptions, + ...options + }; + + if ( $( '.rwmb-modal' ).length === 0 ) { + return; + } + + const $this = $( this ), + $modal = $( '.rwmb-modal' ); + + let $input = $this.closest( '.rwmb-input' ); + if ( $input.find( '.rwmb-clone' ).length > 0 && $this.closest( '.rwmb-clone' ).length > 0 ) { + $input = $this.closest( '.rwmb-clone' ); + } + + $this.click( function ( e ) { + e.preventDefault(); + + $modal.find( '.rwmb-modal-title h2' ).html( $this.html() ); + $modal.find( '.rwmb-modal-content' ).html( options.markupIframe.replace( '{URL}', $this.data( 'url' ) ) ); + $( '#rwmb-modal-iframe' ).on( 'load', function () { + const $contents = $( this ).contents(); + options.isBlockEditor = $contents.find( 'body' ).hasClass( 'block-editor-page' ); + + if ( options.removeElement !== '' ) { + $contents.find( options.removeElement ).remove(); + } + + $modal.find( '.rwmb-modal-title' ).css( 'background-color', '' ); + if ( options.isBlockEditor ) { + $modal.find( '.rwmb-modal-title' ).css( 'background-color', '#fff' ); + } + + $contents + .find( options.removeElementDefault ).remove().end() + .find( '.rwmb-modal-add-button' ).parent().remove(); + $contents.find( 'html' ).css( 'padding-top', 0 ).end() + .find( '#wpcontent' ).css( 'margin-left', 0 ).end() + .find( 'a' ).on( 'click', e => e.preventDefault() ); + + if ( options.callback !== null && typeof options.callback === 'function' ) { + options.callback( $modal, $contents ); + } + + $body.addClass( 'rwmb-modal-show' ); + $( '.rwmb-modal-overlay' ).fadeIn( 'medium' ); + $modal.fadeIn( 'medium' ); + + return false; + } ); + + $( '.rwmb-modal-close' ).on( 'click', function ( event ) { + if ( options.closeModalCallback !== null && typeof options.closeModalCallback === 'function' ) { + options.closeModalCallback( $( '#rwmb-modal-iframe' ).contents(), $input ); + } + + $modal.fadeOut( 'medium' ); + $( '.rwmb-modal-overlay' ).fadeOut( 'medium' ); + $body.removeClass( 'rwmb-modal-show' ); + + // If not add new + if ( !options.$objectId || !options.$objectDisplay ) { + $( this ).off( event ); + return; + } + + // Select, select advanced, select tree. + const $select = $input.find( 'select' ); + if ( $select.length > 0 ) { + $select.prepend( $( '