diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..79207a40 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,22 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +# WordPress Coding Standards +# https://make.wordpress.org/core/handbook/coding-standards/ + +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = tab +indent_size = 4 + +[{.jshintrc,*.json,*.yml}] +indent_style = space +indent_size = 2 + +[{*.txt,wp-config-sample.php}] +end_of_line = crlf diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 782125e7..00000000 --- a/.eslintrc.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "extends": "plugin:@wordpress/eslint-plugin/es5", - "env": { - "browser": true, - "jquery": true - }, - "globals": { - "Raphael": "readonly", - "getAnchors": "readonly" - }, - "rules": { - "camelcase": 0, - "eqeqeq": 0, - "no-mixed-operators": 0, - "no-redeclare": 0, - "no-shadow": 0, - "no-unused-expressions": 0, - "no-unused-vars": 0, - "vars-on-top": 0 - } -} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e7b91e45..8bf180e7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,11 +1,11 @@ name: Tests, Behat, Coding Standards on: push jobs: - test: + test-unit: runs-on: ubuntu-latest strategy: matrix: - php-versions: ['7.3', '7.2', '5.4'] + php-versions: ['8.3', '7.4'] steps: - uses: actions/checkout@master - name: Setup PHP @@ -14,70 +14,69 @@ jobs: php-version: ${{ matrix.php-versions }} extensions: mbstring, intl ini-values: post_max_size=256M, short_open_tag=On - tools: phpunit, composer - - name: Set COMPOSER environment variable for 5.4 - if: matrix.php-versions == '5.4' - run: echo "COMPOSER=composer-php-5-4.json" >> $GITHUB_ENV - - name: Run tests + tools: composer + - name: Install run: | composer install - ./vendor/bin/phpunit -c ./phpunit.xml.dist - behat: - runs-on: ubuntu-latest - services: - mysql: - image: mysql:5.7 - env: - MYSQL_ALLOW_EMPTY_PASSWORD: yes - MYSQL_DATABASE: pluginkollektiv_antispambee_behat - ports: - - '8888:3306' - options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 - strategy: - matrix: - php: ['8'] - wordpress: ['nightly', 'latest'] - include: - - php: '7.4' - wordpress: '5.5' - - php: '7.4' - wordpress: '5.4' - - php: '7.3' - wordpress: '5.3' - - php: '7.3' - wordpress: '5.2' - - php: '7.3' - wordpress: '5.1' - - php: '7.2' - wordpress: '4.9' - - php: '7.2' - wordpress: '4.8' - - php: '7.2' - wordpress: '4.7' - - php: '7.2' - wordpress: '4.6' - steps: - - uses: actions/checkout@master - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: mbstring, intl, pdo_mysql, zip - ini-values: post_max_size=256M, short_open_tag=On - tools: phpunit, composer - - name: Start mysql service - run: sudo /etc/init.d/mysql start - - name: Install XVFB - run: sudo apt-get update && sudo apt-get install xvfb - name: Run tests run: | - composer install --ignore-platform-req=php - ./bin/behat.sh - env: - WORDPRESS_VERSION: ${{ matrix.wordpress }} - NAP_LENGTH: 10 - - name: Cleanup xvfb - uses: bcomnes/cleanup-xvfb@v1 + composer test:unit +# behat: +# runs-on: ubuntu-latest +# services: +# mysql: +# image: mysql:5.7 +# env: +# MYSQL_ALLOW_EMPTY_PASSWORD: yes +# MYSQL_DATABASE: pluginkollektiv_antispambee_behat +# ports: +# - '8888:3306' +# options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 +# strategy: +# matrix: +# php: ['8'] +# wordpress: ['nightly', 'latest'] +# include: +# - php: '7.4' +# wordpress: '5.5' +# - php: '7.4' +# wordpress: '5.4' +# - php: '7.3' +# wordpress: '5.3' +# - php: '7.3' +# wordpress: '5.2' +# - php: '7.3' +# wordpress: '5.1' +# - php: '7.2' +# wordpress: '4.9' +# - php: '7.2' +# wordpress: '4.8' +# - php: '7.2' +# wordpress: '4.7' +# - php: '7.2' +# wordpress: '4.6' +# steps: +# - uses: actions/checkout@master +# - name: Setup PHP +# uses: shivammathur/setup-php@v2 +# with: +# php-version: ${{ matrix.php }} +# extensions: mbstring, intl, pdo_mysql, zip +# ini-values: post_max_size=256M, short_open_tag=On +# tools: phpunit, composer +# - name: Start mysql service +# run: sudo /etc/init.d/mysql start +# - name: Install XVFB +# run: sudo apt-get update && sudo apt-get install xvfb +# - name: Run tests +# run: | +# composer install --ignore-platform-req=php +# ./bin/behat.sh +# env: +# WORDPRESS_VERSION: ${{ matrix.wordpress }} +# NAP_LENGTH: 10 +# - name: Cleanup xvfb +# uses: bcomnes/cleanup-xvfb@v1 quality: runs-on: ubuntu-latest steps: @@ -85,16 +84,10 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '7.2' - extensions: mbstring, intl - ini-values: post_max_size=256M, short_open_tag=On - tools: phpunit, composer - - uses: actions/setup-node@v2 - with: - node-version: '14' + php-version: '8.2' + tools: composer - name: Run code style checks for CSS, JavaScript and PHP run: | - composer install - npm install - composer lint-all + composer install --ignore-platform-req=php + ./vendor/bin/phpcs --config-set ignore_warnings_on_exit 1 composer cs diff --git a/.gitignore b/.gitignore index 0436199f..d0402aa1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,14 @@ -css/*.min.css -js/*.min.js +assets/dist .idea/ +build/ node_modules/ tmp/ vendor/ chromedriver +composer.lock driver.tar.gz driver.zip geckodrier nohup.out package-lock.json +yarn.lock diff --git a/.stylelintrc.json b/.stylelintrc.json deleted file mode 100644 index 68e038b0..00000000 --- a/.stylelintrc.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "@wordpress/stylelint-config", - "rules": { - "declaration-property-unit-allowed-list": null, - "font-weight-notation": null, - "font-family-no-missing-generic-family-keyword": null, - "no-descending-specificity": null, - "selector-class-pattern": null, - "selector-id-pattern": null - } -} diff --git a/CHANGELOG.md b/CHANGELOG.md index 89ee8352..a14100e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,55 @@ ## Changelog ## +### 3.0.0 – WIP ### +* **English** + * Complete code rewrite and backend UI overhaul + * Allows to extend Antispam Bee with own rules + * Allows to use Antispam Bee rules for other reactions than comments, for example, forms + +* **Deutsch** + * Kompletter Code-Rewrite und Überarbeitung des Backend-User-Interfaces + * Möglichkeit der Erweiterung von Antispam Bee um eigene Spam-Regeln + * Erlaubt die Nutzung von Antispam Bee für andere Reaktionen als Kommentare, beispielsweise Formulare + +### 2.11.3 ### +* **English** + * Fix: Multiselect for "Delete comments by spam reasons" was not saving values + * Fix: Fix broken link for ISO country codes + * Maintenance: Added test for PHP 8.2 + * Maintenance: Tested up to WordPress 6.2 + +* **Deutsch** + * Behoben: Multiselect für "Kommentare aus Spamgründen löschen" speicherte keine Werte + * Fix: Fehlerhafter Link für ISO-Ländercodes behoben + * Wartung: Test für PHP 8.2 hinzugefügt + * Wartung: Getestet mit WordPress 6.2 + +### 2.11.2 ### +* **English** + * Tweak: remove superfluous translations + * Tweak: make FAQ link an anchor link + * Fix: spam counter no longer raises a warning with PHP 8.1 if no spam is present yet + * Fix: spam reasons are now localized correctly + * Fix: Translations were loaded twice on some admin pages + * Maintenance: Tested up to WordPress 6.1 + +* **Deutsch** + * Tweak: Überflüssige Übersetzungen entfernt + * Tweak: Link zu den FAQ ist jetzt ein Anker-Link + * Fix: Der Spam-Zähler erzeugt mit PHP 8.1 keine Warnung mehr, wenn noch kein Spam vorhanden ist + * Fix: Spam-Gründe werden nun korrekt übersetzt + * Fix: Übersetzungen wurden auf einzelnen Adminseiten doppelt geladen + * Wartung: Getestet mit WordPress 6.1 + +### 2.11.1 ### +* **English** + * Tweak: remove superfluous type attribute from inline script tag + * Maintenance: Tested up to WordPress 6.0 + +* **Deutsch** + * Tweak: Überflüssiges type-Attribut von script-Tag entfernt + * Wartung: Getestet mit WordPress 6.0 + ### 2.11.0 ### * **English** * Fix: Allow empty comments if `allow_empty_comment` is set to true diff --git a/README.md b/README.md index 4f5f5ad1..ea628f01 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@ [![Build status](https://github.com/pluginkollektiv/antispam-bee/actions/workflows/tests.yml/badge.svg)](https://github.com/pluginkollektiv/antispam-bee/actions/workflows/tests.yml) [![Current Antispam Bee version](https://img.shields.io/wordpress/plugin/v/antispam-bee.svg)](https://wordpress.org/plugins/antispam-bee/) [![Number of downloads](https://img.shields.io/wordpress/plugin/dt/antispam-bee.svg)](https://wordpress.org/plugins/antispam-bee/advanced/) [![Number of active installs](https://img.shields.io/wordpress/plugin/installs/antispam-bee.svg)](https://wordpress.org/plugins/antispam-bee/advanced/) [![WordPress plugin rating](https://img.shields.io/wordpress/plugin/r/antispam-bee.svg)](https://wordpress.org/plugins/antispam-bee/#reviews) [![Donate with PayPal](https://img.shields.io/badge/PayPal-Donate-yellow.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=TD4AMD2D8EMZW) -Antispam plugin with a sophisticated toolset for effective day to day comment and trackback spam-fighting. Built with data protection and privacy in mind. +Antispam plugin with a sophisticated toolset for effective day to day comment and linkback spam-fighting. Built with data protection and privacy in mind, and extendable with own anti-spam rules and possibility to use Antispam Bee rules for other reactions than comments and linkbacks. ## Description ## -Say Goodbye to comment spam on your WordPress blog or website. *Antispam Bee* blocks spam comments and trackbacks effectively and without captchas. It is free of charge, ad-free and compliant with European data privacy standards. +Say Goodbye to comment spam on your WordPress blog or website. *Antispam Bee* blocks spam comments and linkbacks effectively and without captchas. It is free of charge, ad-free and compliant with European data privacy standards. ### Feature/Settings Overview ### * Trust approved commenters. @@ -45,7 +45,7 @@ Say Goodbye to comment spam on your WordPress blog or website. *Antispam Bee* bl * If you don’t know how to install a plugin for WordPress, [here’s how](http://codex.wordpress.org/Managing_Plugins#Installing_Plugins). ### Requirements ### -* PHP 5.2.4 or greater +* PHP 7.0 or greater * WordPress 4.5 or greater ### Settings ### diff --git a/antispam_bee.php b/antispam_bee.php old mode 100755 new mode 100644 index afdf2a17..f56c9e11 --- a/antispam_bee.php +++ b/antispam_bee.php @@ -1,3044 +1,104 @@ 0, - ), - '', - 'no' - ); - - if ( self::get_option( 'cronjob_enable' ) ) { - self::init_scheduled_hook(); - } - } - - - /** - * Action to deactivate the plugin - * - * @since 0.1 - * @since 2.4 - */ - public static function deactivate() { - self::clear_scheduled_hook(); - } - - - /** - * Action deleting the plugin - * - * @since 2.4 - */ - public static function uninstall() { - if ( ! self::get_option( 'delete_data_on_uninstall' ) ) { - return; - } - global $wpdb; - - delete_option( 'antispam_bee' ); - $wpdb->query( 'OPTIMIZE TABLE `' . $wpdb->options . '`' ); - - //phpcs:disable WordPress.DB.PreparedSQL.NotPrepared - $sql = 'delete from `' . $wpdb->commentmeta . '` where `meta_key` IN ("antispam_bee_iphash", "antispam_bee_reason")'; - $wpdb->query( $sql ); - //phpcs:enable WordPress.DB.PreparedSQL.NotPrepared - } - - - - /* - * ############################ - * ######## INTERNAL ######## - * ############################ - */ - - /** - * Initialization of the internal variables - * - * @since 2.4 - * @since 2.7.0 - * @since 2.10.0 Change renamed country option names in options array - */ - private static function _init_internal_vars() { - self::$_base = plugin_basename( __FILE__ ); - - $salt = defined( 'NONCE_SALT' ) ? NONCE_SALT : ABSPATH; - self::$_salt = substr( sha1( $salt ), 0, 10 ); - - self::$defaults = array( - 'options' => array( - 'regexp_check' => 1, - 'spam_ip' => 1, - 'already_commented' => 1, - 'gravatar_check' => 0, - 'time_check' => 0, - 'ignore_pings' => 0, - - 'dashboard_chart' => 0, - 'dashboard_count' => 0, - - 'country_code' => 0, - 'country_denied' => '', - 'country_allowed' => '', - - 'translate_api' => 0, - 'translate_lang' => array(), - - 'bbcode_check' => 1, - - 'flag_spam' => 1, - 'email_notify' => 0, - 'no_notice' => 0, - 'cronjob_enable' => 0, - 'cronjob_interval' => 0, - - 'ignore_filter' => 0, - 'ignore_type' => 0, - - 'reasons_enable' => 0, - 'ignore_reasons' => array(), - - 'delete_data_on_uninstall' => 1, - ), - 'reasons' => array( - 'css' => esc_attr__( 'Honeypot', 'antispam-bee' ), - 'time' => esc_attr__( 'Comment time', 'antispam-bee' ), - 'empty' => esc_attr__( 'Empty Data', 'antispam-bee' ), - 'localdb' => esc_attr__( 'Local DB Spam', 'antispam-bee' ), - 'server' => esc_attr__( 'Fake IP', 'antispam-bee' ), - 'country' => esc_attr__( 'Country Check', 'antispam-bee' ), - 'bbcode' => esc_attr__( 'BBCode', 'antispam-bee' ), - 'lang' => esc_attr__( 'Comment Language', 'antispam-bee' ), - 'regexp' => esc_attr__( 'Regular Expression', 'antispam-bee' ), - 'title_is_name' => esc_attr__( 'Identical Post title and blog title', 'antispam-bee' ), - 'manually' => esc_attr__( 'Manually', 'antispam-bee' ), - ), - ); - } - - /** - * Check and return an array key - * - * @since 2.4.2 - * @since 2.10.0 Only return `null` if option does not exist. - * - * @param array $array Array with values. - * @param string $key Name of the key. - * @return mixed Value of the requested key. - */ - public static function get_key( $array, $key ) { - if ( empty( $array ) || empty( $key ) || ! isset( $array[ $key ] ) ) { - return null; - } - - return $array[ $key ]; - } - - /** - * Check if comment is a ping (pingback, trackback or something similar) - * - * @since 2.10.0 - * - * @param array $comment Treated commentary data. - * @return boolean `true` if ping and `false` if classic comment - */ - public static function is_ping( $comment ) { - $types = array( 'pingback', 'trackback', 'pings' ); - $is_ping = false; - - if ( in_array( self::get_key( $comment, 'comment_type' ), $types, true ) ) { - $is_ping = true; - } - - return apply_filters( 'antispam_bee_is_ping', $is_ping, $comment ); - } - - /** - * Localization of the admin pages - * - * @since 0.1 - * @since 2.4 - * - * @param string $page Mark the page. - * @return boolean True on success. - */ - private static function _current_page( $page ) { - // phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification - switch ( $page ) { - case 'dashboard': - return ( empty( $GLOBALS['pagenow'] ) || ( ! empty( $GLOBALS['pagenow'] ) && 'index.php' === $GLOBALS['pagenow'] ) ); - - case 'options': - return ( ! empty( $_GET['page'] ) && 'antispam_bee' === $_GET['page'] ); - - case 'plugins': - return ( ! empty( $GLOBALS['pagenow'] ) && 'plugins.php' === $GLOBALS['pagenow'] ); - - case 'admin-post': - return ( ! empty( $GLOBALS['pagenow'] ) && 'admin-post.php' === $GLOBALS['pagenow'] ); - - case 'edit-comments': - return ( ! empty( $GLOBALS['pagenow'] ) && 'edit-comments.php' === $GLOBALS['pagenow'] ); - - default: - return false; - } - // phpcs:enable WordPress.CSRF.NonceVerification.NoNonceVerification - } - - - /** - * Integration of the localization file - * - * @since 0.1 - * @since 2.4 - */ - public static function load_plugin_lang() { - load_plugin_textdomain( - 'antispam-bee' - ); - } - - - /** - * Add the link to the settings - * - * @since 1.1 - * - * @param array $data The action link array. - * @return array $data The action link array. - */ - public static function init_action_links( $data ) { - if ( ! current_user_can( 'manage_options' ) ) { - return $data; - } - - return array_merge( - $data, - array( - sprintf( - '%s', - add_query_arg( - array( - 'page' => 'antispam_bee', - ), - admin_url( 'options-general.php' ) - ), - esc_attr__( 'Settings', 'antispam-bee' ) - ), - ) - ); - } - - /** - * Meta links of the plugin - * - * @since 0.1 - * @since 2.6.2 - * - * @param array $input Existing links. - * @param string $file Current page. - * @return array $data Modified links. - */ - public static function init_row_meta( $input, $file ) { - if ( $file !== self::$_base ) { - return $input; - } - - return array_merge( - $input, - array( - '' . esc_html__( 'Donate', 'antispam-bee' ) . '', - '' . esc_html__( 'Support', 'antispam-bee' ) . '', - ) - ); - } - - /* - * ############################ - * ####### RESOURCES ######## - * ############################ - */ - - /** - * Registration of resources (CSS & JS) - * - * @since 1.6 - * @since 2.4.5 - */ - public static function init_plugin_sources() { - $plugin = get_plugin_data( __FILE__ ); - - wp_register_script( - 'ab_script', - plugins_url( 'js/scripts.min.js', __FILE__ ), - array( 'jquery' ), - $plugin['Version'] - ); - - wp_register_style( - 'ab_style', - plugins_url( 'css/styles.min.css', __FILE__ ), - array( 'dashicons' ), - $plugin['Version'] - ); - } - - - /** - * Initialization of the option page - * - * @since 0.1 - * @since 2.4.3 - */ - public static function add_sidebar_menu() { - $page = add_options_page( - 'Antispam Bee', - 'Antispam Bee', - 'manage_options', - 'antispam_bee', - array( - 'Antispam_Bee_GUI', - 'options_page', - ) - ); - - add_action( - 'admin_print_scripts-' . $page, - array( - __CLASS__, - 'add_options_script', - ) - ); - - add_action( - 'admin_print_styles-' . $page, - array( - __CLASS__, - 'add_options_style', - ) - ); - - add_action( - 'load-' . $page, - array( - __CLASS__, - 'init_options_page', - ) - ); - } - - - /** - * Initialization of JavaScript - * - * @since 1.6 - * @since 2.4 - */ - public static function add_options_script() { - wp_enqueue_script( 'ab_script' ); - } - - - /** - * Initialization of Stylesheets - * - * @since 1.6 - * @since 2.4 - */ - public static function add_options_style() { - wp_enqueue_style( 'ab_style' ); - } - - - /** - * Integration of the GUI - * - * @since 2.4 - */ - public static function init_options_page() { - require_once dirname( __FILE__ ) . '/inc/gui.class.php'; - } - - - - /* - * ############################ - * ####### DASHBOARD ######## - * ############################ - */ - - /** - * Display the spam counter on the dashboard - * - * @since 0.1 - * @since 2.6.5 - * - * @param array $items Initial array with dashboard items. - * @return array $items Merged array with dashboard items. - */ - public static function add_dashboard_count( $items = array() ) { - if ( ! current_user_can( 'manage_options' ) || ! self::get_option( 'dashboard_count' ) ) { - return $items; - } - - echo ''; - - $items[] = '' . esc_html( - sprintf( - // translators: The number of spam comments Antispam Bee blocked so far. - __( '%s Blocked', 'antispam-bee' ), - self::_get_spam_count() - ) - ) . ''; - - return $items; - } - - /** - * Initialize the dashboard chart - * - * @since 1.9 - * @since 2.5.6 - */ - public static function add_dashboard_chart() { - if ( ! current_user_can( 'publish_posts' ) || ! self::get_option( 'dashboard_chart' ) ) { - return; - } +function pre_init(): void { + // Load the translation, as they might be needed in pre_init. + add_action( 'plugins_loaded', __NAMESPACE__ . '\load_textdomain', 5 ); - wp_add_dashboard_widget( - 'ab_widget', - 'Antispam Bee', - array( - __CLASS__, - 'show_spam_chart', - ) - ); + // Check, if the min. required PHP version is available and if not, show an admin notice. + if ( version_compare( PHP_VERSION, '5.6', '<' ) ) { + add_action( 'admin_notices', __NAMESPACE__ . '\min_php_version_error' ); - add_action( - 'admin_head', - array( - __CLASS__, - 'add_dashboard_style', - ) - ); + // Stop the further processing of the plugin. + return; } - /** - * Print dashboard styles - * - * @since 1.9.0 - * @since 2.5.8 - */ - public static function add_dashboard_style() { - $plugin = get_plugin_data( __FILE__ ); + // Check, if the DOMDocument class exists. + if ( ! class_exists( 'DOMDocument' ) ) { + add_action( 'admin_notices', __NAMESPACE__ . '\domdocument_class_error' ); - wp_register_style( - 'ab_chart', - plugins_url( 'css/dashboard.min.css', __FILE__ ), - array(), - $plugin['Version'] - ); - - wp_print_styles( 'ab_chart' ); - } - - - /** - * Print dashboard scripts - * - * @since 1.9.0 - * @since 2.5.8 - */ - public static function add_dashboard_script() { - if ( ! self::get_option( 'daily_stats' ) ) { - return; - } - - $plugin = get_plugin_data( __FILE__ ); - - wp_enqueue_script( - 'raphael', - plugins_url( 'js/raphael.min.js', __FILE__ ), - array(), - '2.1.0', - true - ); - - wp_enqueue_script( - 'ab-raphael', - plugins_url( 'js/raphael.helper.min.js', __FILE__ ), - array( 'raphael' ), - $plugin['Version'], - true - ); - - wp_enqueue_script( - 'ab_chart_js', - plugins_url( 'js/dashboard.min.js', __FILE__ ), - array( 'jquery', 'ab-raphael' ), - $plugin['Version'], - true - ); - } - - /** - * Print dashboard html - * - * @since 1.9.0 - * @since 2.5.8 - */ - public static function show_spam_chart() { - $items = (array) self::get_option( 'daily_stats' ); - - if ( empty( $items ) ) { - echo sprintf( - '

%s

', - esc_html__( 'No data available.', 'antispam-bee' ) - ); - - return; - } - - self::add_dashboard_script(); - - ksort( $items, SORT_NUMERIC ); - - $html = "\n"; - - $html .= "\n"; - foreach ( $items as $date => $count ) { - $html .= '\n"; - } - $html .= "\n"; - - $html .= "\n"; - foreach ( $items as $date => $count ) { - $html .= '\n"; - } - $html .= "\n"; - - $html .= "
' . date_i18n( 'j. F Y', $date ) . "
' . (int) $count . "
\n"; - - echo wp_kses_post( '
' . $html . '
' ); - } - - /* - * ############################ - * ######## OPTIONS ######### - * ############################ - */ - - /** - * Get all plugin options - * - * @since 2.4 - * @since 2.6.1 - * - * @return array $options Array with option fields. - */ - public static function get_options() { - $options = wp_cache_get( 'antispam_bee' ); - if ( ! $options ) { - wp_cache_set( - 'antispam_bee', - $options = get_option( 'antispam_bee' ) - ); - } - - if ( null === self::$defaults ) { - self::_init_internal_vars(); - } - - return wp_parse_args( - $options, - self::$defaults['options'] - ); - } - - /** - * Get single option field - * - * @since 0.1 - * @since 2.4.2 - * - * @param string $field Field name. - * @return mixed Field value. - */ - public static function get_option( $field ) { - $options = self::get_options(); - - return self::get_key( $options, $field ); - } - - - /** - * Update single option field - * - * @since 0.1 - * @since 2.4 - * - * @param string $field Field name. - * @param mixed $value The Field value. - */ - private static function _update_option( $field, $value ) { - self::update_options( - array( - $field => $value, - ) - ); - } - - - /** - * Update multiple option fields - * - * @since 0.1 - * @since 2.6.1 - * - * @param array $data Array with plugin option fields. - */ - public static function update_options( $data ) { - $options = get_option( 'antispam_bee' ); - - if ( is_array( $options ) ) { - $options = array_merge( - $options, - $data - ); - } else { - $options = $data; - } - - update_option( - 'antispam_bee', - $options - ); - - wp_cache_set( - 'antispam_bee', - $options - ); - } - - - - /* - * ############################ - * ######## CRONJOBS ######## - * ############################ - */ - - /** - * Execution of the daily cronjobs - * - * @since 0.1 - * @since 2.4 - */ - public static function start_daily_cronjob() { - if ( ! self::get_option( 'cronjob_enable' ) ) { - return; - } - - self::_update_option( - 'cronjob_timestamp', - time() - ); - - self::_delete_old_spam(); - } - - - /** - * Delete old spam comments - * - * @since 0.1 - * @since 2.4 - */ - private static function _delete_old_spam() { - $days = (int) self::get_option( 'cronjob_interval' ); - - if ( empty( $days ) ) { - return false; - } - - global $wpdb; - - $wpdb->query( - $wpdb->prepare( - "DELETE c, cm FROM `$wpdb->comments` AS c LEFT JOIN `$wpdb->commentmeta` AS cm ON (c.comment_ID = cm.comment_id) WHERE c.comment_approved = 'spam' AND SUBDATE(NOW(), %d) > c.comment_date_gmt", - $days - ) - ); - - $wpdb->query( "OPTIMIZE TABLE `$wpdb->comments`" ); - } - - - /** - * Initialization of the cronjobs - * - * @since 0.1 - * @since 2.4 - */ - public static function init_scheduled_hook() { - if ( ! wp_next_scheduled( 'antispam_bee_daily_cronjob' ) ) { - wp_schedule_event( - time(), - 'daily', - 'antispam_bee_daily_cronjob' - ); - } - } - - - /** - * Deletion of the cronjobs - * - * @since 0.1 - * @since 2.4 - */ - public static function clear_scheduled_hook() { - if ( wp_next_scheduled( 'antispam_bee_daily_cronjob' ) ) { - wp_clear_scheduled_hook( 'antispam_bee_daily_cronjob' ); - } - } - - - - /* - * ############################ - * ###### SPAM CHECK ######## - * ############################ - */ - - /** - * Check POST values - * - * @since 0.1 - * @since 2.6.3 - */ - public static function precheck_incoming_request() { - // phpcs:disable WordPress.Security.NonceVerification.Missing - if ( is_feed() || is_trackback() || empty( $_POST ) || self::_is_mobile() ) { - return; - } - - $request_uri = self::get_key( $_SERVER, 'REQUEST_URI' ); - $request_path = self::parse_url( $request_uri, 'path' ); - - if ( strpos( $request_path, 'wp-comments-post.php' ) === false ) { - return; - } - - $post_id = (int) self::get_key( $_POST, 'comment_post_ID' ); - $hidden_field = self::get_key( $_POST, 'comment' ); - $plugin_field = self::get_key( $_POST, self::get_secret_name_for_post( $post_id ) ); - - if ( ! empty( $hidden_field ) ) { - $_POST['ab_spam__hidden_field'] = 1; - } else { - $_POST['comment'] = $plugin_field; - unset( $_POST[ self::get_secret_name_for_post( $post_id ) ] ); - } - // phpcs:enable WordPress.Security.NonceVerification.Missing - } - - - /** - * Check incoming requests for spam - * - * @since 0.1 - * @since 2.6.3 - * @since 2.10.0 Refactoring of code if pings are allowed and if is ping - * - * @param array $comment Untreated comment. - * @return array $comment Treated comment. - */ - public static function handle_incoming_request( $comment ) { - $comment['comment_author_IP'] = self::get_client_ip(); - - $request_uri = self::get_key( $_SERVER, 'REQUEST_URI' ); - $request_path = self::parse_url( $request_uri, 'path' ); - - if ( empty( $request_path ) ) { - return self::_handle_spam_request( - $comment, - 'empty' - ); - } - - $pings_allowed = ! self::get_option( 'ignore_pings' ); - - // phpcs:disable WordPress.Security.NonceVerification.Missing - // Everybody can post. - if ( strpos( $request_path, 'wp-comments-post.php' ) !== false && ! empty( $_POST ) ) { - // phpcs:enable WordPress.Security.NonceVerification.Missing - $status = self::_verify_comment_request( $comment ); - - if ( ! empty( $status['reason'] ) ) { - return self::_handle_spam_request( - $comment, - $status['reason'] - ); - } - } elseif ( self::is_ping( $comment ) && $pings_allowed ) { - $status = self::_verify_trackback_request( $comment ); - - if ( ! empty( $status['reason'] ) ) { - return self::_handle_spam_request( - $comment, - $status['reason'], - true - ); - } - } - - return $comment; - } - - /** - * Prepares the replacement of the comment field with output buffering. - * - * @since 2.10.0 - */ - public static function prepare_comment_field_output_buffering() { - if ( is_feed() || is_trackback() || is_robots() || self::_is_mobile() ) { - return; - } - - ob_start( - array( - 'Antispam_Bee', - 'prepare_comment_field', - ) - ); - } - - - /** - * Prepares the replacement of the comment field - * - * @since 0.1 - * @since 2.4 - * @since 2.10.0 Changes needed because of new way to add the honeypot field via filter instead of output buffering - * - * @param string $data Markup of the comment field or whole page (depending on ob option). - */ - public static function prepare_comment_field( $data ) { - if ( empty( $data ) ) { - return $data; - } - - if ( ! preg_match( '# (?# match the whole textarea tag ) - '; - - $output .= $id_script; - $output .= $init_time_field; - - return $output; } + // If all checks were successful, load the plugin. + require_once PLUGIN_PATH . 'src/load.php'; +} - /** - * Check the trackbacks - * - * @since 2.4 - * @since 2.7.0 - * - * @param array $comment Trackback data. - * @return array Array with suspected reason. - */ - private static function _verify_trackback_request( $comment ) { - $ip = self::get_key( $comment, 'comment_author_IP' ); - $url = self::get_key( $comment, 'comment_author_url' ); - $body = self::get_key( $comment, 'comment_content' ); - $post_id = self::get_key( $comment, 'comment_post_ID' ); - $type = self::get_key( $comment, 'comment_type' ); - $blog_name = self::get_key( $comment, 'comment_author' ); - - if ( empty( $url ) || empty( $body ) ) { - return array( - 'reason' => 'empty', - ); - } - - if ( empty( $ip ) ) { - return array( - 'reason' => 'empty', - ); - } - - if ( 'pingback' === $type && self::_pingback_from_myself( $url, $post_id ) ) { - return; - } - - if ( self::is_trackback_post_title_blog_name_spam( $body, $blog_name ) ) { - return array( - 'reason' => 'title_is_name', - ); - } - - $options = self::get_options(); +/** + * Load plugin textdomain. + * + * @since 1.0.0 + */ +function load_textdomain(): void { + load_plugin_textdomain( 'antispam-bee' ); +} - if ( $options['bbcode_check'] && self::_is_bbcode_spam( $body ) ) { - return array( - 'reason' => 'bbcode', - ); - } +/** + * Show a admin notice error message, if the PHP version is too low + */ +function min_php_version_error(): void { + echo '

'; + esc_html_e( 'Antispam Bee requires PHP version 7.2 or higher to function properly. Please upgrade PHP or deactivate Antispam Bee.', 'antispam-bee' ); + echo '

'; +} - if ( $options['spam_ip'] && self::_is_db_spam( $ip, $url ) ) { - return array( - 'reason' => 'localdb', - ); - } +/** + * Show a admin notice error message, if the PHP version is too low + */ +function domdocument_class_error(): void { + echo '

'; + esc_html_e( 'Antispam Bee requires the DOMDocument PHP class. Please install the PHP DOM/XML extension.', 'antispam-bee' ); + echo '

'; +} - if ( $options['country_code'] && self::_is_country_spam( $ip ) ) { - return array( - 'reason' => 'country', - ); - } - - if ( $options['translate_api'] && self::_is_lang_spam( $body ) ) { - return array( - 'reason' => 'lang', - ); - } - - if ( $options['regexp_check'] && self::_is_regexp_spam( - array( - 'ip' => $ip, - 'rawurl' => $url, - 'host' => self::parse_url( $url, 'host' ), - 'body' => $body, - 'email' => '', - 'author' => '', - ) - ) ) { - return array( - 'reason' => 'regexp', - ); - } - } - - /** - * Check, if I pinged myself. - * - * @since 2.8.2 - * - * @param string $url The URL from where the ping came. - * @param int $target_post_id The post ID which has been pinged. - * - * @return bool - */ - private static function _pingback_from_myself( $url, $target_post_id ) { - - if ( 0 !== strpos( $url, home_url() ) ) { - return false; - } - - $original_post_id = (int) url_to_postid( $url ); - if ( ! $original_post_id ) { - return false; - } - - $post = get_post( $original_post_id ); - if ( ! $post ) { - return false; - } - - $urls = wp_extract_urls( $post->post_content ); - $url_to_find = get_permalink( $target_post_id ); - if ( ! $url_to_find ) { - return false; - } - foreach ( $urls as $url ) { - if ( strpos( $url, $url_to_find ) === 0 ) { - return true; - } - } - return false; - } - - /** - * Check the comment - * - * @since 2.4 - * @since 2.7.0 - * @since 2.10.0 Add useragent as data to regex check - * - * @param array $comment Data of the comment. - * @return array|void Array with suspected reason - */ - private static function _verify_comment_request( $comment ) { - $ip = self::get_key( $comment, 'comment_author_IP' ); - $url = self::get_key( $comment, 'comment_author_url' ); - $body = self::get_key( $comment, 'comment_content' ); - $email = self::get_key( $comment, 'comment_author_email' ); - $author = self::get_key( $comment, 'comment_author' ); - $useragent = self::get_key( $comment, 'comment_agent' ); - - // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound - $allow_empty_comment = apply_filters( 'allow_empty_comment', false, $comment ); - - if ( empty( $body ) && ! $allow_empty_comment ) { - return array( - 'reason' => 'empty', - ); - } - - if ( empty( $ip ) ) { - return array( - 'reason' => 'empty', - ); - } - - if ( get_option( 'require_name_email' ) && ( empty( $email ) || empty( $author ) ) ) { - return array( - 'reason' => 'empty', - ); - } - - $options = self::get_options(); - - if ( $options['already_commented'] && ! empty( $email ) && self::_is_approved_email( $email ) ) { - return; - } - - if ( $options['gravatar_check'] && ! empty( $email ) && 1 === (int) get_option( 'show_avatars', 0 ) && self::_has_valid_gravatar( $email ) ) { - return; - } - - // phpcs:disable WordPress.Security.NonceVerification.Missing - if ( ! empty( $_POST['ab_spam__hidden_field'] ) ) { - return array( - 'reason' => 'css', - ); - } - // phpcs:enable WordPress.Security.NonceVerification.Missing - - if ( $options['time_check'] && self::_is_shortest_time() ) { - return array( - 'reason' => 'time', - ); - } - - if ( $options['bbcode_check'] && self::_is_bbcode_spam( $body ) ) { - return array( - 'reason' => 'bbcode', - ); - } - - if ( $options['regexp_check'] && self::_is_regexp_spam( - array( - 'ip' => $ip, - 'rawurl' => $url, - 'host' => self::parse_url( $url, 'host' ), - 'body' => $body, - 'email' => $email, - 'author' => $author, - 'useragent' => $useragent, - ) - ) ) { - return array( - 'reason' => 'regexp', - ); - } - - if ( $options['spam_ip'] && self::_is_db_spam( $ip, $url, $email ) ) { - return array( - 'reason' => 'localdb', - ); - } - - if ( $options['country_code'] && self::_is_country_spam( $ip ) ) { - return array( - 'reason' => 'country', - ); - } - - if ( $options['translate_api'] && self::_is_lang_spam( $body ) ) { - return array( - 'reason' => 'lang', - ); - } - } - - - /** - * Check for a Gravatar image - * - * @since 2.6.5 - * - * @param string $email Input email. - * @return boolean Check status (true = Gravatar available). - */ - private static function _has_valid_gravatar( $email ) { - $response = wp_safe_remote_get( - sprintf( - 'https://www.gravatar.com/avatar/%s?d=404', - md5( strtolower( trim( $email ) ) ) - ) - ); - - if ( is_wp_error( $response ) ) { - return null; - } - - if ( wp_remote_retrieve_response_code( $response ) === 200 ) { - return true; - } - - return false; - } - - - /** - * Check for comment action time - * - * @since 2.6.4 - * - * @return boolean TRUE if the action time is less than 5 seconds - */ - private static function _is_shortest_time() { - // phpcs:disable WordPress.Security.NonceVerification.Missing - // Everybody can Post. - $init_time = (int) self::get_key( $_POST, 'ab_init_time' ); - // phpcs:enable WordPress.Security.NonceVerification.Missing - if ( 0 === $init_time ) { - return false; - } - - if ( time() - $init_time < apply_filters( 'ab_action_time_limit', 5 ) ) { - return true; - } - - return false; - } - - /** - * Check if the blog name and the title of the blog post from which the trackback originates are equal. - * - * @since 2.6.4 - * - * @param string $body The comment body. - * @param string $blog_name The name of the blog. - * - * @return bool - */ - private static function is_trackback_post_title_blog_name_spam( $body, $blog_name ) { - preg_match( '/(.*)<\/strong>\\n\\n/', $body, $matches ); - if ( ! isset( $matches[1] ) ) { - return false; - } - return trim( $matches[1] ) === trim( $blog_name ); - } - - - /** - * Usage of regexp, also custom - * - * @since 2.5.2 - * @since 2.5.6 - * @since 2.10.0 Use useragent in check - * - * @param array $comment Array with commentary data. - * @return boolean True for suspicious comment. - */ - private static function _is_regexp_spam( $comment ) { - $fields = array( - 'ip', - 'host', - 'body', - 'email', - 'author', - 'useragent', - ); - - $patterns = array( - array( - 'host' => '^(www\.)?\d+\w+\.com$', - 'body' => '^\w+\s\d+$', - 'email' => '@gmail.com$', - ), - array( - 'body' => '\b[a-z]{30}\b', - 'author' => '\b[a-z]{10}\b', - 'host' => '\b[a-z]{10}\b', - ), - array( - 'body' => '\<\!.+?mfunc.+?\>', - ), - array( - 'author' => 'moncler|north face|vuitton|handbag|burberry|outlet|prada|cialis|viagra|maillot|oakley|ralph lauren|ray ban|iphone|プラダ', - ), - array( - 'host' => '^(www\.)?fkbook\.co\.uk$|^(www\.)?nsru\.net$|^(www\.)?goo\.gl$|^(www\.)?bit\.ly$', - ), - array( - 'body' => 'target[t]?ed (visitors|traffic)|viagra|cialis', - ), - array( - 'body' => 'purchase amazing|buy amazing|luxurybrandsale', - ), - array( - 'body' => 'dating|sex|lotto|pharmacy', - 'email' => '@mail\.ru|@yandex\.', - ), - ); - - $quoted_author = preg_quote( $comment['author'], '/' ); - if ( $quoted_author ) { - $patterns[] = array( - 'body' => sprintf( - '%s<\/a>$', - $quoted_author - ), - ); - $patterns[] = array( - 'body' => sprintf( - '%s https?:.+?$', - $quoted_author - ), - ); - $patterns[] = array( - 'email' => '@gmail.com$', - 'author' => '^[a-z0-9-\.]+\.[a-z]{2,6}$', - 'host' => sprintf( - '^%s$', - $quoted_author - ), - ); - } - - $patterns = apply_filters( - 'antispam_bee_patterns', - $patterns - ); - - if ( ! $patterns ) { - return false; - } - - foreach ( $patterns as $pattern ) { - $hits = array(); - - foreach ( $pattern as $field => $regexp ) { - if ( empty( $field ) || ! in_array( $field, $fields, true ) || empty( $regexp ) ) { - continue; - } - - $comment[ $field ] = ( function_exists( 'iconv' ) ? iconv( 'utf-8', 'utf-8//TRANSLIT', $comment[ $field ] ) : $comment[ $field ] ); - - if ( empty( $comment[ $field ] ) ) { - continue; - } - - if ( preg_match( '/' . $regexp . '/isu', $comment[ $field ] ) ) { - $hits[ $field ] = true; - } - } - - if ( count( $hits ) === count( $pattern ) ) { - return true; - } - } - - return false; - } - - - /** - * Review a comment on its existence in the local spam - * - * @since 2.0.0 - * @since 2.5.4 - * - * @param string $ip Comment IP. - * @param string $url Comment URL (optional). - * @param string $email Comment Email (optional). - * @return boolean True for suspicious comment. - */ - private static function _is_db_spam( $ip, $url = '', $email = '' ) { - global $wpdb; - - $params = array(); - $filter = array(); - if ( ! empty( $url ) ) { - $filter[] = '`comment_author_url` = %s'; - $params[] = wp_unslash( $url ); - } - if ( ! empty( $ip ) ) { - $filter[] = '`comment_author_IP` = %s'; - $params[] = wp_unslash( $ip ); - } - - if ( ! empty( $email ) ) { - $filter[] = '`comment_author_email` = %s'; - $params[] = wp_unslash( $email ); - } - if ( empty( $params ) ) { - return false; - } - - // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared - // phpcs:disable WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber - $filter_sql = implode( ' OR ', $filter ); - - $result = $wpdb->get_var( - $wpdb->prepare( - sprintf( - "SELECT `comment_ID` FROM `$wpdb->comments` WHERE `comment_approved` = 'spam' AND (%s) LIMIT 1", - $filter_sql - ), - $params - ) - ); - // phpcs:enable WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber - // phpcs:enable WordPress.DB.PreparedSQL.NotPrepared - - return ! empty( $result ); - } - - - /** - * Check for country spam by (anonymized) IP - * - * @since 2.6.9 - * @since 2.10.0 Make country check API filterable and use iplocate.io instead of ip2country.info - * - * @param string $ip IP address. - * @return boolean True if the comment is spam based on country filter. - */ - private static function _is_country_spam( $ip ) { - $options = self::get_options(); - - $allowed = preg_split( - '/[\s,;]+/', - $options['country_allowed'], - -1, - PREG_SPLIT_NO_EMPTY - ); - $denied = preg_split( - '/[\s,;]+/', - $options['country_denied'], - -1, - PREG_SPLIT_NO_EMPTY - ); - - if ( empty( $allowed ) && empty( $denied ) ) { - return false; - } - - /** - * Filter to hook into the `_is_country_spam` functionality, to implement for example a custom IP check. - * - * @since 2.10.0 - * - * @param null $is_country_spam The `is_country_spam` result. - * @param string $ip The IP address. - * @param array $allowed The list of allowed country codes. - * @param array $denied The list of denied country codes. - * - * @return null|boolean The `is_country_spam` result or null. - */ - $is_country_spam = apply_filters( 'antispam_bee_is_country_spam', null, $ip, $allowed, $denied ); - - if ( is_bool( $is_country_spam ) ) { - return $is_country_spam; - } - - /** - * Filters the IPLocate API key. With this filter, you can add your own IPLocate API key. - * - * @since 2.10.0 - * - * @param string The current IPLocate API key. Default is `null`. - * - * @return string The changed IPLocate API key or null. - */ - $apikey = apply_filters( 'antispam_bee_country_spam_apikey', '' ); - - $response = wp_safe_remote_get( - esc_url_raw( - sprintf( - 'https://www.iplocate.io/api/lookup/%s?apikey=%s', - self::_anonymize_ip( $ip ), - $apikey - ), - 'https' - ) - ); - - if ( is_wp_error( $response ) ) { - return false; - } - - if ( wp_remote_retrieve_response_code( $response ) !== 200 ) { - return false; - } - - $body = (string) wp_remote_retrieve_body( $response ); - - $json = json_decode( $body, true ); - - // Check if response is valid json. - if ( ! is_array( $json ) ) { - return false; - } - - if ( empty( $json['country_code'] ) ) { - return false; - } - - $country = strtoupper( $json['country_code'] ); - - if ( empty( $country ) || strlen( $country ) !== 2 ) { - return false; - } - - if ( ! empty( $denied ) ) { - return ( in_array( $country, $denied, true ) ); - } - - return ( ! in_array( $country, $allowed, true ) ); - } - - - /** - * Check for BBCode spam - * - * @since 2.5.1 - * - * @param string $body Content of a comment. - * @return boolean True for BBCode in content - */ - private static function _is_bbcode_spam( $body ) { - return (bool) preg_match( '/\[url[=\]].*\[\/url\]/is', $body ); - } - - - /** - * Check for an already approved e-mail address - * - * @since 2.0 - * @since 2.5.1 - * - * @param string $email E-mail address. - * @return boolean True for a found entry. - */ - private static function _is_approved_email( $email ) { - global $wpdb; - - $result = $wpdb->get_var( - $wpdb->prepare( - "SELECT `comment_ID` FROM `$wpdb->comments` WHERE `comment_approved` = '1' AND `comment_author_email` = %s LIMIT 1", - wp_unslash( $email ) - ) - ); - - if ( $result ) { - return true; - } - - return false; - } - - /** - * Check for unwanted languages - * - * @since 2.0 - * @since 2.6.6 - * @since 2.8.2 - * - * @param string $comment_content Content of the comment. - * - * @return boolean TRUE if it is spam. - */ - private static function _is_lang_spam( $comment_content ) { - $allowed_lang = (array) self::get_option( 'translate_lang' ); - - $comment_text = wp_strip_all_tags( $comment_content ); - - if ( empty( $allowed_lang ) || empty( $comment_text ) ) { - return false; - } - - /** - * Filters the detected language. With this filter, other detection methods can skip in and detect the language. - * - * @since 2.8.2 - * - * @param null $detected_lang The detected language. - * @param string $comment_text The text, to detect the language. - * - * @return null|string The detected language or null. - */ - $detected_lang = apply_filters( 'antispam_bee_detected_lang', null, $comment_text ); - if ( null !== $detected_lang ) { - return ! in_array( $detected_lang, $allowed_lang, true ); - } - - $word_count = 0; - $text = trim( preg_replace( "/[\n\r\t ]+/", ' ', $comment_text ), ' ' ); - - /* - * translators: If your word count is based on single characters (e.g. East Asian characters), - * enter 'characters_excluding_spaces' or 'characters_including_spaces'. Otherwise, enter 'words'. - * Do not translate into your own language. - */ - if ( strpos( _x( 'words', 'Word count type. Do not translate!' ), 'characters' ) === 0 && preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ) ) { // phpcs:ignore WordPress.WP.I18n.MissingArgDomain - preg_match_all( '/./u', $text, $words_array ); - if ( isset( $words_array[0] ) ) { - $word_count = count( $words_array[0] ); - } - } else { - $words_array = preg_split( "/[\n\r\t ]+/", $text, -1, PREG_SPLIT_NO_EMPTY ); - $word_count = count( $words_array ); - } - - if ( $word_count < 10 ) { - return false; - } - - $response = wp_safe_remote_post( - 'https://api.pluginkollektiv.org/language/v1/', - array( 'body' => wp_json_encode( array( 'body' => $comment_text ) ) ) - ); - - if ( is_wp_error( $response ) - || wp_remote_retrieve_response_code( $response ) !== 200 ) { - return false; - } - - $detected_lang = wp_remote_retrieve_body( $response ); - if ( ! $detected_lang ) { - return false; - } - - $detected_lang = json_decode( $detected_lang ); - if ( ! $detected_lang || ! isset( $detected_lang->code ) ) { - return false; - } - - return ! in_array( self::_map_lang_code( $detected_lang->code ), $allowed_lang, true ); - } - - /** - * Map franc language codes - * - * @since 2.9.0 - * - * @param string $franc_code The franc code, received from the service. - * - * @return string Mapped ISO code - */ - private static function _map_lang_code( $franc_code ) { - $codes = array( - 'zha' => 'za', - 'zho' => 'zh', - 'zul' => 'zu', - 'yid' => 'yi', - 'yor' => 'yo', - 'xho' => 'xh', - 'wln' => 'wa', - 'wol' => 'wo', - 'ven' => 've', - 'vie' => 'vi', - 'vol' => 'vo', - 'uig' => 'ug', - 'ukr' => 'uk', - 'urd' => 'ur', - 'uzb' => 'uz', - 'tah' => 'ty', - 'tam' => 'ta', - 'tat' => 'tt', - 'tel' => 'te', - 'tgk' => 'tg', - 'tgl' => 'tl', - 'tha' => 'th', - 'tir' => 'ti', - 'ton' => 'to', - 'tsn' => 'tn', - 'tso' => 'ts', - 'tuk' => 'tk', - 'tur' => 'tr', - 'twi' => 'tw', - 'sag' => 'sg', - 'san' => 'sa', - 'sin' => 'si', - 'slk' => 'sk', - 'slv' => 'sl', - 'sme' => 'se', - 'smo' => 'sm', - 'sna' => 'sn', - 'snd' => 'sd', - 'som' => 'so', - 'sot' => 'st', - 'spa' => 'es', - 'sqi' => 'sq', - 'srd' => 'sc', - 'srp' => 'sr', - 'ssw' => 'ss', - 'sun' => 'su', - 'swa' => 'sw', - 'swe' => 'sv', - 'roh' => 'rm', - 'ron' => 'ro', - 'run' => 'rn', - 'rus' => 'ru', - 'que' => 'qu', - 'pan' => 'pa', - 'pli' => 'pi', - 'pol' => 'pl', - 'por' => 'pt', - 'pus' => 'ps', - 'oci' => 'oc', - 'oji' => 'oj', - 'ori' => 'or', - 'orm' => 'om', - 'oss' => 'os', - 'nau' => 'na', - 'nav' => 'nv', - 'nbl' => 'nr', - 'nde' => 'nd', - 'ndo' => 'ng', - 'nep' => 'ne', - 'nld' => 'nl', - 'nno' => 'nn', - 'nob' => 'nb', - 'nor' => 'no', - 'nya' => 'ny', - 'mah' => 'mh', - 'mal' => 'ml', - 'mar' => 'mr', - 'mkd' => 'mk', - 'mlg' => 'mg', - 'mlt' => 'mt', - 'mon' => 'mn', - 'mri' => 'mi', - 'msa' => 'ms', - 'mya' => 'my', - 'lao' => 'lo', - 'lat' => 'la', - 'lav' => 'lv', - 'lim' => 'li', - 'lin' => 'ln', - 'lit' => 'lt', - 'ltz' => 'lb', - 'lub' => 'lu', - 'lug' => 'lg', - 'kal' => 'kl', - 'kan' => 'kn', - 'kas' => 'ks', - 'kat' => 'ka', - 'kau' => 'kr', - 'kaz' => 'kk', - 'khm' => 'km', - 'kik' => 'ki', - 'kin' => 'rw', - 'kir' => 'ky', - 'kom' => 'kv', - 'kon' => 'kg', - 'kor' => 'ko', - 'kua' => 'kj', - 'kur' => 'ku', - 'jav' => 'jv', - 'jpn' => 'ja', - 'ibo' => 'ig', - 'ido' => 'io', - 'iii' => 'ii', - 'iku' => 'iu', - 'ile' => 'ie', - 'ina' => 'ia', - 'ind' => 'id', - 'ipk' => 'ik', - 'isl' => 'is', - 'ita' => 'it', - 'hat' => 'ht', - 'hau' => 'ha', - 'hbs' => 'sh', - 'heb' => 'he', - 'her' => 'hz', - 'hin' => 'hi', - 'hmo' => 'ho', - 'hrv' => 'hr', - 'hun' => 'hu', - 'hye' => 'hy', - 'gla' => 'gd', - 'gle' => 'ga', - 'glg' => 'gl', - 'glv' => 'gv', - 'grn' => 'gn', - 'guj' => 'gu', - 'fao' => 'fo', - 'fas' => 'fa', - 'fij' => 'fj', - 'fin' => 'fi', - 'fra' => 'fr', - 'fry' => 'fy', - 'ful' => 'ff', - 'ell' => 'el', - 'eng' => 'en', - 'epo' => 'eo', - 'est' => 'et', - 'eus' => 'eu', - 'ewe' => 'ee', - 'dan' => 'da', - 'deu' => 'de', - 'div' => 'dv', - 'dzo' => 'dz', - 'cat' => 'ca', - 'ces' => 'cs', - 'cha' => 'ch', - 'che' => 'ce', - 'chu' => 'cu', - 'chv' => 'cv', - 'cor' => 'kw', - 'cos' => 'co', - 'cre' => 'cr', - 'cym' => 'cy', - 'bak' => 'ba', - 'bam' => 'bm', - 'bel' => 'be', - 'ben' => 'bn', - 'bis' => 'bi', - 'bod' => 'bo', - 'bos' => 'bs', - 'bre' => 'br', - 'bul' => 'bg', - 'aar' => 'aa', - 'abk' => 'ab', - 'afr' => 'af', - 'aka' => 'ak', - 'amh' => 'am', - 'ara' => 'ar', - 'arg' => 'an', - 'asm' => 'as', - 'ava' => 'av', - 'ave' => 'ae', - 'aym' => 'ay', - 'aze' => 'az', - 'nds' => 'de', - ); - - if ( array_key_exists( $franc_code, $codes ) ) { - return $codes[ $franc_code ]; - } - - return $franc_code; - } - - /** - * Trim IP addresses - * - * @since 0.1 - * @since 2.5.1 - * - * @param string $ip Original IP. - * @param boolean $cut_end Shortening the end. - * @return string Shortened IP. - */ - private static function _cut_ip( $ip, $cut_end = true ) { - $separator = ( self::_is_ipv4( $ip ) ? '.' : ':' ); - - return str_replace( - ( $cut_end ? strrchr( $ip, $separator ) : strstr( $ip, $separator ) ), - '', - $ip - ); - } - - - /** - * Anonymize the IP addresses - * - * @since 2.5.1 - * - * @param string $ip Original IP. - * @return string Anonymous IP. - */ - private static function _anonymize_ip( $ip ) { - if ( self::_is_ipv4( $ip ) ) { - return self::_cut_ip( $ip ) . '.0'; - } - - return self::_cut_ip( $ip, false ) . ':0:0:0:0:0:0:0'; - } - - - /** - * Rotates the IP address - * - * @since 2.4.5 - * - * @param string $ip IP address. - * @return string Turned IP address. - */ - private static function _reverse_ip( $ip ) { - return implode( - '.', - array_reverse( - explode( - '.', - $ip - ) - ) - ); - } - - - /** - * Check for an IPv4 address - * - * @since 2.4 - * @since 2.6.4 - * - * @param string $ip IP to validate. - * @return integer TRUE if IPv4. - */ - private static function _is_ipv4( $ip ) { - if ( function_exists( 'filter_var' ) ) { - return filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) !== false; - } else { - return preg_match( '/^\d{1,3}(\.\d{1,3}){3}$/', $ip ); - } - } - - - /** - * Check for an IPv6 address - * - * @since 2.6.2 - * @since 2.6.4 - * - * @param string $ip IP to validate. - * @return boolean TRUE if IPv6. - */ - private static function _is_ipv6( $ip ) { - if ( function_exists( 'filter_var' ) ) { - return filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) !== false; - } else { - return ! self::_is_ipv4( $ip ); - } - } - - - /** - * Testing on mobile devices - * - * @since 0.1 - * @since 2.4 - * - * @return boolean TRUE if "wptouch" is active - */ - private static function _is_mobile() { - return strpos( get_template_directory(), 'wptouch' ); - } - - /** - * Testing if we are on an AMP site. - * - * Starting with v2.0, amp_is_request() is the preferred method to check, - * but we fall back to the then deprecated is_amp_endpoint() as needed. - * - * @return bool - */ - private static function _is_amp() { - return ( function_exists( 'amp_is_request' ) && amp_is_request() ) || ( function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() ); - } - - - - /* - * ############################ - * ##### SPAM-TREATMENT ##### - * ############################ - */ - - /** - * Execution of the delete/marking process - * - * @since 0.1 - * @since 2.6.0 - * - * @param array $comment Untreated commentary data. - * @param string $reason Reason for suspicion. - * @param boolean $is_ping Ping (optional). - * @return array $comment Treated commentary data. - */ - private static function _handle_spam_request( $comment, $reason, $is_ping = false ) { - - $options = self::get_options(); - - $spam_remove = ! $options['flag_spam']; - $spam_notice = ! $options['no_notice']; - - // Filter settings. - $ignore_filter = $options['ignore_filter']; - $ignore_type = $options['ignore_type']; - $ignore_reason = in_array( $reason, (array) $options['ignore_reasons'], true ); - - // Remember spam. - self::_update_spam_log( $comment ); - self::_update_spam_count(); - self::_update_daily_stats(); - - // Delete spam. - if ( $spam_remove ) { - self::_go_in_peace(); - } - - if ( $ignore_filter && ( ( 1 === (int) $ignore_type && $is_ping ) || ( 2 === (int) $ignore_type && ! $is_ping ) ) ) { - self::_go_in_peace(); - } - - // Spam reason. - if ( $ignore_reason ) { - self::_go_in_peace(); - } - self::$_reason = $reason; - - // Mark spam. - add_filter( - 'pre_comment_approved', - array( - __CLASS__, - 'return_spam', - ) - ); - - // Send e-mail. - add_action( - 'comment_post', - array( - __CLASS__, - 'send_mail_notification', - ) - ); - - // Spam reason as comment meta. - if ( $spam_notice ) { - add_action( - 'comment_post', - array( - __CLASS__, - 'add_spam_reason_to_comment', - ) - ); - } - - return $comment; - } - - - /** - * Logfile with detected spam - * - * @since 2.5.7 - * @since 2.6.1 - * - * @param array $comment Array with commentary data. - * @return mixed FALSE in case of error - */ - private static function _update_spam_log( $comment ) { - if ( ! defined( 'ANTISPAM_BEE_LOG_FILE' ) || ! ANTISPAM_BEE_LOG_FILE || ! is_writable( ANTISPAM_BEE_LOG_FILE ) || validate_file( ANTISPAM_BEE_LOG_FILE ) === 1 ) { - return false; - } - - $entry = sprintf( - '%s comment for post=%d from host=%s marked as spam%s', - current_time( 'mysql' ), - $comment['comment_post_ID'], - $comment['comment_author_IP'], - PHP_EOL - ); - - file_put_contents( - ANTISPAM_BEE_LOG_FILE, - $entry, - FILE_APPEND | LOCK_EX - ); - } - - - /** - * Sends the 403 header and terminates the connection - * - * @since 2.5.6 - */ - private static function _go_in_peace() { - status_header( 403 ); - die( 'Spam deleted.' ); - } - - - /** - * Return real client IP - * - * @since 2.6.1 - * - * @return mixed $ip Client IP - */ - public static function get_client_ip() { - // phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized - // Sanitization of $ip takes place further down. - $ip = ''; - - if ( isset( $_SERVER['HTTP_CLIENT_IP'] ) ) { - $ip = wp_unslash( $_SERVER['HTTP_CLIENT_IP'] ); - } elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) { - $ip = wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ); - } elseif ( isset( $_SERVER['HTTP_X_FORWARDED'] ) ) { - $ip = wp_unslash( $_SERVER['HTTP_X_FORWARDED'] ); - } elseif ( isset( $_SERVER['HTTP_FORWARDED_FOR'] ) ) { - $ip = wp_unslash( $_SERVER['HTTP_FORWARDED_FOR'] ); - } elseif ( isset( $_SERVER['HTTP_FORWARDED'] ) ) { - $ip = wp_unslash( $_SERVER['HTTP_FORWARDED'] ); - } - - $ip = self::_sanitize_ip( $ip ); - if ( $ip ) { - return $ip; - } - - if ( isset( $_SERVER['REMOTE_ADDR'] ) ) { - $ip = wp_unslash( $_SERVER['REMOTE_ADDR'] ); - return self::_sanitize_ip( $ip ); - } - - return ''; - // phpcs:enable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized - } - - /** - * Sanitize an IP string. - * - * @param string $raw_ip The raw IP. - * - * @return string The sanitized IP or an empty string. - */ - private static function _sanitize_ip( $raw_ip ) { - - if ( strpos( $raw_ip, ',' ) !== false ) { - $ips = explode( ',', $raw_ip ); - $raw_ip = trim( $ips[0] ); - } - if ( function_exists( 'filter_var' ) ) { - return (string) filter_var( - $raw_ip, - FILTER_VALIDATE_IP - ); - } - - return (string) preg_replace( - '/[^0-9a-f:. ]/si', - '', - $raw_ip - ); - } - - - /** - * Add spam reason as comment data - * - * @since 2.6.0 - * - * @param integer $comment_id Comment ID. - */ - public static function add_spam_reason_to_comment( $comment_id ) { - add_comment_meta( - $comment_id, - 'antispam_bee_reason', - self::$_reason - ); - } - - - /** - * Delete spam reason as comment data - * - * @since 2.6.0 - * - * @param integer $comment_id Comment ID. - */ - public static function delete_spam_reason_by_comment( $comment_id ) { - delete_comment_meta( - $comment_id, - 'antispam_bee_reason' - ); - } - - /** - * Updates the Antispam Bee reason for manual transitions - * - * @since 2.9.2 - * @param WP_Comment $comment Comment Object. - */ - public static function update_antispam_bee_reason( $comment ) { - update_comment_meta( $comment->comment_ID, 'antispam_bee_reason', 'manually' ); - } - - - /** - * Get the current post ID. - * - * @since 2.7.1 - */ - public static function populate_post_id() { - - if ( null === self::$_current_post_id ) { - self::$_current_post_id = get_the_ID(); - } - } - - - /** - * Send notification via e-mail - * - * @since 0.1 - * @since 2.5.7 - * @since 2.10.0 Change plugin website URL - * - * @hook string antispam_bee_notification_subject Custom subject for notification mails - * - * @param int $id ID of the comment. - * @return int $id ID of the comment. - */ - public static function send_mail_notification( $id ) { - $options = self::get_options(); - - if ( ! $options['email_notify'] ) { - return $id; - } - - $comment = get_comment( $id, ARRAY_A ); - - if ( empty( $comment ) ) { - return $id; - } - - $post = get_post( $comment['comment_post_ID'] ); - if ( ! $post ) { - return $id; - } - - self::load_plugin_lang(); - - $subject = sprintf( - '[%s] %s', - stripslashes_deep( - // phpcs:ignore PHPCompatibility.ParameterValues.NewHTMLEntitiesEncodingDefault.NotSet - html_entity_decode( - get_bloginfo( 'name' ), - ENT_QUOTES - ) - ), - esc_html__( 'Comment marked as spam', 'antispam-bee' ) - ); - - // Content. - $content = strip_tags( stripslashes( $comment['comment_content'] ) ); - if ( ! $content ) { - $content = sprintf( - '-- %s --', - esc_html__( 'Content removed by Antispam Bee', 'antispam-bee' ) - ); - } - - // Prepare Comment Type. - $comment_name = __( 'Comment', 'antispam-bee' ); - if ( 'trackback' === $comment['comment_type'] ) { - $comment_name = __( 'Trackback', 'antispam-bee' ); - } - if ( 'pingback' === $comment['comment_type'] ) { - $comment_name = __( 'Pingback', 'antispam-bee' ); - } - - // Body. - $body = sprintf( - "%s \"%s\"\r\n\r\n", - esc_html__( 'New spam comment on your post', 'antispam-bee' ), - strip_tags( $post->post_title ) - ) . sprintf( - "%s: %s\r\n", - esc_html__( 'Author', 'antispam-bee' ), - ( empty( $comment['comment_author'] ) ? '' : strip_tags( $comment['comment_author'] ) ) - ) . sprintf( - "URL: %s\r\n", - // empty check exists. - esc_url( $comment['comment_author_url'] ) - ) . sprintf( - "%s: %s\r\n", - esc_html__( 'Type', 'antispam-bee' ), - esc_html( $comment_name ) - ) . sprintf( - "Whois: http://whois.arin.net/rest/ip/%s\r\n", - $comment['comment_author_IP'] - ) . sprintf( - "%s: %s\r\n\r\n", - esc_html__( 'Spam Reason', 'antispam-bee' ), - esc_html( self::$defaults['reasons'][ self::$_reason ] ) - ) . sprintf( - "%s\r\n\r\n\r\n", - $content - ) . ( - EMPTY_TRASH_DAYS ? ( - sprintf( - "%s: %s\r\n", - esc_html__( 'Trash it', 'antispam-bee' ), - admin_url( 'comment.php?action=trash&c=' . $id ) - ) - ) : ( - sprintf( - "%s: %s\r\n", - esc_html__( 'Delete it', 'antispam-bee' ), - admin_url( 'comment.php?action=delete&c=' . $id ) - ) - ) - ) . sprintf( - "%s: %s\r\n", - esc_html__( 'Approve it', 'antispam-bee' ), - admin_url( 'comment.php?action=approve&c=' . $id ) - ) . sprintf( - "%s: %s\r\n\r\n", - esc_html__( 'Spam list', 'antispam-bee' ), - admin_url( 'edit-comments.php?comment_status=spam' ) - ) . sprintf( - "%s\r\n%s\r\n", - esc_html__( 'Notify message by Antispam Bee', 'antispam-bee' ), - esc_html__( 'https://antispambee.pluginkollektiv.org/', 'antispam-bee' ) - ); - - wp_mail( - /** - * Filters the recipients of the spam notification. - * - * @param array The recipients array. - */ - apply_filters( - 'antispam_bee_notification_recipients', - array( get_bloginfo( 'admin_email' ) ) - ), - /** - * Filters the subject of the spam notification. - * - * @param string $subject subject line. - */ - apply_filters( - 'antispam_bee_notification_subject', - $subject - ), - $body - ); - - return $id; - } - - - - /* - * ############################ - * ####### STATISTICS ####### - * ############################ - */ - - /** - * Return the number of spam comments - * - * @since 0.1 - * @since 2.4 - */ - private static function _get_spam_count() { - // Init. - $count = self::get_option( 'spam_count' ); - - // Fire. - return ( get_locale() === 'de_DE' ? number_format( $count, 0, '', '.' ) : number_format_i18n( $count ) ); - } - - - /** - * Output the number of spam comments - * - * @since 0.1 - * @since 2.4 - */ - public static function the_spam_count() { - echo esc_html( self::_get_spam_count() ); - } - - - /** - * Update the number of spam comments - * - * @since 0.1 - * @since 2.6.1 - */ - private static function _update_spam_count() { - // Skip if not enabled. - if ( ! self::get_option( 'dashboard_count' ) ) { - return; - } - - self::_update_option( - 'spam_count', - intval( self::get_option( 'spam_count' ) + 1 ) - ); - } - - /** - * Update statistics - * - * @since 1.9 - * @since 2.6.1 - */ - private static function _update_daily_stats() { - // Skip if not enabled. - if ( ! self::get_option( 'dashboard_chart' ) ) { - return; - } - - // Init. - $stats = (array) self::get_option( 'daily_stats' ); - $today = (int) strtotime( 'today' ); - - // Count up. - if ( array_key_exists( $today, $stats ) ) { - $stats[ $today ] ++; - } else { - $stats[ $today ] = 1; - } - - // Sort. - krsort( $stats, SORT_NUMERIC ); - - // Save. - self::_update_option( - 'daily_stats', - array_slice( $stats, 0, 31, true ) - ); - } - - /** - * Returns the secret of a post used in the textarea name attribute. - * - * @since 2.10.0 Modify secret generation because `always_allowed` option not longer exists - * - * @param int $post_id The Post ID. - * - * @return string - */ - public static function get_secret_name_for_post( $post_id ) { - $secret = substr( sha1( md5( 'comment-id' . self::$_salt ) ), 0, 10 ); - - $secret = self::ensure_secret_starts_with_letter( $secret ); - - /** - * Filters the secret for a post, which is used in the textarea name attribute. - * - * @param string $secret The secret. - * @param int $post_id The post ID. - * @param bool $always_allowed Whether the comment form is used outside of the single post view or not. - */ - return apply_filters( - 'ab_get_secret_name_for_post', - $secret, - (int) $post_id, - (bool) self::get_option( 'always_allowed' ) - ); - - } - - /** - * Returns the secret of a post used in the textarea id attribute. - * - * @since 2.10.0 Modify secret generation because `always_allowed` option not longer exists - * - * @param int $post_id The post ID. - * - * @return string - */ - public static function get_secret_id_for_post( $post_id ) { - - $secret = substr( sha1( md5( 'comment-id' . self::$_salt ) ), 0, 10 ); - - $secret = self::ensure_secret_starts_with_letter( $secret ); - - /** - * Filters the secret for a post, which is used in the textarea id attribute. - * - * @param string $secret The secret. - * @param int $post_id The post ID. - * @param bool $always_allowed Whether the comment form is used outside of the single post view or not. - */ - return apply_filters( - 'ab_get_secret_id_for_post', - $secret, - (int) $post_id, - (bool) self::get_option( 'always_allowed' ) - ); - } - - /** - * Ensures that the secret starts with a letter. - * - * @param string $secret The secret. - * - * @return string - */ - public static function ensure_secret_starts_with_letter( $secret ) { - - $first_char = substr( $secret, 0, 1 ); - if ( is_numeric( $first_char ) ) { - return chr( $first_char + 97 ) . substr( $secret, 1 ); - } else { - return $secret; - } - } - - /** - * Returns 'spam' - * - * @since 2.7.3 - * - * @return string - */ - public static function return_spam() { - - return 'spam'; - } - - /** - * A wrapper around wp_parse_url(). - * - * @since 2.8.2 - * - * @param string $url The URL to parse. - * @param string $component The component to get back. - * - * @return string - */ - private static function parse_url( $url, $component = 'host' ) { - - $parts = wp_parse_url( $url ); - return ( is_array( $parts ) && isset( $parts[ $component ] ) ) ? $parts[ $component ] : ''; - } - - /** - * Updates the database structure if necessary - * - * @since 2.10.0 Add update routine for country option names - */ - public static function update_database() { - if ( self::db_version_is_current() ) { - return; - } - - $version_from_db = floatval( get_option( 'antispambee_db_version', 0 ) ); - if ( $version_from_db < 1.01 ) { - global $wpdb; - - /** - * In Version 2.9 the IP of the commenter was saved as a hash. We reverted this solution. - * Therefore, we need to delete this unused data. - */ - //phpcs:disable WordPress.DB.PreparedSQL.NotPrepared - $sql = 'delete from `' . $wpdb->commentmeta . '` where `meta_key` IN ("antispam_bee_iphash")'; - $wpdb->query( $sql ); - //phpcs:enable WordPress.DB.PreparedSQL.NotPrepared - } - - // DB version was raised in ASB 2.10.0 to 1.02. - if ( $version_from_db < 1.02 ) { - // Update option names. - $options = self::get_options(); - if ( isset( $options['country_black'] ) ) { - $options['country_denied'] = $options['country_black']; - unset( $options['country_black'] ); - } - if ( isset( $options['country_white'] ) ) { - $options['country_allowed'] = $options['country_white']; - unset( $options['country_white'] ); - } - - update_option( - 'antispam_bee', - $options - ); - - wp_cache_set( - 'antispam_bee', - $options - ); - } - - update_option( 'antispambee_db_version', self::$db_version ); - } - - /** - * Whether the database structure is up to date. - * - * @since 2.10.0 Return a float instead of int - * - * @return bool - */ - private static function db_version_is_current() { - - $current_version = floatval( get_option( 'antispambee_db_version', 0 ) ); - return $current_version === self::$db_version; - - } - - /** - * Runs after upgrades are completed. - * - * @since 2.10.0 - * - * @param \WP_Upgrader $wp_upgrader WP_Upgrader instance. - * @param array $hook_extra Array of bulk item update data. - */ - public static function upgrades_completed( $wp_upgrader, $hook_extra ) { - if ( ! $wp_upgrader instanceof Plugin_Upgrader || ! isset( $hook_extra['plugins'] ) ) { - return; - } - - $updated_plugins = $hook_extra['plugins']; - $asb_updated = false; - foreach ( $updated_plugins as $updated_plugin ) { - if ( $updated_plugin !== self::$_base ) { - continue; - } - $asb_updated = true; - } - - if ( false === $asb_updated ) { - return; - } - - self::asb_updated(); - } - - /** - * Runs after an upgrade via an uploaded ZIP package was completed. - * - * @since 2.10.0 - * - * @param string $package The package file. - * @param array $data The new plugin or theme data. - * @param string $package_type The package type. - */ - public static function uploaded_upgrade_completed( $package, $data, $package_type ) { - if ( 'plugin' !== $package_type ) { - return; - } - - $text_domain = isset( $data['TextDomain'] ) ? $data['TextDomain'] : ''; - - if ( 'antispam-bee' !== $text_domain ) { - return; - } - - self::asb_updated(); - } - - /** - * Runs after ASB was updated. - * - * @since 2.10.0 - * - * @return void - */ - private static function asb_updated() { - self::update_database(); - } +/** + * Show a admin notice error message, if the PHP version is too low + */ +function autoloader_missing(): void { + echo '

'; + esc_html_e( 'Antispam Bee is missing the Composer autoloader file. Please run `composer install --no-dev -o` in the root folder of the plugin or use a release version including the `vendor` folder.', 'antispam-bee' ); + echo '

'; } - - -// Fire. -add_action( - 'plugins_loaded', - array( - 'Antispam_Bee', - 'init', - ) -); - -// Activation. -register_activation_hook( - __FILE__, - array( - 'Antispam_Bee', - 'activate', - ) -); - -// Deactivation. -register_deactivation_hook( - __FILE__, - array( - 'Antispam_Bee', - 'deactivate', - ) -); - -// Uninstall. -register_uninstall_hook( - __FILE__, - array( - 'Antispam_Bee', - 'uninstall', - ) -); diff --git a/composer-php-5-4.json b/composer-php-5-4.json deleted file mode 100644 index 89160d79..00000000 --- a/composer-php-5-4.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "pluginkollektiv/antispam-bee", - "description": "Antispam Bee blocks spam comments and trackbacks effectively and without captchas.", - "keywords": [ - "WordPress", - "antispam", - "honeypot" - ], - "homepage": "https://pluginkollektiv.github.io/antispam-bee/", - "authors": [ - { - "name": "pluginkollektiv", - "homepage": "https://github.com/pluginkollektiv", - "role": "Maintainer" - } - ], - "support": { - "issues": "https://github.com/pluginkollektiv/antispam-bee/issues", - "source": "https://github.com/pluginkollektiv/antispam-bee", - "docs": "https://github.com/pluginkollektiv/antispam-bee/blob/master/README.md" - }, - "type": "wordpress-plugin", - "license": "GPL-v2", - "require-dev": { - "phpunit/phpunit": "*", - "brain/monkey": "*" - }, - "config": { - "optimize-autoloader": true, - "platform": { - "php": "5.4" - } - }, - "autoload-dev": { - "classmap": [ - "antispam_bee.php", - "inc/" - ], - "psr-4": { - "AntispamBee\\Tests\\": "tests/" - } - } -} diff --git a/composer.json b/composer.json index 43ea4454..d3d7227f 100644 --- a/composer.json +++ b/composer.json @@ -21,65 +21,50 @@ }, "type": "wordpress-plugin", "license": "GPL-v2", + "require": { + "php": ">=7.2" + }, "require-dev": { - "behat/mink": "1.7.1", - "behat/mink-goutte-driver": "^1.2", - "brain/monkey": "^1.5", - "composer/package-versions-deprecated": "^1.11", - "dmore/behat-chrome-extension": "^1.3", - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.1", - "friends-of-behat/mink-extension": "^2.5", - "matthiasmullie/minify": "^1.3", - "paulgibbs/behat-wordpress-extension": "^3.3", + "behat/mink": "^v1.11.0", + "behat/mink-browserkit-driver": "^v2.2.0", + "dmore/behat-chrome-extension": "^1.4.0", + "dealerdirect/phpcodesniffer-composer-installer": "^v1.0.0", + "friends-of-behat/mink-extension": "^v2.7.5", "phpcompatibility/phpcompatibility-wp": "^2.1", - "phpunit/phpunit": "^4", "wp-cli/wp-cli-bundle": "@stable", - "wp-coding-standards/wpcs": "^2.3" + "wp-coding-standards/wpcs": "^3.0.1", + "yoast/wp-test-utils": "^1.2.0" + }, + "autoload": { + "psr-4": { + "AntispamBee\\": "src/" + } }, "autoload-dev": { "classmap": [ "antispam_bee.php", - "inc/" + "src/" ], "psr-4": { "AntispamBee\\Tests\\": "tests/" } }, "scripts": { - "post-install-cmd": [ - "@build" - ], - "post-update-cmd": [ - "@build" - ], - "build": [ - "@minify" - ], "cs": [ "@lint-php" ], "csfix": [ "phpcbf --standard=phpcs.xml" ], - "lint-all": [ - "@lint-js", - "@lint-css" - ], - "lint-css": [ - "npx stylelint css/dashboard.css css/styles.css" - ], - "lint-js": [ - "npx eslint js/dashboard.js js/raphael.helper.js js/scripts.js" - ], "lint-php": [ "phpcs --standard=phpcs.xml -s" ], - "minify": [ - "minifycss css/dashboard.css > css/dashboard.min.css", - "minifycss css/styles.css > css/styles.min.css", - "minifyjs js/dashboard.js > js/dashboard.min.js", - "minifyjs js/raphael.helper.js > js/raphael.helper.min.js", - "minifyjs js/scripts.js > js/scripts.min.js" - ] + "test:unit": [ "phpunit -c phpunit.xml.dist --testsuite unit" ] + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true, + "cweagans/composer-patches": true + } } } diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 83e4d901..00000000 --- a/composer.lock +++ /dev/null @@ -1,8171 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "111c08fbeff06000634003849aa35710", - "packages": [], - "packages-dev": [ - { - "name": "antecedent/patchwork", - "version": "2.0.9", - "source": { - "type": "git", - "url": "https://github.com/antecedent/patchwork.git", - "reference": "cab3be4865e47f1dc447715e76c7b616e48b005d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/antecedent/patchwork/zipball/cab3be4865e47f1dc447715e76c7b616e48b005d", - "reference": "cab3be4865e47f1dc447715e76c7b616e48b005d", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ignas Rudaitis", - "email": "ignas.rudaitis@gmail.com" - } - ], - "description": "Method redefinition (monkey-patching) functionality for PHP.", - "homepage": "http://patchwork2.org/", - "keywords": [ - "aop", - "aspect", - "interception", - "monkeypatching", - "redefinition", - "runkit", - "testing" - ], - "support": { - "issues": "https://github.com/antecedent/patchwork/issues", - "source": "https://github.com/antecedent/patchwork/tree/master" - }, - "time": "2017-08-01T11:52:57+00:00" - }, - { - "name": "behat/behat", - "version": "v3.7.0", - "source": { - "type": "git", - "url": "https://github.com/Behat/Behat.git", - "reference": "08052f739619a9e9f62f457a67302f0715e6dd13" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Behat/Behat/zipball/08052f739619a9e9f62f457a67302f0715e6dd13", - "reference": "08052f739619a9e9f62f457a67302f0715e6dd13", - "shasum": "" - }, - "require": { - "behat/gherkin": "^4.6.0", - "behat/transliterator": "^1.2", - "ext-mbstring": "*", - "php": ">=5.3.3", - "psr/container": "^1.0", - "symfony/config": "^2.7.51 || ^3.0 || ^4.0 || ^5.0", - "symfony/console": "^2.7.51 || ^2.8.33 || ^3.3.15 || ^3.4.3 || ^4.0.3 || ^5.0", - "symfony/dependency-injection": "^2.7.51 || ^3.0 || ^4.0 || ^5.0", - "symfony/event-dispatcher": "^2.7.51 || ^3.0 || ^4.0 || ^5.0", - "symfony/translation": "^2.7.51 || ^3.0 || ^4.0 || ^5.0", - "symfony/yaml": "^2.7.51 || ^3.0 || ^4.0 || ^5.0" - }, - "require-dev": { - "container-interop/container-interop": "^1.2", - "herrera-io/box": "~1.6.1", - "phpunit/phpunit": "^4.8.36 || ^6.5.14 || ^7.5.20", - "symfony/process": "~2.5 || ^3.0 || ^4.0 || ^5.0" - }, - "suggest": { - "ext-dom": "Needed to output test results in JUnit format." - }, - "bin": [ - "bin/behat" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.6.x-dev" - } - }, - "autoload": { - "psr-4": { - "Behat\\Behat\\": "src/Behat/Behat/", - "Behat\\Testwork\\": "src/Behat/Testwork/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - } - ], - "description": "Scenario-oriented BDD framework for PHP 5.3", - "homepage": "http://behat.org/", - "keywords": [ - "Agile", - "BDD", - "ScenarioBDD", - "Scrum", - "StoryBDD", - "User story", - "business", - "development", - "documentation", - "examples", - "symfony", - "testing" - ], - "support": { - "issues": "https://github.com/Behat/Behat/issues", - "source": "https://github.com/Behat/Behat/tree/v3.7.0" - }, - "time": "2020-06-03T13:08:44+00:00" - }, - { - "name": "behat/gherkin", - "version": "v4.8.0", - "source": { - "type": "git", - "url": "https://github.com/Behat/Gherkin.git", - "reference": "2391482cd003dfdc36b679b27e9f5326bd656acd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Behat/Gherkin/zipball/2391482cd003dfdc36b679b27e9f5326bd656acd", - "reference": "2391482cd003dfdc36b679b27e9f5326bd656acd", - "shasum": "" - }, - "require": { - "php": "~7.2|~8.0" - }, - "require-dev": { - "cucumber/cucumber": "dev-gherkin-16.0.0", - "phpunit/phpunit": "~8|~9", - "symfony/phpunit-bridge": "~3|~4|~5", - "symfony/yaml": "~3|~4|~5" - }, - "suggest": { - "symfony/yaml": "If you want to parse features, represented in YAML files" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, - "autoload": { - "psr-0": { - "Behat\\Gherkin": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - } - ], - "description": "Gherkin DSL parser for PHP", - "homepage": "http://behat.org/", - "keywords": [ - "BDD", - "Behat", - "Cucumber", - "DSL", - "gherkin", - "parser" - ], - "support": { - "issues": "https://github.com/Behat/Gherkin/issues", - "source": "https://github.com/Behat/Gherkin/tree/v4.8.0" - }, - "time": "2021-02-04T12:44:21+00:00" - }, - { - "name": "behat/mink", - "version": "v1.7.1", - "source": { - "type": "git", - "url": "https://github.com/minkphp/Mink.git", - "reference": "e6930b9c74693dff7f4e58577e1b1743399f3ff9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/minkphp/Mink/zipball/e6930b9c74693dff7f4e58577e1b1743399f3ff9", - "reference": "e6930b9c74693dff7f4e58577e1b1743399f3ff9", - "shasum": "" - }, - "require": { - "php": ">=5.3.1", - "symfony/css-selector": "~2.1|~3.0" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7|~3.0" - }, - "suggest": { - "behat/mink-browserkit-driver": "extremely fast headless driver for Symfony\\Kernel-based apps (Sf2, Silex)", - "behat/mink-goutte-driver": "fast headless driver for any app without JS emulation", - "behat/mink-selenium2-driver": "slow, but JS-enabled driver for any app (requires Selenium2)", - "behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7.x-dev" - } - }, - "autoload": { - "psr-4": { - "Behat\\Mink\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - } - ], - "description": "Browser controller/emulator abstraction for PHP", - "homepage": "http://mink.behat.org/", - "keywords": [ - "browser", - "testing", - "web" - ], - "support": { - "issues": "https://github.com/minkphp/Mink/issues", - "source": "https://github.com/minkphp/Mink/tree/master" - }, - "time": "2016-03-05T08:26:18+00:00" - }, - { - "name": "behat/mink-browserkit-driver", - "version": "v1.3.4", - "source": { - "type": "git", - "url": "https://github.com/minkphp/MinkBrowserKitDriver.git", - "reference": "e3b90840022ebcd544c7b394a3c9597ae242cbee" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/minkphp/MinkBrowserKitDriver/zipball/e3b90840022ebcd544c7b394a3c9597ae242cbee", - "reference": "e3b90840022ebcd544c7b394a3c9597ae242cbee", - "shasum": "" - }, - "require": { - "behat/mink": "^1.7.1@dev", - "php": ">=5.3.6", - "symfony/browser-kit": "~2.3|~3.0|~4.0", - "symfony/dom-crawler": "~2.3|~3.0|~4.0" - }, - "require-dev": { - "mink/driver-testsuite": "dev-master", - "symfony/debug": "^2.7|^3.0|^4.0", - "symfony/http-kernel": "~2.3|~3.0|~4.0" - }, - "type": "mink-driver", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Behat\\Mink\\Driver\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - } - ], - "description": "Symfony2 BrowserKit driver for Mink framework", - "homepage": "http://mink.behat.org/", - "keywords": [ - "Mink", - "Symfony2", - "browser", - "testing" - ], - "support": { - "issues": "https://github.com/minkphp/MinkBrowserKitDriver/issues", - "source": "https://github.com/minkphp/MinkBrowserKitDriver/tree/v1.3.4" - }, - "time": "2020-03-11T09:49:45+00:00" - }, - { - "name": "behat/mink-goutte-driver", - "version": "v1.2.1", - "source": { - "type": "git", - "url": "https://github.com/minkphp/MinkGoutteDriver.git", - "reference": "8b9ad6d2d95bc70b840d15323365f52fcdaea6ca" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/minkphp/MinkGoutteDriver/zipball/8b9ad6d2d95bc70b840d15323365f52fcdaea6ca", - "reference": "8b9ad6d2d95bc70b840d15323365f52fcdaea6ca", - "shasum": "" - }, - "require": { - "behat/mink": "~1.6@dev", - "behat/mink-browserkit-driver": "~1.2@dev", - "fabpot/goutte": "~1.0.4|~2.0|~3.1", - "php": ">=5.3.1" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7|~3.0" - }, - "type": "mink-driver", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "psr-4": { - "Behat\\Mink\\Driver\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - } - ], - "description": "Goutte driver for Mink framework", - "homepage": "http://mink.behat.org/", - "keywords": [ - "browser", - "goutte", - "headless", - "testing" - ], - "support": { - "issues": "https://github.com/minkphp/MinkGoutteDriver/issues", - "source": "https://github.com/minkphp/MinkGoutteDriver/tree/master" - }, - "time": "2016-03-05T09:04:22+00:00" - }, - { - "name": "behat/transliterator", - "version": "v1.3.0", - "source": { - "type": "git", - "url": "https://github.com/Behat/Transliterator.git", - "reference": "3c4ec1d77c3d05caa1f0bf8fb3aae4845005c7fc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Behat/Transliterator/zipball/3c4ec1d77c3d05caa1f0bf8fb3aae4845005c7fc", - "reference": "3c4ec1d77c3d05caa1f0bf8fb3aae4845005c7fc", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "chuyskywalker/rolling-curl": "^3.1", - "php-yaoi/php-yaoi": "^1.0", - "phpunit/phpunit": "^4.8.36|^6.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2-dev" - } - }, - "autoload": { - "psr-4": { - "Behat\\Transliterator\\": "src/Behat/Transliterator" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Artistic-1.0" - ], - "description": "String transliterator", - "keywords": [ - "i18n", - "slug", - "transliterator" - ], - "support": { - "issues": "https://github.com/Behat/Transliterator/issues", - "source": "https://github.com/Behat/Transliterator/tree/v1.3.0" - }, - "time": "2020-01-14T16:39:13+00:00" - }, - { - "name": "brain/monkey", - "version": "1.5.0", - "source": { - "type": "git", - "url": "https://github.com/Brain-WP/BrainMonkey.git", - "reference": "44b2ea87147803227154c990fa01fd5e82a6bb61" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Brain-WP/BrainMonkey/zipball/44b2ea87147803227154c990fa01fd5e82a6bb61", - "reference": "44b2ea87147803227154c990fa01fd5e82a6bb61", - "shasum": "" - }, - "require": { - "antecedent/patchwork": "~2.0.6", - "mockery/mockery": "0.9.*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev", - "dev-version/1": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Brain\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Giuseppe Mazzapica", - "email": "giuseppe.mazzapica@gmail.com", - "homepage": "https://gmazzap.me", - "role": "Developer" - } - ], - "description": "Mocking utility for PHP functions and WordPress plugin API", - "keywords": [ - "Monkey Patching", - "interception", - "mock", - "mock functions", - "mockery", - "patchwork", - "redefinition", - "runkit", - "test", - "testing" - ], - "support": { - "issues": "https://github.com/Giuseppe-Mazzapica/BrainMonkey/issues", - "source": "https://github.com/Giuseppe-Mazzapica/BrainMonkey" - }, - "time": "2017-06-02T09:01:26+00:00" - }, - { - "name": "composer/ca-bundle", - "version": "1.2.9", - "source": { - "type": "git", - "url": "https://github.com/composer/ca-bundle.git", - "reference": "78a0e288fdcebf92aa2318a8d3656168da6ac1a5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/78a0e288fdcebf92aa2318a8d3656168da6ac1a5", - "reference": "78a0e288fdcebf92aa2318a8d3656168da6ac1a5", - "shasum": "" - }, - "require": { - "ext-openssl": "*", - "ext-pcre": "*", - "php": "^5.3.2 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^0.12.55", - "psr/log": "^1.0", - "symfony/phpunit-bridge": "^4.2 || ^5", - "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\CaBundle\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", - "keywords": [ - "cabundle", - "cacert", - "certificate", - "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.2.9" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2021-01-12T12:10:35+00:00" - }, - { - "name": "composer/composer", - "version": "1.10.23", - "source": { - "type": "git", - "url": "https://github.com/composer/composer.git", - "reference": "28c9dfbe2351635961f670773e8d7b17bc5eda25" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/28c9dfbe2351635961f670773e8d7b17bc5eda25", - "reference": "28c9dfbe2351635961f670773e8d7b17bc5eda25", - "shasum": "" - }, - "require": { - "composer/ca-bundle": "^1.0", - "composer/semver": "^1.0", - "composer/spdx-licenses": "^1.2", - "composer/xdebug-handler": "^1.1", - "justinrainbow/json-schema": "^5.2.10", - "php": "^5.3.2 || ^7.0 || ^8.0", - "psr/log": "^1.0", - "seld/jsonlint": "^1.4", - "seld/phar-utils": "^1.0", - "symfony/console": "^2.7 || ^3.0 || ^4.0 || ^5.0", - "symfony/filesystem": "^2.7 || ^3.0 || ^4.0 || ^5.0", - "symfony/finder": "^2.7 || ^3.0 || ^4.0 || ^5.0", - "symfony/process": "^2.7 || ^3.0 || ^4.0 || ^5.0" - }, - "conflict": { - "symfony/console": "2.8.38" - }, - "require-dev": { - "phpspec/prophecy": "^1.10", - "symfony/phpunit-bridge": "^4.2" - }, - "suggest": { - "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", - "ext-zip": "Enabling the zip extension allows you to unzip archives", - "ext-zlib": "Allow gzip compression of HTTP requests" - }, - "bin": [ - "bin/composer" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\": "src/Composer" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nils Adermann", - "email": "naderman@naderman.de", - "homepage": "http://www.naderman.de" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.", - "homepage": "https://getcomposer.org/", - "keywords": [ - "autoload", - "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.23" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2021-04-27T11:10:45+00:00" - }, - { - "name": "composer/package-versions-deprecated", - "version": "1.11.99.1", - "source": { - "type": "git", - "url": "https://github.com/composer/package-versions-deprecated.git", - "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/7413f0b55a051e89485c5cb9f765fe24bb02a7b6", - "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.1.0 || ^2.0", - "php": "^7 || ^8" - }, - "replace": { - "ocramius/package-versions": "1.11.99" - }, - "require-dev": { - "composer/composer": "^1.9.3 || ^2.0@dev", - "ext-zip": "^1.13", - "phpunit/phpunit": "^6.5 || ^7" - }, - "type": "composer-plugin", - "extra": { - "class": "PackageVersions\\Installer", - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "PackageVersions\\": "src/PackageVersions" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be" - } - ], - "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", - "support": { - "issues": "https://github.com/composer/package-versions-deprecated/issues", - "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.1" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2020-11-11T10:22:58+00:00" - }, - { - "name": "composer/semver", - "version": "1.7.2", - "source": { - "type": "git", - "url": "https://github.com/composer/semver.git", - "reference": "647490bbcaf7fc4891c58f47b825eb99d19c377a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/647490bbcaf7fc4891c58f47b825eb99d19c377a", - "reference": "647490bbcaf7fc4891c58f47b825eb99d19c377a", - "shasum": "" - }, - "require": { - "php": "^5.3.2 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.5 || ^5.0.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\Semver\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nils Adermann", - "email": "naderman@naderman.de", - "homepage": "http://www.naderman.de" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - }, - { - "name": "Rob Bast", - "email": "rob.bast@gmail.com", - "homepage": "http://robbast.nl" - } - ], - "description": "Semver library that offers utilities, version constraint parsing and validation.", - "keywords": [ - "semantic", - "semver", - "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", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2020-12-03T15:47:16+00:00" - }, - { - "name": "composer/spdx-licenses", - "version": "1.5.5", - "source": { - "type": "git", - "url": "https://github.com/composer/spdx-licenses.git", - "reference": "de30328a7af8680efdc03e396aad24befd513200" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/de30328a7af8680efdc03e396aad24befd513200", - "reference": "de30328a7af8680efdc03e396aad24befd513200", - "shasum": "" - }, - "require": { - "php": "^5.3.2 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\Spdx\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nils Adermann", - "email": "naderman@naderman.de", - "homepage": "http://www.naderman.de" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - }, - { - "name": "Rob Bast", - "email": "rob.bast@gmail.com", - "homepage": "http://robbast.nl" - } - ], - "description": "SPDX licenses list and validation library.", - "keywords": [ - "license", - "spdx", - "validator" - ], - "support": { - "irc": "irc://irc.freenode.org/composer", - "issues": "https://github.com/composer/spdx-licenses/issues", - "source": "https://github.com/composer/spdx-licenses/tree/1.5.5" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2020-12-03T16:04:16+00:00" - }, - { - "name": "composer/xdebug-handler", - "version": "1.4.6", - "source": { - "type": "git", - "url": "https://github.com/composer/xdebug-handler.git", - "reference": "f27e06cd9675801df441b3656569b328e04aa37c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/f27e06cd9675801df441b3656569b328e04aa37c", - "reference": "f27e06cd9675801df441b3656569b328e04aa37c", - "shasum": "" - }, - "require": { - "php": "^5.3.2 || ^7.0 || ^8.0", - "psr/log": "^1.0" - }, - "require-dev": { - "phpstan/phpstan": "^0.12.55", - "symfony/phpunit-bridge": "^4.2 || ^5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Composer\\XdebugHandler\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "John Stevenson", - "email": "john-stevenson@blueyonder.co.uk" - } - ], - "description": "Restarts a process without Xdebug.", - "keywords": [ - "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", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2021-03-25T17:01:18+00:00" - }, - { - "name": "cweagans/composer-patches", - "version": "1.7.0", - "source": { - "type": "git", - "url": "https://github.com/cweagans/composer-patches.git", - "reference": "ae02121445ad75f4eaff800cc532b5e6233e2ddf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/cweagans/composer-patches/zipball/ae02121445ad75f4eaff800cc532b5e6233e2ddf", - "reference": "ae02121445ad75f4eaff800cc532b5e6233e2ddf", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0 || ^2.0", - "php": ">=5.3.0" - }, - "require-dev": { - "composer/composer": "~1.0 || ~2.0", - "phpunit/phpunit": "~4.6" - }, - "type": "composer-plugin", - "extra": { - "class": "cweagans\\Composer\\Patches" - }, - "autoload": { - "psr-4": { - "cweagans\\Composer\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Cameron Eagans", - "email": "me@cweagans.net" - } - ], - "description": "Provides a way to patch Composer packages.", - "support": { - "issues": "https://github.com/cweagans/composer-patches/issues", - "source": "https://github.com/cweagans/composer-patches/tree/1.7.0" - }, - "time": "2020-09-30T17:56:20+00:00" - }, - { - "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v0.7.1", - "source": { - "type": "git", - "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", - "reference": "fe390591e0241955f22eb9ba327d137e501c771c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/fe390591e0241955f22eb9ba327d137e501c771c", - "reference": "fe390591e0241955f22eb9ba327d137e501c771c", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0 || ^2.0", - "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.0 || ^3.0 || ^4.0" - }, - "require-dev": { - "composer/composer": "*", - "phpcompatibility/php-compatibility": "^9.0", - "sensiolabs/security-checker": "^4.1.0" - }, - "type": "composer-plugin", - "extra": { - "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" - }, - "autoload": { - "psr-4": { - "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Franck Nijhof", - "email": "franck.nijhof@dealerdirect.com", - "homepage": "http://www.frenck.nl", - "role": "Developer / IT Manager" - } - ], - "description": "PHP_CodeSniffer Standards Composer Installer Plugin", - "homepage": "http://www.dealerdirect.com", - "keywords": [ - "PHPCodeSniffer", - "PHP_CodeSniffer", - "code quality", - "codesniffer", - "composer", - "installer", - "phpcs", - "plugin", - "qa", - "quality", - "standard", - "standards", - "style guide", - "stylecheck", - "tests" - ], - "support": { - "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", - "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" - }, - "time": "2020-12-07T18:04:37+00:00" - }, - { - "name": "dmore/behat-chrome-extension", - "version": "1.3.0", - "source": { - "type": "git", - "url": "https://gitlab.com/DMore/behat-chrome-extension.git", - "reference": "6279986ef85ac179f055460502e9b11c3784146c" - }, - "dist": { - "type": "zip", - "url": "https://gitlab.com/api/v4/projects/DMore%2Fbehat-chrome-extension/repository/archive.zip?sha=6279986ef85ac179f055460502e9b11c3784146c", - "reference": "6279986ef85ac179f055460502e9b11c3784146c", - "shasum": "" - }, - "require": { - "behat/behat": "^3.0.4", - "behat/mink-extension": "^2.0", - "dmore/chrome-mink-driver": "^2.4.1", - "php": ">=5.6" - }, - "require-dev": { - "phpunit/phpunit": "^5.7" - }, - "type": "library", - "autoload": { - "psr-4": { - "DMore\\ChromeExtension\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Dorian More", - "email": "doriancmore@gmail.com" - } - ], - "description": "Behat extension for controlling chrome without selenium", - "keywords": [ - "Behat", - "chrome", - "driver", - "headless" - ], - "time": "2019-03-30T08:57:34+00:00" - }, - { - "name": "dmore/chrome-mink-driver", - "version": "2.8.0", - "source": { - "type": "git", - "url": "https://gitlab.com/DMore/chrome-mink-driver.git", - "reference": "f85c8f86ca2e9000119c310577a6942683f7e280" - }, - "dist": { - "type": "zip", - "url": "https://gitlab.com/api/v4/projects/DMore%2Fchrome-mink-driver/repository/archive.zip?sha=f85c8f86ca2e9000119c310577a6942683f7e280", - "reference": "f85c8f86ca2e9000119c310577a6942683f7e280", - "shasum": "" - }, - "require": { - "behat/mink": "^1.7", - "ext-curl": "*", - "ext-json": "*", - "ext-mbstring": "*", - "textalk/websocket": "^1.2.0" - }, - "require-dev": { - "mink/driver-testsuite": "dev-master", - "phpunit/phpunit": "^5.0.0", - "squizlabs/php_codesniffer": "^3.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "DMore\\ChromeDriver\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Dorian More", - "email": "doriancmore@gmail.com" - } - ], - "description": "Mink driver for controlling chrome without selenium", - "support": { - "issues": "https://gitlab.com/api/v4/projects/3255077/issues" - }, - "time": "2021-04-25T06:49:32+00:00" - }, - { - "name": "doctrine/instantiator", - "version": "1.4.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^8.0", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "https://ocramius.github.io/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", - "keywords": [ - "constructor", - "instantiate" - ], - "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.0" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" - } - ], - "time": "2020-11-10T18:47:58+00:00" - }, - { - "name": "fabpot/goutte", - "version": "v3.2.3", - "source": { - "type": "git", - "url": "https://github.com/FriendsOfPHP/Goutte.git", - "reference": "3f0eaf0a40181359470651f1565b3e07e3dd31b8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/3f0eaf0a40181359470651f1565b3e07e3dd31b8", - "reference": "3f0eaf0a40181359470651f1565b3e07e3dd31b8", - "shasum": "" - }, - "require": { - "guzzlehttp/guzzle": "^6.0", - "php": ">=5.5.0", - "symfony/browser-kit": "~2.1|~3.0|~4.0", - "symfony/css-selector": "~2.1|~3.0|~4.0", - "symfony/dom-crawler": "~2.1|~3.0|~4.0" - }, - "require-dev": { - "symfony/phpunit-bridge": "^3.3 || ^4" - }, - "type": "application", - "extra": { - "branch-alias": { - "dev-master": "3.2-dev" - } - }, - "autoload": { - "psr-4": { - "Goutte\\": "Goutte" - }, - "exclude-from-classmap": [ - "Goutte/Tests" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "A simple PHP Web Scraper", - "homepage": "https://github.com/FriendsOfPHP/Goutte", - "keywords": [ - "scraper" - ], - "support": { - "issues": "https://github.com/FriendsOfPHP/Goutte/issues", - "source": "https://github.com/FriendsOfPHP/Goutte/tree/master" - }, - "time": "2018-06-29T15:13:57+00:00" - }, - { - "name": "friends-of-behat/mink-extension", - "version": "v2.5.0", - "source": { - "type": "git", - "url": "https://github.com/FriendsOfBehat/MinkExtension.git", - "reference": "83119aa70be1f2c63061c29dced9d41775cd9db2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/FriendsOfBehat/MinkExtension/zipball/83119aa70be1f2c63061c29dced9d41775cd9db2", - "reference": "83119aa70be1f2c63061c29dced9d41775cd9db2", - "shasum": "" - }, - "require": { - "behat/behat": "^3.0.5", - "behat/mink": "^1.5", - "php": ">=7.2", - "symfony/config": "^3.4 || ^4.4 || ^5.0" - }, - "replace": { - "behat/mink-extension": "self.version" - }, - "require-dev": { - "behat/mink-goutte-driver": "^1.1", - "phpspec/phpspec": "^6.0 || ^7.0" - }, - "type": "behat-extension", - "extra": { - "branch-alias": { - "dev-master": "2.1.x-dev" - } - }, - "autoload": { - "psr-0": { - "Behat\\MinkExtension": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com" - }, - { - "name": "Christophe Coevoet", - "email": "stof@notk.org" - } - ], - "description": "Mink extension for Behat", - "homepage": "http://extensions.behat.org/mink", - "keywords": [ - "browser", - "gui", - "test", - "web" - ], - "support": { - "source": "https://github.com/FriendsOfBehat/MinkExtension/tree/v2.5.0" - }, - "time": "2021-01-21T09:27:44+00:00" - }, - { - "name": "gettext/gettext", - "version": "v4.8.4", - "source": { - "type": "git", - "url": "https://github.com/php-gettext/Gettext.git", - "reference": "58bc0f7f37e78efb0f9758f93d4a0f669f0f84a1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-gettext/Gettext/zipball/58bc0f7f37e78efb0f9758f93d4a0f669f0f84a1", - "reference": "58bc0f7f37e78efb0f9758f93d4a0f669f0f84a1", - "shasum": "" - }, - "require": { - "gettext/languages": "^2.3", - "php": ">=5.4.0" - }, - "require-dev": { - "illuminate/view": "*", - "phpunit/phpunit": "^4.8|^5.7|^6.5", - "squizlabs/php_codesniffer": "^3.0", - "symfony/yaml": "~2", - "twig/extensions": "*", - "twig/twig": "^1.31|^2.0" - }, - "suggest": { - "illuminate/view": "Is necessary if you want to use the Blade extractor", - "symfony/yaml": "Is necessary if you want to use the Yaml extractor/generator", - "twig/extensions": "Is necessary if you want to use the Twig extractor", - "twig/twig": "Is necessary if you want to use the Twig extractor" - }, - "type": "library", - "autoload": { - "psr-4": { - "Gettext\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Oscar Otero", - "email": "oom@oscarotero.com", - "homepage": "http://oscarotero.com", - "role": "Developer" - } - ], - "description": "PHP gettext manager", - "homepage": "https://github.com/oscarotero/Gettext", - "keywords": [ - "JS", - "gettext", - "i18n", - "mo", - "po", - "translation" - ], - "support": { - "email": "oom@oscarotero.com", - "issues": "https://github.com/oscarotero/Gettext/issues", - "source": "https://github.com/php-gettext/Gettext/tree/v4.8.4" - }, - "funding": [ - { - "url": "https://paypal.me/oscarotero", - "type": "custom" - }, - { - "url": "https://github.com/oscarotero", - "type": "github" - }, - { - "url": "https://www.patreon.com/misteroom", - "type": "patreon" - } - ], - "time": "2021-03-10T19:35:49+00:00" - }, - { - "name": "gettext/languages", - "version": "2.6.0", - "source": { - "type": "git", - "url": "https://github.com/php-gettext/Languages.git", - "reference": "38ea0482f649e0802e475f0ed19fa993bcb7a618" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-gettext/Languages/zipball/38ea0482f649e0802e475f0ed19fa993bcb7a618", - "reference": "38ea0482f649e0802e475f0ed19fa993bcb7a618", - "shasum": "" - }, - "require": { - "php": ">=5.3" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^2.16.0", - "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.5 || ^8.4" - }, - "bin": [ - "bin/export-plural-rules" - ], - "type": "library", - "autoload": { - "psr-4": { - "Gettext\\Languages\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michele Locati", - "email": "mlocati@gmail.com", - "role": "Developer" - } - ], - "description": "gettext languages with plural rules", - "homepage": "https://github.com/php-gettext/Languages", - "keywords": [ - "cldr", - "i18n", - "internationalization", - "l10n", - "language", - "languages", - "localization", - "php", - "plural", - "plural rules", - "plurals", - "translate", - "translations", - "unicode" - ], - "support": { - "issues": "https://github.com/php-gettext/Languages/issues", - "source": "https://github.com/php-gettext/Languages/tree/2.6.0" - }, - "time": "2019-11-13T10:30:21+00:00" - }, - { - "name": "guzzlehttp/guzzle", - "version": "6.5.5", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", - "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", - "shasum": "" - }, - "require": { - "ext-json": "*", - "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.6.1", - "php": ">=5.5", - "symfony/polyfill-intl-idn": "^1.17.0" - }, - "require-dev": { - "ext-curl": "*", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", - "psr/log": "^1.1" - }, - "suggest": { - "psr/log": "Required for using the Log middleware" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.5-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle is a PHP HTTP client library", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "rest", - "web service" - ], - "support": { - "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/6.5" - }, - "time": "2020-06-16T21:01:06+00:00" - }, - { - "name": "guzzlehttp/promises", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/8e7d04f1f6450fef59366c399cfad4b9383aa30d", - "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d", - "shasum": "" - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Promise\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle promises library", - "keywords": [ - "promise" - ], - "support": { - "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/1.4.1" - }, - "time": "2021-03-07T09:25:29+00:00" - }, - { - "name": "guzzlehttp/psr7", - "version": "1.8.2", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "dc960a912984efb74d0a90222870c72c87f10c91" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/dc960a912984efb74d0a90222870c72c87f10c91", - "reference": "dc960a912984efb74d0a90222870c72c87f10c91", - "shasum": "" - }, - "require": { - "php": ">=5.4.0", - "psr/http-message": "~1.0", - "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "ext-zlib": "*", - "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" - }, - "suggest": { - "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Tobias Schultze", - "homepage": "https://github.com/Tobion" - } - ], - "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/1.8.2" - }, - "time": "2021-04-26T09:17:50+00:00" - }, - { - "name": "hamcrest/hamcrest-php", - "version": "v1.2.2", - "source": { - "type": "git", - "url": "https://github.com/hamcrest/hamcrest-php.git", - "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/b37020aa976fa52d3de9aa904aa2522dc518f79c", - "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "replace": { - "cordoval/hamcrest-php": "*", - "davedevelopment/hamcrest-php": "*", - "kodova/hamcrest-php": "*" - }, - "require-dev": { - "phpunit/php-file-iterator": "1.3.3", - "satooshi/php-coveralls": "dev-master" - }, - "type": "library", - "autoload": { - "classmap": [ - "hamcrest" - ], - "files": [ - "hamcrest/Hamcrest.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD" - ], - "description": "This is the PHP port of Hamcrest Matchers", - "keywords": [ - "test" - ], - "support": { - "issues": "https://github.com/hamcrest/hamcrest-php/issues", - "source": "https://github.com/hamcrest/hamcrest-php/tree/master" - }, - "time": "2015-05-11T14:41:42+00:00" - }, - { - "name": "justinrainbow/json-schema", - "version": "5.2.10", - "source": { - "type": "git", - "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", - "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", - "json-schema/json-schema-test-suite": "1.2.0", - "phpunit/phpunit": "^4.8.35" - }, - "bin": [ - "bin/validate-json" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "JsonSchema\\": "src/JsonSchema/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bruno Prieto Reis", - "email": "bruno.p.reis@gmail.com" - }, - { - "name": "Justin Rainbow", - "email": "justin.rainbow@gmail.com" - }, - { - "name": "Igor Wiedler", - "email": "igor@wiedler.ch" - }, - { - "name": "Robert Schönthal", - "email": "seroscho@googlemail.com" - } - ], - "description": "A library to validate a json schema.", - "homepage": "https://github.com/justinrainbow/json-schema", - "keywords": [ - "json", - "schema" - ], - "support": { - "issues": "https://github.com/justinrainbow/json-schema/issues", - "source": "https://github.com/justinrainbow/json-schema/tree/5.2.10" - }, - "time": "2020-05-27T16:41:55+00:00" - }, - { - "name": "matthiasmullie/minify", - "version": "1.3.66", - "source": { - "type": "git", - "url": "https://github.com/matthiasmullie/minify.git", - "reference": "45fd3b0f1dfa2c965857c6d4a470bea52adc31a6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/45fd3b0f1dfa2c965857c6d4a470bea52adc31a6", - "reference": "45fd3b0f1dfa2c965857c6d4a470bea52adc31a6", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "matthiasmullie/path-converter": "~1.1", - "php": ">=5.3.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "~2.0", - "matthiasmullie/scrapbook": "dev-master", - "phpunit/phpunit": ">=4.8" - }, - "suggest": { - "psr/cache-implementation": "Cache implementation to use with Minify::cache" - }, - "bin": [ - "bin/minifycss", - "bin/minifyjs" - ], - "type": "library", - "autoload": { - "psr-4": { - "MatthiasMullie\\Minify\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthias Mullie", - "email": "minify@mullie.eu", - "homepage": "http://www.mullie.eu", - "role": "Developer" - } - ], - "description": "CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.", - "homepage": "http://www.minifier.org", - "keywords": [ - "JS", - "css", - "javascript", - "minifier", - "minify" - ], - "support": { - "issues": "https://github.com/matthiasmullie/minify/issues", - "source": "https://github.com/matthiasmullie/minify/tree/1.3.66" - }, - "funding": [ - { - "url": "https://github.com/[user1", - "type": "github" - }, - { - "url": "https://github.com/matthiasmullie] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g.", - "type": "github" - }, - { - "url": "https://github.com/user2", - "type": "github" - } - ], - "time": "2021-01-06T15:18:10+00:00" - }, - { - "name": "matthiasmullie/path-converter", - "version": "1.1.3", - "source": { - "type": "git", - "url": "https://github.com/matthiasmullie/path-converter.git", - "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/e7d13b2c7e2f2268e1424aaed02085518afa02d9", - "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.8" - }, - "type": "library", - "autoload": { - "psr-4": { - "MatthiasMullie\\PathConverter\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthias Mullie", - "email": "pathconverter@mullie.eu", - "homepage": "http://www.mullie.eu", - "role": "Developer" - } - ], - "description": "Relative path converter", - "homepage": "http://github.com/matthiasmullie/path-converter", - "keywords": [ - "converter", - "path", - "paths", - "relative" - ], - "support": { - "issues": "https://github.com/matthiasmullie/path-converter/issues", - "source": "https://github.com/matthiasmullie/path-converter/tree/1.1.3" - }, - "time": "2019-02-05T23:41:09+00:00" - }, - { - "name": "mck89/peast", - "version": "v1.12.0", - "source": { - "type": "git", - "url": "https://github.com/mck89/peast.git", - "reference": "833be7a294627a8c5b1c482cbf489f73bf9b8086" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mck89/peast/zipball/833be7a294627a8c5b1c482cbf489f73bf9b8086", - "reference": "833be7a294627a8c5b1c482cbf489f73bf9b8086", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.12.0-dev" - } - }, - "autoload": { - "psr-4": { - "Peast\\": "lib/Peast/", - "Peast\\test\\": "test/Peast/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Marchiò", - "email": "marco.mm89@gmail.com" - } - ], - "description": "Peast is PHP library that generates AST for JavaScript code", - "support": { - "issues": "https://github.com/mck89/peast/issues", - "source": "https://github.com/mck89/peast/tree/v1.12.0" - }, - "time": "2021-01-08T15:16:19+00:00" - }, - { - "name": "mockery/mockery", - "version": "0.9.11", - "source": { - "type": "git", - "url": "https://github.com/mockery/mockery.git", - "reference": "be9bf28d8e57d67883cba9fcadfcff8caab667f8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mockery/mockery/zipball/be9bf28d8e57d67883cba9fcadfcff8caab667f8", - "reference": "be9bf28d8e57d67883cba9fcadfcff8caab667f8", - "shasum": "" - }, - "require": { - "hamcrest/hamcrest-php": "~1.1", - "lib-pcre": ">=7.0", - "php": ">=5.3.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.9.x-dev" - } - }, - "autoload": { - "psr-0": { - "Mockery": "library/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Pádraic Brady", - "email": "padraic.brady@gmail.com", - "homepage": "http://blog.astrumfutura.com" - }, - { - "name": "Dave Marshall", - "email": "dave.marshall@atstsolutions.co.uk", - "homepage": "http://davedevelopment.co.uk" - } - ], - "description": "Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succinct API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.", - "homepage": "http://github.com/padraic/mockery", - "keywords": [ - "BDD", - "TDD", - "library", - "mock", - "mock objects", - "mockery", - "stub", - "test", - "test double", - "testing" - ], - "support": { - "issues": "https://github.com/mockery/mockery/issues", - "source": "https://github.com/mockery/mockery/tree/0.9" - }, - "time": "2019-02-12T16:07:13+00:00" - }, - { - "name": "mustache/mustache", - "version": "v2.14.1", - "source": { - "type": "git", - "url": "https://github.com/bobthecow/mustache.php.git", - "reference": "579ffa5c96e1d292c060b3dd62811ff01ad8c24e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/579ffa5c96e1d292c060b3dd62811ff01ad8c24e", - "reference": "579ffa5c96e1d292c060b3dd62811ff01ad8c24e", - "shasum": "" - }, - "require": { - "php": ">=5.2.4" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "~1.11", - "phpunit/phpunit": "~3.7|~4.0|~5.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "Mustache": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Justin Hileman", - "email": "justin@justinhileman.info", - "homepage": "http://justinhileman.com" - } - ], - "description": "A Mustache implementation in PHP.", - "homepage": "https://github.com/bobthecow/mustache.php", - "keywords": [ - "mustache", - "templating" - ], - "support": { - "issues": "https://github.com/bobthecow/mustache.php/issues", - "source": "https://github.com/bobthecow/mustache.php/tree/v2.14.1" - }, - "time": "2022-01-21T06:08:36+00:00" - }, - { - "name": "nb/oxymel", - "version": "v0.1.0", - "source": { - "type": "git", - "url": "https://github.com/nb/oxymel.git", - "reference": "cbe626ef55d5c4cc9b5e6e3904b395861ea76e3c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nb/oxymel/zipball/cbe626ef55d5c4cc9b5e6e3904b395861ea76e3c", - "reference": "cbe626ef55d5c4cc9b5e6e3904b395861ea76e3c", - "shasum": "" - }, - "require": { - "php": ">=5.2.4" - }, - "type": "library", - "autoload": { - "psr-0": { - "Oxymel": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nikolay Bachiyski", - "email": "nb@nikolay.bg", - "homepage": "http://extrapolate.me/" - } - ], - "description": "A sweet XML builder", - "homepage": "https://github.com/nb/oxymel", - "keywords": [ - "xml" - ], - "support": { - "issues": "https://github.com/nb/oxymel/issues", - "source": "https://github.com/nb/oxymel/tree/master" - }, - "time": "2013-02-24T15:01:54+00:00" - }, - { - "name": "ocramius/proxy-manager", - "version": "2.2.3", - "source": { - "type": "git", - "url": "https://github.com/Ocramius/ProxyManager.git", - "reference": "4d154742e31c35137d5374c998e8f86b54db2e2f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Ocramius/ProxyManager/zipball/4d154742e31c35137d5374c998e8f86b54db2e2f", - "reference": "4d154742e31c35137d5374c998e8f86b54db2e2f", - "shasum": "" - }, - "require": { - "ocramius/package-versions": "^1.1.3", - "php": "^7.2.0", - "zendframework/zend-code": "^3.3.0" - }, - "require-dev": { - "couscous/couscous": "^1.6.1", - "ext-phar": "*", - "humbug/humbug": "1.0.0-RC.0@RC", - "nikic/php-parser": "^3.1.1", - "padraic/phpunit-accelerator": "dev-master@DEV", - "phpbench/phpbench": "^0.12.2", - "phpstan/phpstan": "dev-master#856eb10a81c1d27c701a83f167dc870fd8f4236a as 0.9.999", - "phpstan/phpstan-phpunit": "dev-master#5629c0a1f4a9c417cb1077cf6693ad9753895761", - "phpunit/phpunit": "^6.4.3", - "squizlabs/php_codesniffer": "^2.9.1" - }, - "suggest": { - "ocramius/generated-hydrator": "To have very fast object to array to object conversion for ghost objects", - "zendframework/zend-json": "To have the JsonRpc adapter (Remote Object feature)", - "zendframework/zend-soap": "To have the Soap adapter (Remote Object feature)", - "zendframework/zend-xmlrpc": "To have the XmlRpc adapter (Remote Object feature)" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "ProxyManager\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.io/" - } - ], - "description": "A library providing utilities to generate, instantiate and generally operate with Object Proxies", - "homepage": "https://github.com/Ocramius/ProxyManager", - "keywords": [ - "aop", - "lazy loading", - "proxy", - "proxy pattern", - "service proxies" - ], - "support": { - "issues": "https://github.com/Ocramius/ProxyManager/issues", - "source": "https://github.com/Ocramius/ProxyManager/tree/2.2.x" - }, - "time": "2019-08-10T08:37:15+00:00" - }, - { - "name": "paulgibbs/behat-wordpress-extension", - "version": "v3.3.0", - "source": { - "type": "git", - "url": "https://github.com/paulgibbs/behat-wordpress-extension.git", - "reference": "ebd86dec6e29e827b03e2aff9bbe3de5ad2ec396" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paulgibbs/behat-wordpress-extension/zipball/ebd86dec6e29e827b03e2aff9bbe3de5ad2ec396", - "reference": "ebd86dec6e29e827b03e2aff9bbe3de5ad2ec396", - "shasum": "" - }, - "require": { - "behat/behat": "~3.1", - "behat/mink-extension": "~2.3", - "php": ">=7.2 <7.4", - "sensiolabs/behat-page-object-extension": "~2.1" - }, - "require-dev": { - "behat/mink-goutte-driver": "^1.2", - "dmore/behat-chrome-extension": "^1.3", - "genesis/behat-fail-aid": "^2.0", - "phpstan/phpstan": "~0.9", - "squizlabs/php_codesniffer": "~3.0", - "wp-cli/wp-cli-bundle": "~2.1" - }, - "suggest": { - "behat/mink-goutte-driver": "Headless Mink driver", - "behat/mink-selenium2-driver": "JS-enabled Mink driver (requires Selenium)", - "dmore/behat-chrome-extension": "JS-enabled Mink driver for Chrome (does not require Selenium)", - "genesis/behat-fail-aid": "Get more out of your test suite by getting it to work with you when tests fail." - }, - "type": "behat-extension", - "extra": { - "wordpress-install-dir": "tests/app/www" - }, - "autoload": { - "psr-4": { - "PaulGibbs\\WordpressBehatExtension\\": "src" - }, - "files": [ - "src/Util/functions.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "GPL-3.0-or-later" - ], - "authors": [ - { - "name": "Paul Gibbs", - "email": "djpaul@gmail.com", - "homepage": "https://byotos.com" - } - ], - "description": "WordHat is a Behat extension for WordPress. It provides WordPress-specific functionality for common testing scenarios specific to WordPress sites.", - "homepage": "https://wordhat.info", - "keywords": [ - "BDD", - "Behat", - "extension", - "wordpress" - ], - "support": { - "issues": "https://github.com/paulgibbs/behat-wordpress-extension/issues", - "source": "https://github.com/paulgibbs/behat-wordpress-extension/tree/v3.3.0" - }, - "abandoned": true, - "time": "2019-06-24T19:27:08+00:00" - }, - { - "name": "phpcompatibility/php-compatibility", - "version": "9.3.5", - "source": { - "type": "git", - "url": "https://github.com/PHPCompatibility/PHPCompatibility.git", - "reference": "9fb324479acf6f39452e0655d2429cc0d3914243" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9fb324479acf6f39452e0655d2429cc0d3914243", - "reference": "9fb324479acf6f39452e0655d2429cc0d3914243", - "shasum": "" - }, - "require": { - "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.3 || ^3.0.2" - }, - "conflict": { - "squizlabs/php_codesniffer": "2.6.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0" - }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.", - "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." - }, - "type": "phpcodesniffer-standard", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Wim Godden", - "homepage": "https://github.com/wimg", - "role": "lead" - }, - { - "name": "Juliette Reinders Folmer", - "homepage": "https://github.com/jrfnl", - "role": "lead" - }, - { - "name": "Contributors", - "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors" - } - ], - "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.", - "homepage": "http://techblog.wimgodden.be/tag/codesniffer/", - "keywords": [ - "compatibility", - "phpcs", - "standards" - ], - "support": { - "issues": "https://github.com/PHPCompatibility/PHPCompatibility/issues", - "source": "https://github.com/PHPCompatibility/PHPCompatibility" - }, - "time": "2019-12-27T09:44:58+00:00" - }, - { - "name": "phpcompatibility/phpcompatibility-paragonie", - "version": "1.3.1", - "source": { - "type": "git", - "url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git", - "reference": "ddabec839cc003651f2ce695c938686d1086cf43" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/ddabec839cc003651f2ce695c938686d1086cf43", - "reference": "ddabec839cc003651f2ce695c938686d1086cf43", - "shasum": "" - }, - "require": { - "phpcompatibility/php-compatibility": "^9.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7", - "paragonie/random_compat": "dev-master", - "paragonie/sodium_compat": "dev-master" - }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", - "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." - }, - "type": "phpcodesniffer-standard", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Wim Godden", - "role": "lead" - }, - { - "name": "Juliette Reinders Folmer", - "role": "lead" - } - ], - "description": "A set of rulesets for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by the Paragonie polyfill libraries.", - "homepage": "http://phpcompatibility.com/", - "keywords": [ - "compatibility", - "paragonie", - "phpcs", - "polyfill", - "standards" - ], - "support": { - "issues": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie/issues", - "source": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie" - }, - "time": "2021-02-15T10:24:51+00:00" - }, - { - "name": "phpcompatibility/phpcompatibility-wp", - "version": "2.1.1", - "source": { - "type": "git", - "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git", - "reference": "b7dc0cd7a8f767ccac5e7637550ea1c50a67b09e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/b7dc0cd7a8f767ccac5e7637550ea1c50a67b09e", - "reference": "b7dc0cd7a8f767ccac5e7637550ea1c50a67b09e", - "shasum": "" - }, - "require": { - "phpcompatibility/php-compatibility": "^9.0", - "phpcompatibility/phpcompatibility-paragonie": "^1.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7" - }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", - "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." - }, - "type": "phpcodesniffer-standard", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Wim Godden", - "role": "lead" - }, - { - "name": "Juliette Reinders Folmer", - "role": "lead" - } - ], - "description": "A ruleset for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by WordPress.", - "homepage": "http://phpcompatibility.com/", - "keywords": [ - "compatibility", - "phpcs", - "standards", - "wordpress" - ], - "support": { - "issues": "https://github.com/PHPCompatibility/PHPCompatibilityWP/issues", - "source": "https://github.com/PHPCompatibility/PHPCompatibilityWP" - }, - "time": "2021-02-15T12:58:46+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" - }, - "time": "2020-06-27T09:03:43+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "5.2.2", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", - "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master" - }, - "time": "2020-09-03T19:13:55+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.4.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", - "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0" - }, - "time": "2020-09-17T18:55:26+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "v1.10.3", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "451c3cd1418cf640de218914901e51b064abb093" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093", - "reference": "451c3cd1418cf640de218914901e51b064abb093", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", - "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^2.5 || ^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.10.3" - }, - "time": "2020-03-05T15:02:03+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "2.2.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-file-iterator": "~1.3", - "phpunit/php-text-template": "~1.2", - "phpunit/php-token-stream": "~1.3", - "sebastian/environment": "^1.3.2", - "sebastian/version": "~1.0" - }, - "require-dev": { - "ext-xdebug": ">=2.1.4", - "phpunit/phpunit": "~4" - }, - "suggest": { - "ext-dom": "*", - "ext-xdebug": ">=2.2.1", - "ext-xmlwriter": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "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" - ], - "support": { - "irc": "irc://irc.freenode.net/phpunit", - "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/2.2" - }, - "time": "2015-10-06T15:47:00+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.4.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "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" - ], - "support": { - "irc": "irc://irc.freenode.net/phpunit", - "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/1.4.5" - }, - "time": "2017-11-27T13:52:08+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "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": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" - }, - "time": "2015-06-21T13:50:34+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "1.0.9", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "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" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/master" - }, - "time": "2017-02-26T11:10:40+00:00" - }, - { - "name": "phpunit/php-token-stream", - "version": "1.4.12", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1ce90ba27c42e4e44e6d8458241466380b51fa16", - "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", - "source": "https://github.com/sebastianbergmann/php-token-stream/tree/1.4" - }, - "abandoned": true, - "time": "2017-12-04T08:55:13+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "4.8.36", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "46023de9a91eec7dfb06cc56cb4e260017298517" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517", - "reference": "46023de9a91eec7dfb06cc56cb4e260017298517", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=5.3.3", - "phpspec/prophecy": "^1.3.1", - "phpunit/php-code-coverage": "~2.1", - "phpunit/php-file-iterator": "~1.4", - "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": "^1.0.6", - "phpunit/phpunit-mock-objects": "~2.3", - "sebastian/comparator": "~1.2.2", - "sebastian/diff": "~1.2", - "sebastian/environment": "~1.3", - "sebastian/exporter": "~1.2", - "sebastian/global-state": "~1.0", - "sebastian/version": "~1.0", - "symfony/yaml": "~2.1|~3.0" - }, - "suggest": { - "phpunit/php-invoker": "~1.1" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.8.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": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/4.8.36" - }, - "time": "2017-06-21T08:07:12+00:00" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "2.3.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": ">=5.3.3", - "phpunit/php-text-template": "~1.2", - "sebastian/exporter": "~1.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "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" - ], - "support": { - "irc": "irc://irc.freenode.net/phpunit", - "issues": "https://github.com/sebastianbergmann/phpunit-mock-objects/issues", - "source": "https://github.com/sebastianbergmann/phpunit-mock-objects/tree/2.3" - }, - "abandoned": true, - "time": "2015-10-02T06:51:40+00:00" - }, - { - "name": "psr/container", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", - "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", - "shasum": "" - }, - "require": { - "php": ">=7.2.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Psr\\Container\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", - "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" - ], - "support": { - "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.1" - }, - "time": "2021-03-05T17:36:06+00:00" - }, - { - "name": "psr/http-message", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "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" - ], - "support": { - "source": "https://github.com/php-fig/http-message/tree/master" - }, - "time": "2016-08-06T14:39:51+00:00" - }, - { - "name": "psr/log", - "version": "1.1.4", - "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" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "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" - }, - "time": "2021-05-03T11:20:27+00:00" - }, - { - "name": "ralouphie/getallheaders", - "version": "3.0.3", - "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" - }, - "type": "library", - "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" - }, - "time": "2019-03-08T08:55:37+00:00" - }, - { - "name": "rmccue/requests", - "version": "v1.8.0", - "source": { - "type": "git", - "url": "https://github.com/WordPress/Requests.git", - "reference": "afbe4790e4def03581c4a0963a1e8aa01f6030f1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/WordPress/Requests/zipball/afbe4790e4def03581c4a0963a1e8aa01f6030f1", - "reference": "afbe4790e4def03581c4a0963a1e8aa01f6030f1", - "shasum": "" - }, - "require": { - "php": ">=5.2" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7", - "php-parallel-lint/php-console-highlighter": "^0.5.0", - "php-parallel-lint/php-parallel-lint": "^1.3", - "phpcompatibility/php-compatibility": "^9.0", - "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.5", - "requests/test-server": "dev-master", - "squizlabs/php_codesniffer": "^3.5", - "wp-coding-standards/wpcs": "^2.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "Requests": "library/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Ryan McCue", - "homepage": "http://ryanmccue.info" - } - ], - "description": "A HTTP library written in PHP, for human beings.", - "homepage": "http://github.com/WordPress/Requests", - "keywords": [ - "curl", - "fsockopen", - "http", - "idna", - "ipv6", - "iri", - "sockets" - ], - "support": { - "issues": "https://github.com/WordPress/Requests/issues", - "source": "https://github.com/WordPress/Requests/tree/v1.8.0" - }, - "time": "2021-04-27T11:05:25+00:00" - }, - { - "name": "sebastian/comparator", - "version": "1.2.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", - "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2 || ~2.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "http://www.github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/1.2" - }, - "time": "2017-01-29T09:50:25+00:00" - }, - { - "name": "sebastian/diff", - "version": "1.4.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", - "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/1.4" - }, - "time": "2017-05-22T07:24:03+00:00" - }, - { - "name": "sebastian/environment", - "version": "1.3.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8 || ^5.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/1.3" - }, - "time": "2016-08-18T05:49:44+00:00" - }, - { - "name": "sebastian/exporter", - "version": "1.2.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", - "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "sebastian/recursion-context": "~1.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/master" - }, - "time": "2016-06-17T09:04:28+00:00" - }, - { - "name": "sebastian/global-state", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/1.1.1" - }, - "time": "2015-10-12T03:26:01+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", - "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "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": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/master" - }, - "time": "2016-10-03T07:41:43+00:00" - }, - { - "name": "sebastian/version", - "version": "1.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "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", - "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/1.0.6" - }, - "time": "2015-06-21T13:59:46+00:00" - }, - { - "name": "seld/jsonlint", - "version": "1.8.3", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/jsonlint.git", - "reference": "9ad6ce79c342fbd44df10ea95511a1b24dee5b57" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/9ad6ce79c342fbd44df10ea95511a1b24dee5b57", - "reference": "9ad6ce79c342fbd44df10ea95511a1b24dee5b57", - "shasum": "" - }, - "require": { - "php": "^5.3 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" - }, - "bin": [ - "bin/jsonlint" - ], - "type": "library", - "autoload": { - "psr-4": { - "Seld\\JsonLint\\": "src/Seld/JsonLint/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "JSON Linter", - "keywords": [ - "json", - "linter", - "parser", - "validator" - ], - "support": { - "issues": "https://github.com/Seldaek/jsonlint/issues", - "source": "https://github.com/Seldaek/jsonlint/tree/1.8.3" - }, - "funding": [ - { - "url": "https://github.com/Seldaek", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/seld/jsonlint", - "type": "tidelift" - } - ], - "time": "2020-11-11T09:19:24+00:00" - }, - { - "name": "seld/phar-utils", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/phar-utils.git", - "reference": "8674b1d84ffb47cc59a101f5d5a3b61e87d23796" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/8674b1d84ffb47cc59a101f5d5a3b61e87d23796", - "reference": "8674b1d84ffb47cc59a101f5d5a3b61e87d23796", - "shasum": "" - }, - "require": { - "php": ">=5.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Seld\\PharUtils\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be" - } - ], - "description": "PHAR file format utilities, for when PHP phars you up", - "keywords": [ - "phar" - ], - "support": { - "issues": "https://github.com/Seldaek/phar-utils/issues", - "source": "https://github.com/Seldaek/phar-utils/tree/master" - }, - "time": "2020-07-07T18:42:57+00:00" - }, - { - "name": "sensiolabs/behat-page-object-extension", - "version": "v2.3.2", - "source": { - "type": "git", - "url": "https://github.com/sensiolabs/BehatPageObjectExtension.git", - "reference": "408bc81cafb824ca8d2a1d9435f3d50b9075d3aa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sensiolabs/BehatPageObjectExtension/zipball/408bc81cafb824ca8d2a1d9435f3d50b9075d3aa", - "reference": "408bc81cafb824ca8d2a1d9435f3d50b9075d3aa", - "shasum": "" - }, - "require": { - "behat/behat": "^3.3", - "behat/mink": "^1.7", - "friends-of-behat/mink-extension": "^2.2", - "ocramius/proxy-manager": "^2.1.1", - "php": "^7.2" - }, - "conflict": { - "guzzlehttp/guzzle": "<6.3" - }, - "require-dev": { - "behat/mink-goutte-driver": "^1.2", - "bossa/phpspec2-expect": "^3.1.1", - "fabpot/goutte": "^3.2", - "phpspec/phpspec": "^6.1", - "symfony/filesystem": "^4.2 || ^5.0", - "symfony/process": "^4.2 || ^5.0", - "symfony/yaml": "^4.2 || ^5.0" - }, - "suggest": { - "bossa/phpspec2-expect": "Allows to use PHPSpec2 matchers in Behat context files" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "SensioLabs\\Behat\\PageObjectExtension\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marcello Duarte", - "email": "mduarte@inviqa.com" - }, - { - "name": "Jakub Zalas", - "email": "jakub@zalas.pl" - } - ], - "description": "Page object extension for Behat", - "homepage": "https://github.com/sensiolabs/BehatPageObjectExtension", - "keywords": [ - "BDD", - "Behat", - "page" - ], - "support": { - "issues": "https://github.com/sensiolabs/BehatPageObjectExtension/issues", - "source": "https://github.com/sensiolabs/BehatPageObjectExtension/tree/v2.3.2" - }, - "time": "2020-06-18T10:20:26+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.6.0", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "ffced0d2c8fa8e6cdc4d695a743271fab6c38625" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ffced0d2c8fa8e6cdc4d695a743271fab6c38625", - "reference": "ffced0d2c8fa8e6cdc4d695a743271fab6c38625", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "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", - "keywords": [ - "phpcs", - "standards" - ], - "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" - }, - "time": "2021-04-09T00:54:41+00:00" - }, - { - "name": "symfony/browser-kit", - "version": "v4.4.22", - "source": { - "type": "git", - "url": "https://github.com/symfony/browser-kit.git", - "reference": "4c8b42b4aae93517e8f67d68c5cbe69413e3e3c1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/4c8b42b4aae93517e8f67d68c5cbe69413e3e3c1", - "reference": "4c8b42b4aae93517e8f67d68c5cbe69413e3e3c1", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "symfony/dom-crawler": "^3.4|^4.0|^5.0" - }, - "require-dev": { - "symfony/css-selector": "^3.4|^4.0|^5.0", - "symfony/http-client": "^4.3|^5.0", - "symfony/mime": "^4.3|^5.0", - "symfony/process": "^3.4|^4.0|^5.0" - }, - "suggest": { - "symfony/process": "" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\BrowserKit\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/browser-kit/tree/v4.4.22" - }, - "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": "2021-04-08T07:40:10+00:00" - }, - { - "name": "symfony/config", - "version": "v5.2.8", - "source": { - "type": "git", - "url": "https://github.com/symfony/config.git", - "reference": "8dfa5f8adea9cd5155920069224beb04f11d6b7e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/8dfa5f8adea9cd5155920069224beb04f11d6b7e", - "reference": "8dfa5f8adea9cd5155920069224beb04f11d6b7e", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/filesystem": "^4.4|^5.0", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-php80": "^1.15" - }, - "conflict": { - "symfony/finder": "<4.4" - }, - "require-dev": { - "symfony/event-dispatcher": "^4.4|^5.0", - "symfony/finder": "^4.4|^5.0", - "symfony/messenger": "^4.4|^5.0", - "symfony/service-contracts": "^1.1|^2", - "symfony/yaml": "^4.4|^5.0" - }, - "suggest": { - "symfony/yaml": "To use the yaml reference dumper" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Config\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/config/tree/v5.2.8" - }, - "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": "2021-05-07T13:41:16+00:00" - }, - { - "name": "symfony/console", - "version": "v4.4.23", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "1ab187ac21d41d7d34a4f529091a1f5d0bb2924f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/1ab187ac21d41d7d34a4f529091a1f5d0bb2924f", - "reference": "1ab187ac21d41d7d34a4f529091a1f5d0bb2924f", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "^1.8", - "symfony/polyfill-php80": "^1.15", - "symfony/service-contracts": "^1.1|^2" - }, - "conflict": { - "symfony/dependency-injection": "<3.4", - "symfony/event-dispatcher": "<4.3|>=5", - "symfony/lock": "<4.4", - "symfony/process": "<3.3" - }, - "provide": { - "psr/log-implementation": "1.0" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/event-dispatcher": "^4.3", - "symfony/lock": "^4.4|^5.0", - "symfony/process": "^3.4|^4.0|^5.0", - "symfony/var-dumper": "^4.3|^5.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Eases the creation of beautiful and testable command line interfaces", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/console/tree/v4.4.23" - }, - "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": "2021-05-10T12:53:15+00:00" - }, - { - "name": "symfony/css-selector", - "version": "v3.4.47", - "source": { - "type": "git", - "url": "https://github.com/symfony/css-selector.git", - "reference": "da3d9da2ce0026771f5fe64cb332158f1bd2bc33" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/da3d9da2ce0026771f5fe64cb332158f1bd2bc33", - "reference": "da3d9da2ce0026771f5fe64cb332158f1bd2bc33", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\CssSelector\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Jean-François Simon", - "email": "jeanfrancois.simon@sensiolabs.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony CssSelector Component", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/css-selector/tree/v3.4.47" - }, - "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": "2020-10-24T10:57:07+00:00" - }, - { - "name": "symfony/dependency-injection", - "version": "v4.3.11", - "source": { - "type": "git", - "url": "https://github.com/symfony/dependency-injection.git", - "reference": "468bfb60a60b7caa03e4722c43f5359df47b4349" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/468bfb60a60b7caa03e4722c43f5359df47b4349", - "reference": "468bfb60a60b7caa03e4722c43f5359df47b4349", - "shasum": "" - }, - "require": { - "php": "^7.1.3", - "psr/container": "^1.0", - "symfony/service-contracts": "^1.1.6" - }, - "conflict": { - "symfony/config": "<4.3", - "symfony/finder": "<3.4", - "symfony/proxy-manager-bridge": "<3.4", - "symfony/yaml": "<3.4" - }, - "provide": { - "psr/container-implementation": "1.0", - "symfony/service-implementation": "1.0" - }, - "require-dev": { - "symfony/config": "^4.3", - "symfony/expression-language": "~3.4|~4.0", - "symfony/yaml": "~3.4|~4.0" - }, - "suggest": { - "symfony/config": "", - "symfony/expression-language": "For using expressions in service container configuration", - "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", - "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", - "symfony/yaml": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.3-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\DependencyInjection\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony DependencyInjection Component", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v4.3.10" - }, - "time": "2020-01-14T16:43:06+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v2.4.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5f38c8804a9e97d23e0c8d63341088cd8a22d627", - "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.4-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "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/v2.4.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": "2021-03-23T23:28:01+00:00" - }, - { - "name": "symfony/dom-crawler", - "version": "v4.4.20", - "source": { - "type": "git", - "url": "https://github.com/symfony/dom-crawler.git", - "reference": "be133557f1b0e6672367325b508e65da5513a311" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/be133557f1b0e6672367325b508e65da5513a311", - "reference": "be133557f1b0e6672367325b508e65da5513a311", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "masterminds/html5": "<2.6" - }, - "require-dev": { - "masterminds/html5": "^2.6", - "symfony/css-selector": "^3.4|^4.0|^5.0" - }, - "suggest": { - "symfony/css-selector": "" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\DomCrawler\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Eases DOM navigation for HTML and XML documents", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v4.4.20" - }, - "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": "2021-02-14T12:29:41+00:00" - }, - { - "name": "symfony/event-dispatcher", - "version": "v4.4.20", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "c352647244bd376bf7d31efbd5401f13f50dad0c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/c352647244bd376bf7d31efbd5401f13f50dad0c", - "reference": "c352647244bd376bf7d31efbd5401f13f50dad0c", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "symfony/event-dispatcher-contracts": "^1.1" - }, - "conflict": { - "symfony/dependency-injection": "<3.4" - }, - "provide": { - "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "1.1" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/error-handler": "~3.4|~4.4", - "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/http-foundation": "^3.4|^4.0|^5.0", - "symfony/service-contracts": "^1.1|^2", - "symfony/stopwatch": "^3.4|^4.0|^5.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v4.4.20" - }, - "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": "2021-01-27T09:09:26+00:00" - }, - { - "name": "symfony/event-dispatcher-contracts", - "version": "v1.1.9", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "84e23fdcd2517bf37aecbd16967e83f0caee25a7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/84e23fdcd2517bf37aecbd16967e83f0caee25a7", - "reference": "84e23fdcd2517bf37aecbd16967e83f0caee25a7", - "shasum": "" - }, - "require": { - "php": ">=7.1.3" - }, - "suggest": { - "psr/event-dispatcher": "", - "symfony/event-dispatcher-implementation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\EventDispatcher\\": "" - } - }, - "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": "Generic abstractions related to dispatching event", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v1.1.9" - }, - "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": "2020-07-06T13:19:58+00:00" - }, - { - "name": "symfony/filesystem", - "version": "v5.2.7", - "source": { - "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "056e92acc21d977c37e6ea8e97374b2a6c8551b0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/056e92acc21d977c37e6ea8e97374b2a6c8551b0", - "reference": "056e92acc21d977c37e6ea8e97374b2a6c8551b0", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/polyfill-ctype": "~1.8" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Filesystem\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides basic utilities for the filesystem", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/filesystem/tree/v5.2.7" - }, - "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": "2021-04-01T10:42:13+00:00" - }, - { - "name": "symfony/finder", - "version": "v5.2.8", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "eccb8be70d7a6a2230d05f6ecede40f3fdd9e252" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/eccb8be70d7a6a2230d05f6ecede40f3fdd9e252", - "reference": "eccb8be70d7a6a2230d05f6ecede40f3fdd9e252", - "shasum": "" - }, - "require": { - "php": ">=7.2.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Finds files and directories via an intuitive fluent interface", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/finder/tree/v5.2.8" - }, - "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": "2021-05-10T14:39:23+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.22.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", - "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.22-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1" - }, - "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": "2021-01-07T16:49:33+00:00" - }, - { - "name": "symfony/polyfill-intl-idn", - "version": "v1.22.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "2d63434d922daf7da8dd863e7907e67ee3031483" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/2d63434d922daf7da8dd863e7907e67ee3031483", - "reference": "2d63434d922daf7da8dd863e7907e67ee3031483", - "shasum": "" - }, - "require": { - "php": ">=7.1", - "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php72": "^1.10" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.22-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Intl\\Idn\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Laurent Bassin", - "email": "laurent@bassin.info" - }, - { - "name": "Trevor Rowbotham", - "email": "trevor.rowbotham@pm.me" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "idn", - "intl", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.22.1" - }, - "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": "2021-01-22T09:19:47+00:00" - }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.22.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/43a0283138253ed1d48d352ab6d0bdb3f809f248", - "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.22-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, - "files": [ - "bootstrap.php" - ], - "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 for intl's Normalizer class and related functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "intl", - "normalizer", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.1" - }, - "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": "2021-01-22T09:19:47+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.22.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "5232de97ee3b75b0360528dae24e73db49566ab1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1", - "reference": "5232de97ee3b75b0360528dae24e73db49566ab1", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.22-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, - "files": [ - "bootstrap.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": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.1" - }, - "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": "2021-01-22T09:19:47+00:00" - }, - { - "name": "symfony/polyfill-php72", - "version": "v1.22.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", - "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.22-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - }, - "files": [ - "bootstrap.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": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.22.1" - }, - "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": "2021-01-07T16:49:33+00:00" - }, - { - "name": "symfony/polyfill-php73", - "version": "v1.22.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", - "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.22-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" - }, - "files": [ - "bootstrap.php" - ], - "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 7.3+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.22.1" - }, - "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": "2021-01-07T16:49:33+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.22.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91", - "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.22-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.1" - }, - "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": "2021-01-07T16:49:33+00:00" - }, - { - "name": "symfony/process", - "version": "v5.2.7", - "source": { - "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "98cb8eeb72e55d4196dd1e36f1f16e7b3a9a088e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/98cb8eeb72e55d4196dd1e36f1f16e7b3a9a088e", - "reference": "98cb8eeb72e55d4196dd1e36f1f16e7b3a9a088e", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.15" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Process\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Executes commands in sub-processes", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/process/tree/v5.3.0-BETA1" - }, - "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": "2021-04-08T10:27:02+00:00" - }, - { - "name": "symfony/service-contracts", - "version": "v1.1.9", - "source": { - "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "b776d18b303a39f56c63747bcb977ad4b27aca26" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/b776d18b303a39f56c63747bcb977ad4b27aca26", - "reference": "b776d18b303a39f56c63747bcb977ad4b27aca26", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "psr/container": "^1.0" - }, - "suggest": { - "symfony/service-implementation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Service\\": "" - } - }, - "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": "Generic abstractions related to writing services", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/service-contracts/tree/v1.1.9" - }, - "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": "2020-07-06T13:19:58+00:00" - }, - { - "name": "symfony/translation", - "version": "v4.4.23", - "source": { - "type": "git", - "url": "https://github.com/symfony/translation.git", - "reference": "ff6e63c7b5de874464642969968f61f8dc649ac3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/ff6e63c7b5de874464642969968f61f8dc649ac3", - "reference": "ff6e63c7b5de874464642969968f61f8dc649ac3", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/translation-contracts": "^1.1.6|^2" - }, - "conflict": { - "symfony/config": "<3.4", - "symfony/dependency-injection": "<3.4", - "symfony/http-kernel": "<4.4", - "symfony/yaml": "<3.4" - }, - "provide": { - "symfony/translation-implementation": "1.0|2.0" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/console": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/finder": "~2.8|~3.0|~4.0|^5.0", - "symfony/http-kernel": "^4.4", - "symfony/intl": "^3.4|^4.0|^5.0", - "symfony/service-contracts": "^1.1.2|^2", - "symfony/yaml": "^3.4|^4.0|^5.0" - }, - "suggest": { - "psr/log-implementation": "To use logging capability in translator", - "symfony/config": "", - "symfony/yaml": "" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Translation\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides tools to internationalize your application", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/translation/tree/v4.4.23" - }, - "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": "2021-04-28T06:59:52+00:00" - }, - { - "name": "symfony/translation-contracts", - "version": "v2.4.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/translation-contracts.git", - "reference": "95c812666f3e91db75385749fe219c5e494c7f95" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/95c812666f3e91db75385749fe219c5e494c7f95", - "reference": "95c812666f3e91db75385749fe219c5e494c7f95", - "shasum": "" - }, - "require": { - "php": ">=7.2.5" - }, - "suggest": { - "symfony/translation-implementation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.4-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Translation\\": "" - } - }, - "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": "Generic abstractions related to translation", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v2.4.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": "2021-03-23T23:28:01+00:00" - }, - { - "name": "symfony/yaml", - "version": "v3.4.47", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "88289caa3c166321883f67fe5130188ebbb47094" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/88289caa3c166321883f67fe5130188ebbb47094", - "reference": "88289caa3c166321883f67fe5130188ebbb47094", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8", - "symfony/polyfill-ctype": "~1.8" - }, - "conflict": { - "symfony/console": "<3.4" - }, - "require-dev": { - "symfony/console": "~3.4|~4.0" - }, - "suggest": { - "symfony/console": "For validating YAML files using the lint command" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Yaml Component", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/yaml/tree/v3.4.47" - }, - "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": "2020-10-24T10:57:07+00:00" - }, - { - "name": "textalk/websocket", - "version": "1.5.3", - "source": { - "type": "git", - "url": "https://github.com/Textalk/websocket-php.git", - "reference": "25f6e322bfaf978a665391efdddc135d4edd60eb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Textalk/websocket-php/zipball/25f6e322bfaf978a665391efdddc135d4edd60eb", - "reference": "25f6e322bfaf978a665391efdddc135d4edd60eb", - "shasum": "" - }, - "require": { - "php": "^7.2 | ^8.0", - "psr/log": "^1.0" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.0", - "phpunit/phpunit": "^8.0|^9.0", - "squizlabs/php_codesniffer": "^3.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "WebSocket\\": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Fredrik Liljegren" - }, - { - "name": "Sören Jensen", - "email": "soren@abicart.se" - } - ], - "description": "WebSocket client and server", - "support": { - "issues": "https://github.com/Textalk/websocket-php/issues", - "source": "https://github.com/Textalk/websocket-php/tree/1.5.3" - }, - "time": "2021-04-18T15:27:16+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.10.0", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.10.0" - }, - "time": "2021-03-09T10:59:23+00:00" - }, - { - "name": "wp-cli/cache-command", - "version": "v2.0.5", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/cache-command.git", - "reference": "c1a91b35f274e8aa5142eb4d82842421ed89049a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/cache-command/zipball/c1a91b35f274e8aa5142eb4d82842421ed89049a", - "reference": "c1a91b35f274e8aa5142eb4d82842421ed89049a", - "shasum": "" - }, - "require": { - "wp-cli/wp-cli": "^2" - }, - "require-dev": { - "wp-cli/entity-command": "^1.3 || ^2", - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "cache", - "cache add", - "cache decr", - "cache delete", - "cache flush", - "cache get", - "cache incr", - "cache replace", - "cache set", - "cache type", - "transient", - "transient delete", - "transient get", - "transient set", - "transient type", - "transient list" - ] - }, - "autoload": { - "psr-4": { - "": "src/" - }, - "files": [ - "cache-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - } - ], - "description": "Manages object and transient caches.", - "homepage": "https://github.com/wp-cli/cache-command", - "support": { - "issues": "https://github.com/wp-cli/cache-command/issues", - "source": "https://github.com/wp-cli/cache-command/tree/v2.0.5" - }, - "time": "2020-12-07T19:32:47+00:00" - }, - { - "name": "wp-cli/checksum-command", - "version": "v2.0.5", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/checksum-command.git", - "reference": "a03cb058fcb295b8a1b060cc90618e777b86ad49" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/checksum-command/zipball/a03cb058fcb295b8a1b060cc90618e777b86ad49", - "reference": "a03cb058fcb295b8a1b060cc90618e777b86ad49", - "shasum": "" - }, - "require": { - "wp-cli/wp-cli": "^2" - }, - "require-dev": { - "wp-cli/extension-command": "^1.2 || ^2", - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "core verify-checksums", - "plugin verify-checksums" - ] - }, - "autoload": { - "psr-4": { - "": "src/" - }, - "files": [ - "checksum-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - } - ], - "description": "Verifies file integrity by comparing to published checksums.", - "homepage": "https://github.com/wp-cli/checksum-command", - "support": { - "issues": "https://github.com/wp-cli/checksum-command/issues", - "source": "https://github.com/wp-cli/checksum-command/tree/v2.0.5" - }, - "time": "2020-12-07T22:47:40+00:00" - }, - { - "name": "wp-cli/config-command", - "version": "v2.0.7", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/config-command.git", - "reference": "6468e97ab2ace5b0a448d9e19091d42f6461b466" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/config-command/zipball/6468e97ab2ace5b0a448d9e19091d42f6461b466", - "reference": "6468e97ab2ace5b0a448d9e19091d42f6461b466", - "shasum": "" - }, - "require": { - "wp-cli/wp-cli": "^2", - "wp-cli/wp-config-transformer": "^1.2.1" - }, - "require-dev": { - "wp-cli/db-command": "^1.3 || ^2", - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "config", - "config edit", - "config delete", - "config create", - "config get", - "config has", - "config list", - "config path", - "config set", - "config shuffle-salts" - ] - }, - "autoload": { - "psr-4": { - "": "src/" - }, - "files": [ - "config-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - }, - { - "name": "Alain Schlesser", - "email": "alain.schlesser@gmail.com", - "homepage": "https://www.alainschlesser.com" - } - ], - "description": "Generates and reads the wp-config.php file.", - "homepage": "https://github.com/wp-cli/config-command", - "support": { - "issues": "https://github.com/wp-cli/config-command/issues", - "source": "https://github.com/wp-cli/config-command/tree/v2.0.7" - }, - "time": "2020-10-31T11:20:34+00:00" - }, - { - "name": "wp-cli/core-command", - "version": "v2.0.12", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/core-command.git", - "reference": "a7001bd43b58fe67decd02c739615102cc0beb51" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/core-command/zipball/a7001bd43b58fe67decd02c739615102cc0beb51", - "reference": "a7001bd43b58fe67decd02c739615102cc0beb51", - "shasum": "" - }, - "require": { - "composer/semver": "^1.4 || ^2 || ^3", - "wp-cli/wp-cli": "^2.4" - }, - "require-dev": { - "wp-cli/checksum-command": "^1 || ^2", - "wp-cli/db-command": "^1.3 || ^2", - "wp-cli/entity-command": "^1.3 || ^2", - "wp-cli/extension-command": "^1.2 || ^2", - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "core", - "core check-update", - "core download", - "core install", - "core is-installed", - "core multisite-convert", - "core multisite-install", - "core update", - "core update-db", - "core version" - ] - }, - "autoload": { - "psr-4": { - "": "src/" - }, - "files": [ - "core-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - } - ], - "description": "Downloads, installs, updates, and manages a WordPress installation.", - "homepage": "https://github.com/wp-cli/core-command", - "support": { - "issues": "https://github.com/wp-cli/core-command/issues", - "source": "https://github.com/wp-cli/core-command/tree/v2.0.12" - }, - "time": "2020-12-07T19:31:14+00:00" - }, - { - "name": "wp-cli/cron-command", - "version": "v2.0.6", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/cron-command.git", - "reference": "668b8c7bc1c1a1930e8a956b1a8325d159cce78c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/cron-command/zipball/668b8c7bc1c1a1930e8a956b1a8325d159cce78c", - "reference": "668b8c7bc1c1a1930e8a956b1a8325d159cce78c", - "shasum": "" - }, - "require": { - "wp-cli/wp-cli": "^2" - }, - "require-dev": { - "wp-cli/entity-command": "^1.3 || ^2", - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "cron", - "cron test", - "cron event", - "cron event delete", - "cron event list", - "cron event run", - "cron event schedule", - "cron schedule", - "cron schedule list", - "cron event unschedule" - ] - }, - "autoload": { - "psr-4": { - "": "src/" - }, - "files": [ - "cron-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - } - ], - "description": "Tests, runs, and deletes WP-Cron events; manages WP-Cron schedules.", - "homepage": "https://github.com/wp-cli/cron-command", - "support": { - "issues": "https://github.com/wp-cli/cron-command/issues", - "source": "https://github.com/wp-cli/cron-command/tree/v2.0.6" - }, - "time": "2020-12-07T19:30:59+00:00" - }, - { - "name": "wp-cli/db-command", - "version": "v2.0.6", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/db-command.git", - "reference": "8e3cd46987241ed97ddb7f682b3505dff8d6dce4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/db-command/zipball/8e3cd46987241ed97ddb7f682b3505dff8d6dce4", - "reference": "8e3cd46987241ed97ddb7f682b3505dff8d6dce4", - "shasum": "" - }, - "require": { - "wp-cli/wp-cli": "^2" - }, - "require-dev": { - "wp-cli/entity-command": "^1.3 || ^2", - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "db", - "db clean", - "db create", - "db drop", - "db reset", - "db check", - "db optimize", - "db prefix", - "db repair", - "db cli", - "db query", - "db export", - "db import", - "db search", - "db tables", - "db size", - "db columns" - ] - }, - "autoload": { - "psr-4": { - "": "src/" - }, - "files": [ - "db-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - } - ], - "description": "Performs basic database operations using credentials stored in wp-config.php.", - "homepage": "https://github.com/wp-cli/db-command", - "support": { - "issues": "https://github.com/wp-cli/db-command/issues", - "source": "https://github.com/wp-cli/db-command/tree/v2.0.6" - }, - "time": "2020-01-28T16:39:32+00:00" - }, - { - "name": "wp-cli/embed-command", - "version": "v2.0.7", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/embed-command.git", - "reference": "93d5582a9b03e950d3a2fe0869ae2c12d55a6242" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/embed-command/zipball/93d5582a9b03e950d3a2fe0869ae2c12d55a6242", - "reference": "93d5582a9b03e950d3a2fe0869ae2c12d55a6242", - "shasum": "" - }, - "require": { - "wp-cli/wp-cli": "^2" - }, - "require-dev": { - "wp-cli/entity-command": "^1.3 || ^2", - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "embed", - "embed fetch", - "embed provider", - "embed provider list", - "embed provider match", - "embed handler", - "embed handler list", - "embed cache", - "embed cache clear", - "embed cache find", - "embed cache trigger" - ] - }, - "autoload": { - "psr-4": { - "WP_CLI\\Embeds\\": "src/" - }, - "files": [ - "embed-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Pascal Birchler", - "homepage": "https://pascalbirchler.com/" - } - ], - "description": "Inspects oEmbed providers, clears embed cache, and more.", - "homepage": "https://github.com/wp-cli/embed-command", - "support": { - "issues": "https://github.com/wp-cli/embed-command/issues", - "source": "https://github.com/wp-cli/embed-command/tree/v2.0.7" - }, - "time": "2020-12-07T19:30:42+00:00" - }, - { - "name": "wp-cli/entity-command", - "version": "v2.0.7", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/entity-command.git", - "reference": "0df89e4fba48177acf768bff9c00cda95a3fe5b9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/entity-command/zipball/0df89e4fba48177acf768bff9c00cda95a3fe5b9", - "reference": "0df89e4fba48177acf768bff9c00cda95a3fe5b9", - "shasum": "" - }, - "require": { - "wp-cli/wp-cli": "^2" - }, - "require-dev": { - "wp-cli/cache-command": "^1 || ^2", - "wp-cli/db-command": "^1.3 || ^2", - "wp-cli/extension-command": "^1.2 || ^2", - "wp-cli/media-command": "^1.1 || ^2", - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "comment", - "comment approve", - "comment count", - "comment create", - "comment delete", - "comment exists", - "comment generate", - "comment get", - "comment list", - "comment meta", - "comment meta add", - "comment meta delete", - "comment meta get", - "comment meta list", - "comment meta patch", - "comment meta pluck", - "comment meta update", - "comment recount", - "comment spam", - "comment status", - "comment trash", - "comment unapprove", - "comment unspam", - "comment untrash", - "comment update", - "menu", - "menu create", - "menu delete", - "menu item", - "menu item add-custom", - "menu item add-post", - "menu item add-term", - "menu item delete", - "menu item list", - "menu item update", - "menu list", - "menu location", - "menu location assign", - "menu location list", - "menu location remove", - "network meta", - "network meta add", - "network meta delete", - "network meta get", - "network meta list", - "network meta patch", - "network meta pluck", - "network meta update", - "option", - "option add", - "option delete", - "option get", - "option list", - "option patch", - "option pluck", - "option update", - "post", - "post create", - "post delete", - "post edit", - "post exists", - "post generate", - "post get", - "post list", - "post meta", - "post meta add", - "post meta delete", - "post meta get", - "post meta list", - "post meta patch", - "post meta pluck", - "post meta update", - "post term", - "post term add", - "post term list", - "post term remove", - "post term set", - "post update", - "post-type", - "post-type get", - "post-type list", - "site", - "site activate", - "site archive", - "site create", - "site deactivate", - "site delete", - "site empty", - "site list", - "site mature", - "site option", - "site private", - "site public", - "site spam", - "site unarchive", - "site unmature", - "site unspam", - "taxonomy", - "taxonomy get", - "taxonomy list", - "term", - "term create", - "term delete", - "term generate", - "term get", - "term list", - "term meta", - "term meta add", - "term meta delete", - "term meta get", - "term meta list", - "term meta patch", - "term meta pluck", - "term meta update", - "term recount", - "term update", - "user", - "user add-cap", - "user add-role", - "user create", - "user delete", - "user generate", - "user get", - "user import-csv", - "user list", - "user list-caps", - "user meta", - "user meta add", - "user meta delete", - "user meta get", - "user meta list", - "user meta patch", - "user meta pluck", - "user meta update", - "user remove-cap", - "user remove-role", - "user reset-password", - "user session", - "user session destroy", - "user session list", - "user set-role", - "user spam", - "user term", - "user term add", - "user term list", - "user term remove", - "user term set", - "user unspam", - "user update" - ] - }, - "autoload": { - "psr-4": { - "": "src/", - "WP_CLI\\": "src/WP_CLI" - }, - "files": [ - "entity-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - } - ], - "description": "Manage WordPress comments, menus, options, posts, sites, terms, and users.", - "homepage": "https://github.com/wp-cli/entity-command", - "support": { - "issues": "https://github.com/wp-cli/entity-command/issues", - "source": "https://github.com/wp-cli/entity-command/tree/master" - }, - "time": "2019-11-12T11:32:14+00:00" - }, - { - "name": "wp-cli/eval-command", - "version": "v2.0.8", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/eval-command.git", - "reference": "8a5e0340e82e1fb2b48a5dedd88cef1fb8b410ce" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/eval-command/zipball/8a5e0340e82e1fb2b48a5dedd88cef1fb8b410ce", - "reference": "8a5e0340e82e1fb2b48a5dedd88cef1fb8b410ce", - "shasum": "" - }, - "require": { - "wp-cli/wp-cli": "^2" - }, - "require-dev": { - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "eval", - "eval-file" - ] - }, - "autoload": { - "psr-4": { - "": "src/" - }, - "files": [ - "eval-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - } - ], - "description": "Executes arbitrary PHP code or files.", - "homepage": "https://github.com/wp-cli/eval-command", - "support": { - "issues": "https://github.com/wp-cli/eval-command/issues", - "source": "https://github.com/wp-cli/eval-command/tree/v2.0.8" - }, - "time": "2020-12-07T19:30:26+00:00" - }, - { - "name": "wp-cli/export-command", - "version": "v2.0.6", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/export-command.git", - "reference": "df2e1ff4fb7e969c54c57febccdc9d2de1e5f499" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/export-command/zipball/df2e1ff4fb7e969c54c57febccdc9d2de1e5f499", - "reference": "df2e1ff4fb7e969c54c57febccdc9d2de1e5f499", - "shasum": "" - }, - "require": { - "nb/oxymel": "~0.1.0", - "wp-cli/wp-cli": "^2" - }, - "require-dev": { - "wp-cli/db-command": "^1.3 || ^2", - "wp-cli/entity-command": "^1.3 || ^2", - "wp-cli/extension-command": "^1.2 || ^2", - "wp-cli/import-command": "^1 || ^2", - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "export" - ] - }, - "autoload": { - "psr-4": { - "": "src/" - }, - "files": [ - "export-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - } - ], - "description": "Exports WordPress content to a WXR file.", - "homepage": "https://github.com/wp-cli/export-command", - "support": { - "issues": "https://github.com/wp-cli/export-command/issues", - "source": "https://github.com/wp-cli/export-command/tree/v2.0.6" - }, - "time": "2021-01-14T12:16:33+00:00" - }, - { - "name": "wp-cli/extension-command", - "version": "v2.0.10", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/extension-command.git", - "reference": "2bc83433707fa4d2127f2ff48357ccbbee39052f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/extension-command/zipball/2bc83433707fa4d2127f2ff48357ccbbee39052f", - "reference": "2bc83433707fa4d2127f2ff48357ccbbee39052f", - "shasum": "" - }, - "require": { - "composer/semver": "^1.4 || ^2.0", - "wp-cli/wp-cli": "^2" - }, - "require-dev": { - "wp-cli/entity-command": "^1.3 || ^2", - "wp-cli/scaffold-command": "^1.2 || ^2", - "wp-cli/wp-cli-tests": "^2.1.6" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "plugin", - "plugin activate", - "plugin deactivate", - "plugin delete", - "plugin get", - "plugin install", - "plugin is-installed", - "plugin list", - "plugin path", - "plugin search", - "plugin status", - "plugin toggle", - "plugin uninstall", - "plugin update", - "theme", - "theme activate", - "theme delete", - "theme disable", - "theme enable", - "theme get", - "theme install", - "theme is-installed", - "theme list", - "theme mod", - "theme mod get", - "theme mod set", - "theme mod remove", - "theme path", - "theme search", - "theme status", - "theme update", - "theme mod list" - ] - }, - "autoload": { - "psr-4": { - "": "src/" - }, - "files": [ - "extension-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - }, - { - "name": "Alain Schlesser", - "email": "alain.schlesser@gmail.com", - "homepage": "https://www.alainschlesser.com" - } - ], - "description": "Manages plugins and themes, including installs, activations, and updates.", - "homepage": "https://github.com/wp-cli/extension-command", - "support": { - "issues": "https://github.com/wp-cli/extension-command/issues", - "source": "https://github.com/wp-cli/extension-command/tree/master" - }, - "time": "2020-07-05T08:07:53+00:00" - }, - { - "name": "wp-cli/i18n-command", - "version": "v2.2.6", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/i18n-command.git", - "reference": "a66da3f09f6a728832381012848c3074bf1635c8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/i18n-command/zipball/a66da3f09f6a728832381012848c3074bf1635c8", - "reference": "a66da3f09f6a728832381012848c3074bf1635c8", - "shasum": "" - }, - "require": { - "gettext/gettext": "^4.8", - "mck89/peast": "^1.8", - "wp-cli/wp-cli": "^2" - }, - "require-dev": { - "wp-cli/scaffold-command": "^1.2 || ^2", - "wp-cli/wp-cli-tests": "^2.1.3" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "i18n", - "i18n make-pot", - "i18n make-json" - ] - }, - "autoload": { - "psr-4": { - "WP_CLI\\I18n\\": "src/" - }, - "files": [ - "i18n-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Pascal Birchler", - "homepage": "https://pascalbirchler.com/" - } - ], - "description": "Provides internationalization tools for WordPress projects.", - "homepage": "https://github.com/wp-cli/i18n-command", - "support": { - "issues": "https://github.com/wp-cli/i18n-command/issues", - "source": "https://github.com/wp-cli/i18n-command/tree/v2.2.6" - }, - "time": "2020-12-07T19:28:27+00:00" - }, - { - "name": "wp-cli/import-command", - "version": "v2.0.4", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/import-command.git", - "reference": "c7438c1eeda5669531c52fc9223fcea5bda39cc8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/import-command/zipball/c7438c1eeda5669531c52fc9223fcea5bda39cc8", - "reference": "c7438c1eeda5669531c52fc9223fcea5bda39cc8", - "shasum": "" - }, - "require": { - "wp-cli/wp-cli": "^2" - }, - "require-dev": { - "wp-cli/entity-command": "^1.3 || ^2", - "wp-cli/export-command": "^1 || ^2", - "wp-cli/extension-command": "^1.2 || ^2", - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "import" - ] - }, - "autoload": { - "psr-4": { - "": "src/" - }, - "files": [ - "import-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - } - ], - "description": "Imports content from a given WXR file.", - "homepage": "https://github.com/wp-cli/import-command", - "support": { - "issues": "https://github.com/wp-cli/import-command/issues", - "source": "https://github.com/wp-cli/import-command/tree/v2.0.4" - }, - "time": "2020-12-07T19:28:45+00:00" - }, - { - "name": "wp-cli/language-command", - "version": "v2.0.8", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/language-command.git", - "reference": "c4f3cddd816e26df2b0e7e7753d786b54a2c95c8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/language-command/zipball/c4f3cddd816e26df2b0e7e7753d786b54a2c95c8", - "reference": "c4f3cddd816e26df2b0e7e7753d786b54a2c95c8", - "shasum": "" - }, - "require": { - "wp-cli/wp-cli": "^2" - }, - "require-dev": { - "wp-cli/db-command": "^1.3 || ^2", - "wp-cli/entity-command": "^1.3 || ^2", - "wp-cli/extension-command": "^1.2 || ^2", - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "language", - "language core", - "language core activate", - "language core is-installed", - "language core install", - "language core list", - "language core uninstall", - "language core update", - "language plugin", - "language plugin is-installed", - "language plugin install", - "language plugin list", - "language plugin uninstall", - "language plugin update", - "language theme", - "language theme is-installed", - "language theme install", - "language theme list", - "language theme uninstall", - "language theme update" - ] - }, - "autoload": { - "psr-4": { - "": "src/" - }, - "files": [ - "language-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - } - ], - "description": "Installs, activates, and manages language packs.", - "homepage": "https://github.com/wp-cli/language-command", - "support": { - "issues": "https://github.com/wp-cli/language-command/issues", - "source": "https://github.com/wp-cli/language-command/tree/v2.0.8" - }, - "time": "2020-12-07T19:29:09+00:00" - }, - { - "name": "wp-cli/maintenance-mode-command", - "version": "v2.0.4", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/maintenance-mode-command.git", - "reference": "1f4f09ad15696f65e713c4c73008f6550318b3bd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/maintenance-mode-command/zipball/1f4f09ad15696f65e713c4c73008f6550318b3bd", - "reference": "1f4f09ad15696f65e713c4c73008f6550318b3bd", - "shasum": "" - }, - "require": { - "wp-cli/wp-cli": "^2" - }, - "require-dev": { - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "maintenance-mode", - "maintenance-mode activate", - "maintenance-mode deactivate", - "maintenance-mode status", - "maintenance-mode is-active" - ] - }, - "autoload": { - "psr-4": { - "WP_CLI\\MaintenanceMode\\": "src/" - }, - "files": [ - "maintenance-mode-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Thrijith Thankachan", - "email": "thrijith13@gmail.com", - "homepage": "https://thrijith.com" - } - ], - "description": "Activates, deactivates or checks the status of the maintenance mode of a site.", - "homepage": "https://github.com/wp-cli/maintenance-mode-command", - "support": { - "issues": "https://github.com/wp-cli/maintenance-mode-command/issues", - "source": "https://github.com/wp-cli/maintenance-mode-command/tree/v2.0.4" - }, - "time": "2020-12-07T19:29:39+00:00" - }, - { - "name": "wp-cli/media-command", - "version": "v2.0.9", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/media-command.git", - "reference": "830e72a2cbd3eeec95a97df2c1c17d925d86790d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/media-command/zipball/830e72a2cbd3eeec95a97df2c1c17d925d86790d", - "reference": "830e72a2cbd3eeec95a97df2c1c17d925d86790d", - "shasum": "" - }, - "require": { - "wp-cli/wp-cli": "^2" - }, - "require-dev": { - "wp-cli/entity-command": "^1.3 || ^2", - "wp-cli/extension-command": "^2.0", - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "media", - "media import", - "media regenerate", - "media image-size" - ] - }, - "autoload": { - "psr-4": { - "": "src/" - }, - "files": [ - "media-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - } - ], - "description": "Imports files as attachments, regenerates thumbnails, or lists registered image sizes.", - "homepage": "https://github.com/wp-cli/media-command", - "support": { - "issues": "https://github.com/wp-cli/media-command/issues", - "source": "https://github.com/wp-cli/media-command/tree/master" - }, - "time": "2020-06-11T00:17:12+00:00" - }, - { - "name": "wp-cli/mustangostang-spyc", - "version": "0.6.3", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/spyc.git", - "reference": "6aa0b4da69ce9e9a2c8402dab8d43cf32c581cc7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/spyc/zipball/6aa0b4da69ce9e9a2c8402dab8d43cf32c581cc7", - "reference": "6aa0b4da69ce9e9a2c8402dab8d43cf32c581cc7", - "shasum": "" - }, - "require": { - "php": ">=5.3.1" - }, - "require-dev": { - "phpunit/phpunit": "4.3.*@dev" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.5.x-dev" - } - }, - "autoload": { - "psr-4": { - "Mustangostang\\": "src/" - }, - "files": [ - "includes/functions.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "mustangostang", - "email": "vlad.andersen@gmail.com" - } - ], - "description": "A simple YAML loader/dumper class for PHP (WP-CLI fork)", - "homepage": "https://github.com/mustangostang/spyc/", - "support": { - "source": "https://github.com/wp-cli/spyc/tree/autoload" - }, - "time": "2017-04-25T11:26:20+00:00" - }, - { - "name": "wp-cli/package-command", - "version": "v2.0.6", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/package-command.git", - "reference": "92a0d7f2f4b54ad2aeff2292baaa96ba8f93f37a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/package-command/zipball/92a0d7f2f4b54ad2aeff2292baaa96ba8f93f37a", - "reference": "92a0d7f2f4b54ad2aeff2292baaa96ba8f93f37a", - "shasum": "" - }, - "require": { - "composer/composer": ">=1.2.0 <1.7.0 || ^1.7.1", - "ext-json": "*", - "wp-cli/wp-cli": "^2.1" - }, - "require-dev": { - "wp-cli/scaffold-command": "^1 || ^2", - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "package", - "package browse", - "package install", - "package list", - "package update", - "package uninstall" - ] - }, - "autoload": { - "psr-4": { - "": "src/" - }, - "files": [ - "package-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - } - ], - "description": "Lists, installs, and removes WP-CLI packages.", - "homepage": "https://github.com/wp-cli/package-command", - "support": { - "issues": "https://github.com/wp-cli/package-command/issues", - "source": "https://github.com/wp-cli/package-command/tree/master" - }, - "time": "2020-01-28T12:55:09+00:00" - }, - { - "name": "wp-cli/php-cli-tools", - "version": "v0.11.12", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/php-cli-tools.git", - "reference": "e472e08489f7504d9e8c5c5a057e1419cd1b2b3e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/e472e08489f7504d9e8c5c5a057e1419cd1b2b3e", - "reference": "e472e08489f7504d9e8c5c5a057e1419cd1b2b3e", - "shasum": "" - }, - "require": { - "php": ">= 5.3.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "cli": "lib/" - }, - "files": [ - "lib/cli/cli.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@handbuilt.co", - "role": "Maintainer" - }, - { - "name": "James Logsdon", - "email": "jlogsdon@php.net", - "role": "Developer" - } - ], - "description": "Console utilities for PHP", - "homepage": "http://github.com/wp-cli/php-cli-tools", - "keywords": [ - "cli", - "console" - ], - "support": { - "issues": "https://github.com/wp-cli/php-cli-tools/issues", - "source": "https://github.com/wp-cli/php-cli-tools/tree/v0.11.12" - }, - "time": "2021-03-03T12:43:49+00:00" - }, - { - "name": "wp-cli/rewrite-command", - "version": "v2.0.6", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/rewrite-command.git", - "reference": "6b2c7d186b375976869b8d74f1a3bac1f98aca57" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/rewrite-command/zipball/6b2c7d186b375976869b8d74f1a3bac1f98aca57", - "reference": "6b2c7d186b375976869b8d74f1a3bac1f98aca57", - "shasum": "" - }, - "require": { - "wp-cli/wp-cli": "^2" - }, - "require-dev": { - "wp-cli/entity-command": "^1.3 || ^2", - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "rewrite", - "rewrite flush", - "rewrite list", - "rewrite structure" - ] - }, - "autoload": { - "psr-4": { - "": "src/" - }, - "files": [ - "rewrite-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - } - ], - "description": "Lists or flushes the site's rewrite rules, updates the permalink structure.", - "homepage": "https://github.com/wp-cli/rewrite-command", - "support": { - "issues": "https://github.com/wp-cli/rewrite-command/issues", - "source": "https://github.com/wp-cli/rewrite-command/tree/v2.0.6" - }, - "time": "2020-12-07T19:27:22+00:00" - }, - { - "name": "wp-cli/role-command", - "version": "v2.0.5", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/role-command.git", - "reference": "50e563a81f7462c4c5374abf6a1c0e88dfb01c9c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/role-command/zipball/50e563a81f7462c4c5374abf6a1c0e88dfb01c9c", - "reference": "50e563a81f7462c4c5374abf6a1c0e88dfb01c9c", - "shasum": "" - }, - "require": { - "wp-cli/wp-cli": "^2" - }, - "require-dev": { - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "role", - "role create", - "role delete", - "role exists", - "role list", - "role reset", - "cap", - "cap add", - "cap list", - "cap remove" - ] - }, - "autoload": { - "psr-4": { - "": "src/" - }, - "files": [ - "role-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - } - ], - "description": "Adds, removes, lists, and resets roles and capabilities.", - "homepage": "https://github.com/wp-cli/role-command", - "support": { - "issues": "https://github.com/wp-cli/role-command/issues", - "source": "https://github.com/wp-cli/role-command/tree/v2.0.5" - }, - "time": "2020-12-07T19:27:04+00:00" - }, - { - "name": "wp-cli/scaffold-command", - "version": "v2.0.8", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/scaffold-command.git", - "reference": "4814acbdf3d7af499530cc1ae1e82f3ed9f12674" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/scaffold-command/zipball/4814acbdf3d7af499530cc1ae1e82f3ed9f12674", - "reference": "4814acbdf3d7af499530cc1ae1e82f3ed9f12674", - "shasum": "" - }, - "require": { - "php": "^5.4 || ^7.0", - "wp-cli/wp-cli": "^2" - }, - "require-dev": { - "wp-cli/extension-command": "^1.2 || ^2", - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "scaffold", - "scaffold underscores", - "scaffold block", - "scaffold child-theme", - "scaffold plugin", - "scaffold plugin-tests", - "scaffold post-type", - "scaffold taxonomy", - "scaffold theme-tests" - ] - }, - "autoload": { - "psr-4": { - "": "src/" - }, - "files": [ - "scaffold-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - } - ], - "description": "Generates code for post types, taxonomies, blocks, plugins, child themes, etc.", - "homepage": "https://github.com/wp-cli/scaffold-command", - "support": { - "issues": "https://github.com/wp-cli/scaffold-command/issues", - "source": "https://github.com/wp-cli/scaffold-command/tree/master" - }, - "time": "2019-11-25T13:26:31+00:00" - }, - { - "name": "wp-cli/search-replace-command", - "version": "v2.0.7", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/search-replace-command.git", - "reference": "1104e4fb7dd83e85dedb8a98ed8f0ac30639694b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/search-replace-command/zipball/1104e4fb7dd83e85dedb8a98ed8f0ac30639694b", - "reference": "1104e4fb7dd83e85dedb8a98ed8f0ac30639694b", - "shasum": "" - }, - "require": { - "wp-cli/wp-cli": "^2" - }, - "require-dev": { - "wp-cli/db-command": "^1.3 || ^2", - "wp-cli/entity-command": "^1.3 || ^2", - "wp-cli/extension-command": "^1.2 || ^2", - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "search-replace" - ] - }, - "autoload": { - "psr-4": { - "": "src/" - }, - "files": [ - "search-replace-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - } - ], - "description": "Searches/replaces strings in the database.", - "homepage": "https://github.com/wp-cli/search-replace-command", - "support": { - "issues": "https://github.com/wp-cli/search-replace-command/issues", - "source": "https://github.com/wp-cli/search-replace-command/tree/v2.0.7" - }, - "time": "2020-06-10T13:24:39+00:00" - }, - { - "name": "wp-cli/server-command", - "version": "v2.0.6", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/server-command.git", - "reference": "be65465bda181209c95011f15d4575809d039ea9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/server-command/zipball/be65465bda181209c95011f15d4575809d039ea9", - "reference": "be65465bda181209c95011f15d4575809d039ea9", - "shasum": "" - }, - "require": { - "wp-cli/wp-cli": "^2" - }, - "require-dev": { - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "server" - ] - }, - "autoload": { - "psr-4": { - "": "src/" - }, - "files": [ - "server-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - } - ], - "description": "Launches PHP's built-in web server for a specific WordPress installation.", - "homepage": "https://github.com/wp-cli/server-command", - "support": { - "issues": "https://github.com/wp-cli/server-command/issues", - "source": "https://github.com/wp-cli/server-command/tree/v2.0.6" - }, - "time": "2020-12-07T19:26:47+00:00" - }, - { - "name": "wp-cli/shell-command", - "version": "v2.0.7", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/shell-command.git", - "reference": "76088e1ff69855d89454aed886d27c3f62b12c2c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/shell-command/zipball/76088e1ff69855d89454aed886d27c3f62b12c2c", - "reference": "76088e1ff69855d89454aed886d27c3f62b12c2c", - "shasum": "" - }, - "require": { - "wp-cli/wp-cli": "^2" - }, - "require-dev": { - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "shell" - ] - }, - "autoload": { - "psr-4": { - "": "src/", - "WP_CLI\\": "src/WP_CLI" - }, - "files": [ - "shell-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - } - ], - "description": "Opens an interactive PHP console for running and testing PHP code.", - "homepage": "https://github.com/wp-cli/shell-command", - "support": { - "issues": "https://github.com/wp-cli/shell-command/issues", - "source": "https://github.com/wp-cli/shell-command/tree/v2.0.7" - }, - "time": "2020-12-07T19:26:30+00:00" - }, - { - "name": "wp-cli/super-admin-command", - "version": "v2.0.5", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/super-admin-command.git", - "reference": "23b9a4e6f27d5effe5cfd67db2329e0d58dbb53f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/super-admin-command/zipball/23b9a4e6f27d5effe5cfd67db2329e0d58dbb53f", - "reference": "23b9a4e6f27d5effe5cfd67db2329e0d58dbb53f", - "shasum": "" - }, - "require": { - "wp-cli/wp-cli": "^2" - }, - "require-dev": { - "wp-cli/entity-command": "^1.3 || ^2", - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "super-admin", - "super-admin add", - "super-admin list", - "super-admin remove" - ] - }, - "autoload": { - "psr-4": { - "": "src/" - }, - "files": [ - "super-admin-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - } - ], - "description": "Lists, adds, or removes super admin users on a multisite installation.", - "homepage": "https://github.com/wp-cli/super-admin-command", - "support": { - "issues": "https://github.com/wp-cli/super-admin-command/issues", - "source": "https://github.com/wp-cli/super-admin-command/tree/v2.0.5" - }, - "time": "2020-12-07T19:26:13+00:00" - }, - { - "name": "wp-cli/widget-command", - "version": "v2.1.2", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/widget-command.git", - "reference": "0c73470adbc73b45f4d371e4869672eacca104b3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/widget-command/zipball/0c73470adbc73b45f4d371e4869672eacca104b3", - "reference": "0c73470adbc73b45f4d371e4869672eacca104b3", - "shasum": "" - }, - "require": { - "wp-cli/wp-cli": "^2.4" - }, - "require-dev": { - "wp-cli/extension-command": "^1.2 || ^2", - "wp-cli/wp-cli-tests": "^2.1" - }, - "type": "wp-cli-package", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - }, - "bundled": true, - "commands": [ - "widget", - "widget add", - "widget deactivate", - "widget delete", - "widget list", - "widget move", - "widget reset", - "widget update", - "sidebar", - "sidebar list" - ] - }, - "autoload": { - "psr-4": { - "": "src/" - }, - "files": [ - "widget-command.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Bachhuber", - "email": "daniel@runcommand.io", - "homepage": "https://runcommand.io" - } - ], - "description": "Adds, moves, and removes widgets; lists sidebars.", - "homepage": "https://github.com/wp-cli/widget-command", - "support": { - "issues": "https://github.com/wp-cli/widget-command/issues", - "source": "https://github.com/wp-cli/widget-command/tree/v2.1.2" - }, - "time": "2020-12-07T19:25:02+00:00" - }, - { - "name": "wp-cli/wp-cli", - "version": "v2.4.1", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/wp-cli.git", - "reference": "ceb18598e79befa9b2a37a51efbb34910628988b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/wp-cli/zipball/ceb18598e79befa9b2a37a51efbb34910628988b", - "reference": "ceb18598e79befa9b2a37a51efbb34910628988b", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "mustache/mustache": "~2.13", - "php": "^5.4 || ^7.0", - "rmccue/requests": "~1.6", - "symfony/finder": ">2.7", - "wp-cli/mustangostang-spyc": "^0.6.3", - "wp-cli/php-cli-tools": "~0.11.2" - }, - "require-dev": { - "roave/security-advisories": "dev-master", - "wp-cli/db-command": "^1.3 || ^2", - "wp-cli/entity-command": "^1.2 || ^2", - "wp-cli/extension-command": "^1.1 || ^2", - "wp-cli/package-command": "^1 || ^2", - "wp-cli/wp-cli-tests": "^2.1" - }, - "suggest": { - "ext-readline": "Include for a better --prompt implementation", - "ext-zip": "Needed to support extraction of ZIP archives when doing downloads or updates" - }, - "bin": [ - "bin/wp", - "bin/wp.bat" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.4.x-dev" - } - }, - "autoload": { - "psr-0": { - "WP_CLI": "php" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "WP-CLI framework", - "homepage": "https://wp-cli.org", - "keywords": [ - "cli", - "wordpress" - ], - "support": { - "docs": "https://make.wordpress.org/cli/handbook/", - "issues": "https://github.com/wp-cli/wp-cli/issues", - "source": "https://github.com/wp-cli/wp-cli" - }, - "time": "2020-02-18T08:15:37+00:00" - }, - { - "name": "wp-cli/wp-cli-bundle", - "version": "v2.4.0", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/wp-cli-bundle.git", - "reference": "713bc75b2f88550920dedc4f2ad3e1daf9f76326" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/wp-cli-bundle/zipball/713bc75b2f88550920dedc4f2ad3e1daf9f76326", - "reference": "713bc75b2f88550920dedc4f2ad3e1daf9f76326", - "shasum": "" - }, - "require": { - "cweagans/composer-patches": "^1.6", - "php": ">=5.4", - "wp-cli/cache-command": "^2", - "wp-cli/checksum-command": "^2", - "wp-cli/config-command": "^2", - "wp-cli/core-command": "^2", - "wp-cli/cron-command": "^2", - "wp-cli/db-command": "^2", - "wp-cli/embed-command": "^2", - "wp-cli/entity-command": "^2", - "wp-cli/eval-command": "^2", - "wp-cli/export-command": "^2", - "wp-cli/extension-command": "^2", - "wp-cli/i18n-command": "^2", - "wp-cli/import-command": "^2", - "wp-cli/language-command": "^2", - "wp-cli/maintenance-mode-command": "^2", - "wp-cli/media-command": "^2", - "wp-cli/package-command": "^2", - "wp-cli/rewrite-command": "^2", - "wp-cli/role-command": "^2", - "wp-cli/scaffold-command": "^2", - "wp-cli/search-replace-command": "^2", - "wp-cli/server-command": "^2", - "wp-cli/shell-command": "^2", - "wp-cli/super-admin-command": "^2", - "wp-cli/widget-command": "^2", - "wp-cli/wp-cli": "^2.4" - }, - "require-dev": { - "roave/security-advisories": "dev-master", - "wp-cli/wp-cli-tests": "^2.1" - }, - "suggest": { - "psy/psysh": "Enhanced `wp shell` functionality" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1.x-dev" - }, - "enable-patching": true - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "WP-CLI bundle package with default commands.", - "homepage": "https://wp-cli.org", - "keywords": [ - "cli", - "wordpress" - ], - "support": { - "docs": "https://make.wordpress.org/cli/handbook/", - "issues": "https://github.com/wp-cli/wp-cli-bundle/issues", - "source": "https://github.com/wp-cli/wp-cli-bundle" - }, - "time": "2019-11-12T17:43:58+00:00" - }, - { - "name": "wp-cli/wp-config-transformer", - "version": "v1.2.8", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/wp-config-transformer.git", - "reference": "0bb2b9162c38ca72370380aea11dc06e431e13a5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/wp-config-transformer/zipball/0bb2b9162c38ca72370380aea11dc06e431e13a5", - "reference": "0bb2b9162c38ca72370380aea11dc06e431e13a5", - "shasum": "" - }, - "require": { - "php": ">=5.3.29" - }, - "require-dev": { - "composer/composer": ">=1.5.6 <1.7.0 || ^1.7.1 || ^2.0.0", - "phpunit/phpunit": "^6.5.5 || ^7.0.0", - "wp-coding-standards/wpcs": "^0.14.0 || ^1.0.0 || ^2.0.0" - }, - "type": "library", - "autoload": { - "files": [ - "src/WPConfigTransformer.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Frankie Jarrett", - "email": "fjarrett@gmail.com" - } - ], - "description": "Programmatically edit a wp-config.php file.", - "support": { - "issues": "https://github.com/wp-cli/wp-config-transformer/issues", - "source": "https://github.com/wp-cli/wp-config-transformer/tree/v1.2.8" - }, - "time": "2020-11-12T08:08:10+00:00" - }, - { - "name": "wp-coding-standards/wpcs", - "version": "2.3.0", - "source": { - "type": "git", - "url": "https://github.com/WordPress/WordPress-Coding-Standards.git", - "reference": "7da1894633f168fe244afc6de00d141f27517b62" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/7da1894633f168fe244afc6de00d141f27517b62", - "reference": "7da1894633f168fe244afc6de00d141f27517b62", - "shasum": "" - }, - "require": { - "php": ">=5.4", - "squizlabs/php_codesniffer": "^3.3.1" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || ^0.6", - "phpcompatibility/php-compatibility": "^9.0", - "phpcsstandards/phpcsdevtools": "^1.0", - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.6 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically." - }, - "type": "phpcodesniffer-standard", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Contributors", - "homepage": "https://github.com/WordPress/WordPress-Coding-Standards/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions", - "keywords": [ - "phpcs", - "standards", - "wordpress" - ], - "support": { - "issues": "https://github.com/WordPress/WordPress-Coding-Standards/issues", - "source": "https://github.com/WordPress/WordPress-Coding-Standards", - "wiki": "https://github.com/WordPress/WordPress-Coding-Standards/wiki" - }, - "time": "2020-05-13T23:57:56+00:00" - }, - { - "name": "zendframework/zend-code", - "version": "3.4.1", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-code.git", - "reference": "268040548f92c2bfcba164421c1add2ba43abaaa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-code/zipball/268040548f92c2bfcba164421c1add2ba43abaaa", - "reference": "268040548f92c2bfcba164421c1add2ba43abaaa", - "shasum": "" - }, - "require": { - "php": "^7.1", - "zendframework/zend-eventmanager": "^2.6 || ^3.0" - }, - "conflict": { - "phpspec/prophecy": "<1.9.0" - }, - "require-dev": { - "doctrine/annotations": "^1.7", - "ext-phar": "*", - "phpunit/phpunit": "^7.5.16 || ^8.4", - "zendframework/zend-coding-standard": "^1.0", - "zendframework/zend-stdlib": "^2.7 || ^3.0" - }, - "suggest": { - "doctrine/annotations": "Doctrine\\Common\\Annotations >=1.0 for annotation features", - "zendframework/zend-stdlib": "Zend\\Stdlib component" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4.x-dev", - "dev-develop": "3.5.x-dev", - "dev-dev-4.0": "4.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Code\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Extensions to the PHP Reflection API, static code scanning, and code generation", - "keywords": [ - "ZendFramework", - "code", - "zf" - ], - "support": { - "chat": "https://zendframework-slack.herokuapp.com", - "docs": "https://docs.zendframework.com/zend-code/", - "forum": "https://discourse.zendframework.com/c/questions/components", - "issues": "https://github.com/zendframework/zend-code/issues", - "rss": "https://github.com/zendframework/zend-code/releases.atom", - "source": "https://github.com/zendframework/zend-code" - }, - "abandoned": "laminas/laminas-code", - "time": "2019-12-10T19:21:15+00:00" - }, - { - "name": "zendframework/zend-eventmanager", - "version": "3.2.1", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-eventmanager.git", - "reference": "a5e2583a211f73604691586b8406ff7296a946dd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/a5e2583a211f73604691586b8406ff7296a946dd", - "reference": "a5e2583a211f73604691586b8406ff7296a946dd", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "require-dev": { - "athletic/athletic": "^0.1", - "container-interop/container-interop": "^1.1.0", - "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2", - "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-stdlib": "^2.7.3 || ^3.0" - }, - "suggest": { - "container-interop/container-interop": "^1.1.0, to use the lazy listeners feature", - "zendframework/zend-stdlib": "^2.7.3 || ^3.0, to use the FilterChain feature" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.2-dev", - "dev-develop": "3.3-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\EventManager\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Trigger and listen to events within a PHP application", - "homepage": "https://github.com/zendframework/zend-eventmanager", - "keywords": [ - "event", - "eventmanager", - "events", - "zf2" - ], - "support": { - "issues": "https://github.com/zendframework/zend-eventmanager/issues", - "source": "https://github.com/zendframework/zend-eventmanager/tree/master" - }, - "abandoned": "laminas/laminas-eventmanager", - "time": "2018-04-25T15:33:34+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": { - "wp-cli/wp-cli-bundle": 0 - }, - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.0.0" -} diff --git a/css/dashboard.css b/css/dashboard.css deleted file mode 100644 index 91a8d62e..00000000 --- a/css/dashboard.css +++ /dev/null @@ -1,19 +0,0 @@ -#ab_chart { - color: #a7aaad; - height: 140px; - margin: 0 -4px; - text-align: center; -} - -#ab_chart_data { - display: none; -} - -#ab_widget .inside { - height: 1%; - margin: 0; - padding-bottom: 0; - overflow: hidden; - position: relative; - white-space: nowrap; -} diff --git a/css/styles.css b/css/styles.css deleted file mode 100644 index a6177e82..00000000 --- a/css/styles.css +++ /dev/null @@ -1,265 +0,0 @@ -/* @group General */ - -.ab-main *, -.ab-main *::after, -.ab-main *::before { - border: 0; - margin: 0; - padding: 0; - outline: 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -/* @end group */ - -/* @group Columns */ - -.ab-wrap { - margin: 0 0 0 -10px; - padding: 20px 0 0 0; - text-rendering: optimizeLegibility; /* stylelint-disable-line value-keyword-case */ -} - -.ab-column { - float: left; - margin: 0 0 0 10px; - position: relative; -} - -/* @end group */ - -/* @group Headlines + Icons */ - -.ab-column h3 { - margin: 0; - font-size: 18px; - font-weight: normal; - line-height: 20px; - color: #1d2327; -} - -.ab-column h3.icon::before { - font: normal 30px/30px Dashicons; - top: 4px; - right: 20px; - speak: none; - width: 1em; - color: #8c8f94; - position: absolute; - text-align: center; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.ab-column.ab-arrow h3.icon::before { - content: "\f536"; -} - -.ab-column.ab-join h3.icon::before { - content: "\f108"; -} - -.ab-column.ab-diff h3.icon::before { - content: "\f237"; -} - -.ab-column h6 { - clear: both; - color: #3c434a; - margin: 0 0 20px; - font-weight: normal; - font-size: 13px; -} - -/* @end group */ - -/* @group Form */ - -.ab-column input[type="text"], -.ab-column input[type="number"], -.ab-column select { - font-size: 13px; - text-align: center; - background: #f6f7f7; -} - -.ab-column input[type="number"] { - padding: 0; -} - -.ab-column select[multiple] { - width: 175px; - min-height: 60px; -} - -.ab-column select[multiple][name="ab_ignore_reasons[]"] { - width: auto; -} - -.ab-column input.ab-mini-field { - width: 40px; -} - -.ab-column .ab-medium-field { - width: 100%; - max-width: 285px; -} - -.ab-column input[type="text"] + label, -.ab-column select + label { - color: #8c8f94; - margin: 0 0 0 7px; - display: inline-block; - text-transform: uppercase; -} - -/* @end group */ - -/* @group Column contents */ - -.ab-column > ul { - padding: 0 20px 0 0; -} - -.ab-column:last-of-type > ul { - border: 0; -} - -.ab-column > ul > li { - width: 330px; - margin: 0 0 36px; - padding: 10px 0 12px 12px; - position: relative; - background: #fff; -} - -.ab-column > ul > li a { - text-decoration: underline; -} - -.ab-column > ul > li a:hover { - border-color: inherit; -} - -.ab-column > ul > li label { - cursor: default; - display: inline-block; - font-size: 14px; - max-width: 286px; - color: #1d2327; -} - -.ab-column > ul > li label span { - color: #3c434a; - display: block; - font-size: 13px; - line-height: 16px; - margin-top: 5px; -} - -/* @end group */ - -/* @group Separator */ - -.ab-column > ul > li::after, -.ab-column > ul > li::before { - width: 0; - content: ""; - position: absolute; -} - -.ab-column.ab-arrow > ul > li::before, -.ab-column.ab-arrow > ul > li::after { - left: 157px; - border-width: 10px 10px 0; - border-style: solid; -} - -.ab-column.ab-arrow > ul > li::before { - bottom: -24px; - border-color: #fff transparent; -} - -.ab-column.ab-arrow > ul > li::after { - bottom: -22px; - border-color: #f0f0f1 transparent; -} - -.ab-column.ab-join > ul > li::before { - left: 171px; - bottom: -27px; - height: 18px; - border-right: 2px solid #fff; -} - -.ab-column.ab-diff > ul > li::before { - left: 162px; - bottom: -19px; - width: 18px; - height: 0; - border-bottom: 2px solid #fff; -} - -/* @end group */ - -/* @group Submit & Service */ - -.ab-column--submit-service { - width: 342px; - margin-top: 20px; - padding-right: 20px; -} - -.ab-column--submit-service p { - padding: 5px 0; - margin: 0; - text-align: center; - width: 100%; -} - -.ab-column--submit-service p:first-of-type { - border-top: 1px solid #dcdcde; -} - -.ab-column--submit-service p:last-of-type { - border-bottom: 1px solid #dcdcde; -} - -.ab-column--submit-service .button { - width: 100%; - margin: 35px 0 10px; -} - -/* @end group */ - -/* @group 2nd level */ - -.ab-column > ul > li:last-of-type::after, -.ab-column > ul > li:last-of-type::before { - display: none; -} - -.ab-column > ul > li > ul { - margin: 10px 10px 0 26px; - display: none; -} - -.ab-column > ul > li > ul li { - padding: 2px 0; -} - -.ab-column > ul > li > ul label { - margin: 0 0 0 7px; -} - -.ab-column > ul > li > ul label[for="ab_ignore_reasons"] { - margin: 0 0 5px 0; -} - -.ab-column > ul > li > input[type="checkbox"]:checked ~ ul { - display: block; -} - -/* @end group */ diff --git a/docker-compose.yml b/docker-compose.yml index 6194bc39..0de5d100 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,11 +16,14 @@ services: links: - db ports: - - "8088:80" + - "80:80" volumes: - .:/var/www/html/wp-content/plugins/antispam-bee + - ../wp:/var/www/html restart: always environment: WORDPRESS_DB_HOST: db:3306 + WORDPRESS_DB_DATABASE: wordpress + WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress WORDPRESS_DEBUG: 1 diff --git a/docs/adding-rules.md b/docs/adding-rules.md new file mode 100644 index 00000000..22717617 --- /dev/null +++ b/docs/adding-rules.md @@ -0,0 +1,5 @@ +# Adding rules + +ASB 3 makes it possible for third-parties to add custom rules. + +Each Rule is a class that extends the `ControllableBase` (if your rule has options, like for disabling/enabling) or `Base` (if your rule works invisible in the background) class and implements the `SpamReason` interface. diff --git a/docs/program-flow.md b/docs/program-flow.md new file mode 100644 index 00000000..9a782331 --- /dev/null +++ b/docs/program-flow.md @@ -0,0 +1,45 @@ +# Program flow + +1. Entry point for the plugin is, of course, the `antispam_bee.php`. There we check a few requirements like PHP version and PHP extensions. If everything looks good, we proceed. +2. Meeting all requirements in `antispam_bee.php`, the `src/load.php` file is included. Besides registering hooks for doing things on activation/deactivation/uninstall/update, this is the place where the modules of ASB are loaded. + In the `init` method we loop over a class array, and call the `init` method on all classes if it exists. + The `init` methods in the module classes contain `add_action` and `add_filter` calls to hook into WordPress and do their thing. What happens next depends on the kind of request that is done. + 1. **A reaction (comment/linkback/…) coming in:**\ + Handling comment and linkback requests happens in the classes `\AntispamBee\Handlers\Comment` and `\AntispamBee\Handlers\Linkback`. If you look in the `src/load.php` you can see both as part of the modules array. + The classes extend the abstract `\AntispamBee\Handlers\Reaction` class that comes with a basic `init` method, being good enough for the linkback reactions. + In the `process` methods of the classes you can see the process of applying rules to a reaction and, if the rules come to the result it is spam, how the post processors are applied. + 1. To apply all active comment rules to a reaction, all you have to do is: + ```php + $rules = new \AntispamBee\Handlers\Rules( 'comment' ); + $is_spam = $rules->apply( $reaction ); + ``` + Where `$reaction` is an array of comment data. The `apply` method returns a boolean indicating if the reaction is spam or not. + 2. If it is spam, you can apply the post processors (code snippet from the `\AntispamBee\Handlers\Reaction::process` method): + ```php + if ( $is_spam ) { + $item = PostProcessors::apply( 'comment', $reaction, $rules->get_spam_reasons() ); + if ( ! isset( $item['asb_marked_as_delete'] ) ) { + add_filter( + 'pre_comment_approved', + function () { + return 'spam'; + } + ); + + return $reaction; + } + + status_header( 403 ); + die( 'Spam deleted.' ); + } + ``` + The `apply` method of `\AntispamBee\Handlers\PostProcessors` returns the Item again with added data: + * In `$item['asb_reasons']` the reasons are stored that are provided as the third parameter to the `apply` method. + * `$item['reaction_type']` holds the content type that is passed as the first parameter to the `apply` method. + * If `$item['asb_marked_as_delete']` is set, one or more post processors were applied that indicate that the comment should not be stored. + 2. **The user visiting the dashboard:**\ + The `\AntispamBee\Admin\DashboardWidgets` class handles displaying the spam counts in the dashboard widget, if it is enabled. + 3. **Settings page**\ + The `\AntispamBee\Admin\SettingsPage` class adds the settings page. + 4. **Spam reason in comment column**\ + If the option to save the spam reason is enabled for at least one reaction type, the `\AntispamBee\Admin\CommentsColumns` class handles that. diff --git a/docs/project-structure.md b/docs/project-structure.md new file mode 100644 index 00000000..6845081e --- /dev/null +++ b/docs/project-structure.md @@ -0,0 +1,16 @@ +# Project Structure + +Compared to version 2 of Antispam Bee, the project structure has changed a lot. We now do not have one large file that contains all spam detection, but various classes doing that. + +The most important part of ASB 3 are rules and post processors. Both, rules and post processors, can be controllable via the options page or work invisible in the background without registering a control. + +- `src` – this directory contains all of our PHP files except the main plugin file. +- `src/load.php` – registers hooks for activation/deactivation/uninstall and, more important, loads the ASB modules. +- `src/Admin` – contains the files that are responsible for displaying things in the backend, like the spam counter in the dashboard widget or the settings page. +- `src/Crons` – cron-related files. +- `src/GeneralOptions` – contains the classes for the general options, like showing statistics in the Dashboard. +- `src/Handlers` – classes handling things, like incoming comments or linkbacks, and applying rules and post processors to a reaction. +- `src/Helpers` – helpers for various tasks. +- `src/Interfaces` – a few interfaces. +- `src/PostProcessors` – the ASB core post processors. +- `src/Rules` – the ASB core anti-spam rules. diff --git a/inc/columns.class.php b/inc/columns.class.php deleted file mode 100644 index f0802fa3..00000000 --- a/inc/columns.class.php +++ /dev/null @@ -1,160 +0,0 @@ - esc_html__( 'Spam Reason', 'antispam-bee' ), - ) - ); - } - - /** - * Display plugin column values on comments screen - * - * @since 2.6.0 - * @change 2.6.0 - * - * @param string $column Currently selected column. - * @param integer $comment_id Comment ID. - */ - public static function print_plugin_column( $column, $comment_id ) { - if ( 'antispam_bee_reason' !== $column ) { - return; - } - - $spam_reason = get_comment_meta( $comment_id, $column, true ); - $spam_reasons = Antispam_Bee::$defaults['reasons']; - - if ( empty( $spam_reason ) || empty( $spam_reasons[ $spam_reason ] ) ) { - return; - } - - echo esc_html( $spam_reasons[ $spam_reason ] ); - } - - /** - * Register plugin sortable columns on comments screen - * - * @since 2.6.3 - * @change 2.6.3 - * - * @param array $columns Registered columns. - * @return array $columns Columns with AB field. - */ - public static function register_sortable_columns( $columns ) { - $columns['antispam_bee_reason'] = 'antispam_bee_reason'; - - return $columns; - } - - // phpcs:disable WordPress.VIP.SlowDBQuery.slow_db_query_meta_key - // phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification - /** - * Adjust orderby query - * - * @since 2.6.3 - * @change 2.6.3 - * - * @param \WP_Comment_Query $query Current WordPress query. - */ - public static function set_orderby_query( $query ) { - $orderby = isset( $_GET['orderby'] ) ? sanitize_text_field( wp_unslash( $_GET['orderby'] ) ) : ''; - - if ( empty( $orderby ) || 'antispam_bee_reason' !== $orderby ) { - return; - } - - $query->query_vars['meta_key'] = 'antispam_bee_reason'; - $query->query_vars['orderby'] = 'meta_value'; - } - // phpcs:enable WordPress.VIP.SlowDBQuery.slow_db_query_meta_key - // phpcs:enable WordPress.CSRF.NonceVerification.NoNonceVerification - - //phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification - /** - * Filter comments by the spam reason - * - * @global \wpdb $wpdb - */ - public static function filter_columns() { - global $wpdb; - ?> - - - query_vars['meta_key'] = 'antispam_bee_reason'; - $query->query_vars['meta_value'] = $spam_reason; - } - //phpcs:enable WordPress.VIP.SlowDBQuery.slow_db_query_meta_key - //phpcs:enable WordPress.VIP.SlowDBQuery.slow_db_query_meta_value - //phpcs:enable WordPress.CSRF.NonceVerification.NoNonceVerification - - /** - * Print CSS for the plugin column - * - * @since 2.6.1 - * @change 2.6.1 - */ - public static function print_column_styles() { - ?> - - (int) ( ! empty( $_POST['ab_flag_spam'] ) ), - 'email_notify' => (int) ( ! empty( $_POST['ab_email_notify'] ) ), - 'cronjob_enable' => (int) ( ! empty( $_POST['ab_cronjob_enable'] ) ), - 'cronjob_interval' => (int) self::get_key( $_POST, 'ab_cronjob_interval' ), - - 'no_notice' => (int) ( ! empty( $_POST['ab_no_notice'] ) ), - - 'dashboard_count' => (int) ( ! empty( $_POST['ab_dashboard_count'] ) ), - 'dashboard_chart' => (int) ( ! empty( $_POST['ab_dashboard_chart'] ) ), - 'regexp_check' => (int) ( ! empty( $_POST['ab_regexp_check'] ) ), - 'spam_ip' => (int) ( ! empty( $_POST['ab_spam_ip'] ) ), - 'already_commented' => (int) ( ! empty( $_POST['ab_already_commented'] ) ), - 'time_check' => (int) ( ! empty( $_POST['ab_time_check'] ) ), - - 'ignore_pings' => (int) ( ! empty( $_POST['ab_ignore_pings'] ) ), - 'ignore_filter' => (int) ( ! empty( $_POST['ab_ignore_filter'] ) ), - 'ignore_type' => (int) self::get_key( $_POST, 'ab_ignore_type' ), - - 'reasons_enable' => (int) ( ! empty( $_POST['ab_reasons_enable'] ) ), - 'ignore_reasons' => (array) self::get_key( $_POST, 'ab_ignore_reasons' ), - - 'bbcode_check' => (int) ( ! empty( $_POST['ab_bbcode_check'] ) ), - 'gravatar_check' => (int) ( ! empty( $_POST['ab_gravatar_check'] ) ), - 'country_code' => (int) ( ! empty( $_POST['ab_country_code'] ) ), - 'country_denied' => sanitize_text_field( wp_unslash( self::get_key( $_POST, 'ab_country_denied' ) ) ), - 'country_allowed' => sanitize_text_field( wp_unslash( self::get_key( $_POST, 'ab_country_allowed' ) ) ), - - 'translate_api' => (int) ( ! empty( $_POST['ab_translate_api'] ) ), - 'translate_lang' => $selected_languages, - - 'delete_data_on_uninstall' => (int) ( ! empty( $_POST['delete_data_on_uninstall'] ) ), - - 'use_output_buffer' => (int) ( ! empty( $_POST['ab_use_output_buffer'] ) ), - - ); - - foreach ( $options['ignore_reasons'] as $key => $val ) { - if ( ! isset( self::$defaults['reasons'][ $val ] ) ) { - unset( $options['ignore_reasons'][ $key ] ); - } - } - - if ( empty( $options['cronjob_interval'] ) ) { - $options['cronjob_enable'] = 0; - } - - if ( empty( $options['translate_lang'] ) ) { - $options['translate_api'] = 0; - } - - if ( empty( $options['reasons_enable'] ) ) { - $options['ignore_reasons'] = array(); - } - - if ( ! empty( $options['country_denied'] ) ) { - $options['country_denied'] = preg_replace( - '/[^A-Z ,;]/', - '', - strtoupper( $options['country_denied'] ) - ); - } - - if ( ! empty( $options['country_allowed'] ) ) { - $options['country_allowed'] = preg_replace( - '/[^A-Z ,;]/', - '', - strtoupper( $options['country_allowed'] ) - ); - } - - if ( empty( $options['country_denied'] ) && empty( $options['country_allowed'] ) ) { - $options['country_code'] = 0; - } - - if ( $options['cronjob_enable'] && ! self::get_option( 'cronjob_enable' ) ) { - self::init_scheduled_hook(); - } elseif ( ! $options['cronjob_enable'] && self::get_option( 'cronjob_enable' ) ) { - self::clear_scheduled_hook(); - } - - self::update_options( $options ); - - wp_safe_redirect( - add_query_arg( - array( - 'updated' => 'true', - ), - wp_get_referer() - ) - ); - - die(); - } - - /** - * Generation of a selectbox - * - * @since 2.4.5 - * - * @param string $name Name of the Selectbox. - * @param array $data Array with values. - * @param string $selected Selected value. - * @return string $html Generated HTML. - */ - private static function _build_select( $name, $data, $selected ) { - $html = ''; - - return $html; - } - - - /** - * Display the GUI - * - * @since 0.1 - * @since 2.7.0 - * @since 2.10.0 Change documentation links, change country option name, and add option to parse complete markup for comment forms - */ - public static function options_page() { ?> -
-

- Antispam Bee -

- -
- - - - - -
- -
-

- -

-
- -
- -
    -
  • - /> - -
  • - - -
  • - /> - -
  • - - -
  • - /> - -
  • - -
  • - /> - -
  • - - -
  • - /> - -
  • - -
  • - /> - -
  • - -
  • - /> - - -
      - ', - esc_url( - __( 'https://www.iso.org/iso/country_names_and_code_elements', 'antispam-bee' ), - 'https' - ) - ); - ?> -
    • - - -
    • -
    • - - -
    • -
    -
  • - -
  • - /> - - -
      -
    • - - -
    • -
    -
  • -
-
- -
-

- -

-
- -
- -
    -
  • - /> - -
  • - -
  • - /> - -
  • - -
  • - /> - -
  • - -
  • - /> - -
  • - -
  • - /> - -
  • - -
  • - /> - - -
      -
    • - - -
    • -
    -
  • - -
  • - /> - -
  • -
- -
- - -
-

- -

-
- -
- -
    -
  • - /> - -
  • - -
  • - /> - -
  • - -
  • - /> - -
  • - -
  • - /> - -
  • -
-
- -
-

- -

-

- -

-

- -

-

- -

- - -
-
-
-
- __( 'German', 'antispam-bee' ), - 'en' => __( 'English', 'antispam-bee' ), - 'fr' => __( 'French', 'antispam-bee' ), - 'it' => __( 'Italian', 'antispam-bee' ), - 'es' => __( 'Spanish', 'antispam-bee' ), - ); - - /** - * Filter the possible languages for the language spam test - * - * @since 2.7.1 - * @param (array) $lang The languages - * @return (array) - */ - return apply_filters( 'ab_get_allowed_translate_languages', $lang ); - } -} diff --git a/js/dashboard.js b/js/dashboard.js deleted file mode 100644 index 94d1783e..00000000 --- a/js/dashboard.js +++ /dev/null @@ -1,112 +0,0 @@ -( function() { - // Grab the data - var labels = [], - data = []; - jQuery( '#ab_chart_data tfoot th' ).each( function() { - labels.push( jQuery( this ).text() ); - } ); - jQuery( '#ab_chart_data tbody td' ).each( function() { - data.push( jQuery( this ).text() ); - } ); - - // Draw - var width = jQuery( '#ab_chart' ).parent().width() + 8, - height = 140, - leftgutter = 0, - bottomgutter = 22, - topgutter = 22, - color = '#135e96', - r = Raphael( 'ab_chart', width, height ), - txt = { font: 'bold 12px "Open Sans", sans-serif', fill: '#1d2327' }, - X = ( width - leftgutter * 2 ) / labels.length, - max = Math.max.apply( Math, data ), - Y = ( height - bottomgutter - topgutter ) / max; - - // Max value - r - .text( 16, 16, max ) - .attr( - { - font: 'normal 10px "Open Sans", sans-serif', - fill: '#a7aaad', - } - ); - - var path = r.path().attr( { stroke: color, 'stroke-width': 2, 'stroke-linejoin': 'round' } ), - bgp = r.path().attr( { stroke: 'none', opacity: .3, fill: color } ), - label = r.set(), - lx = 0, - ly = 0, - is_label_visible = false, - leave_timer, - blanket = r.set(); - label.push( r.text( 60, 12, '' ).attr( txt ) ); - label.push( r.text( 60, 27, '' ).attr( txt ).attr( { fill: color } ) ); - label.hide(); - var frame = r.popup( 100, 100, label, 'right' ).attr( { fill: '#fff', stroke: '#444', 'stroke-width': 1 } ).hide(); - - var p, bgpp; - for ( var i = 0, ii = labels.length; i < ii; i++ ) { - var y = Math.round( height - bottomgutter - Y * data[i] ), - x = Math.round( leftgutter + X * ( i + .5 ) ); - if ( ! i ) { - p = [ 'M', x, y, 'C', x, y ]; - bgpp = [ 'M', leftgutter + X * .5, height - bottomgutter, 'L', x, y, 'C', x, y ]; - } - if ( i && i < ii - 1 ) { - var Y0 = Math.round( height - bottomgutter - Y * data[i - 1] ), - X0 = Math.round( leftgutter + X * ( i - .5 ) ), - Y2 = Math.round( height - bottomgutter - Y * data[i + 1] ), - X2 = Math.round( leftgutter + X * ( i + 1.5 ) ); - var a = getAnchors( X0, Y0, x, y, X2, Y2 ); - p = p.concat( [ a.x1, a.y1, x, y, a.x2, a.y2 ] ); - bgpp = bgpp.concat( [ a.x1, a.y1, x, y, a.x2, a.y2 ] ); - } - var dot = r.circle( x, y, 4 ).attr( { fill: '#fff', stroke: color, 'stroke-width': 1 } ); - blanket.push( r.rect( leftgutter + X * i, 0, X, height - bottomgutter ).attr( { stroke: 'none', fill: '#fff', opacity: .2 } ) ); - var rect = blanket[blanket.length - 1]; - ( function( x, y, data, date, dot ) { - var timer, - i = 0; - rect.hover( function() { - clearTimeout( leave_timer ); - var side = 'right'; - if ( x + frame.getBBox().width > width ) { - side = 'left'; - } - // set label content to determine correct dimensions - label[0].attr( { text: date } ); - label[1].attr( { text: data + '× Spam' } ); - var ppp = r.popup( x, y, label, side, 1 ), - anim = Raphael.animation( { - path: ppp.path, - transform: [ 't', ppp.dx, ppp.dy ], - }, 200 * is_label_visible ); - lx = label[0].transform()[0][1] + ppp.dx; - ly = label[0].transform()[0][2] + ppp.dy; - frame.show().stop().animate( anim ); - - label[0].show().stop().animateWith( frame, anim, { transform: [ 't', lx, ly ] }, 200 * is_label_visible ); - label[1].show().stop().animateWith( frame, anim, { transform: [ 't', lx, ly ] }, 200 * is_label_visible ); - dot.attr( 'r', 6 ); - is_label_visible = true; - }, function() { - dot.attr( 'r', 4 ); - leave_timer = setTimeout( function() { - frame.hide(); - label[0].hide(); - label[1].hide(); - is_label_visible = false; - }, 1 ); - } ); - }( x, y, data[i], labels[i], dot ) ); - } - p = p.concat( [ x, y, x, y ] ); - bgpp = bgpp.concat( [ x, y, x, y, 'L', x, height - bottomgutter, 'z' ] ); - path.attr( { path: p } ); - bgp.attr( { path: bgpp } ); - frame.toFront(); - label[0].toFront(); - label[1].toFront(); - blanket.toFront(); -}() ); diff --git a/js/raphael.helper.js b/js/raphael.helper.js deleted file mode 100644 index b7a066d3..00000000 --- a/js/raphael.helper.js +++ /dev/null @@ -1,140 +0,0 @@ -var tokenRegex = /\{([^\}]+)\}/g, - objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g, - replacer = function( all, key, obj ) { - var res = obj; - key.replace( objNotationRegex, function( all, name, quote, quotedName, isFunc ) { - name = name || quotedName; - if ( res ) { - if ( name in res ) { - res = res[name]; - } - typeof res === 'function' && isFunc && ( res = res() ); - } - } ); - res = ( res == null || res == obj ? all : res ) + ''; - return res; - }, - fill = function( str, obj ) { - return String( str ).replace( tokenRegex, function( all, key ) { - return replacer( all, key, obj ); - } ); - }; - -Raphael.fn.popup = function( X, Y, set, pos, ret ) { - pos = String( pos || 'top-middle' ).split( '-' ); - pos[1] = pos[1] || 'middle'; - var r = 5, - bb = set.getBBox(), - w = Math.round( bb.width ), - h = Math.round( bb.height ), - x = Math.round( bb.x ) - r, - y = Math.round( bb.y ) - r, - gap = Math.min( h / 2, w / 2, 10 ), - shapes = { - top: 'M{x},{y}h{w4},{w4},{w4},{w4}a{r},{r},0,0,1,{r},{r}v{h4},{h4},{h4},{h4}a{r},{r},0,0,1,-{r},{r}l-{right},0-{gap},{gap}-{gap}-{gap}-{left},0a{r},{r},0,0,1-{r}-{r}v-{h4}-{h4}-{h4}-{h4}a{r},{r},0,0,1,{r}-{r}z', - bottom: 'M{x},{y}l{left},0,{gap}-{gap},{gap},{gap},{right},0a{r},{r},0,0,1,{r},{r}v{h4},{h4},{h4},{h4}a{r},{r},0,0,1,-{r},{r}h-{w4}-{w4}-{w4}-{w4}a{r},{r},0,0,1-{r}-{r}v-{h4}-{h4}-{h4}-{h4}a{r},{r},0,0,1,{r}-{r}z', - right: 'M{x},{y}h{w4},{w4},{w4},{w4}a{r},{r},0,0,1,{r},{r}v{h4},{h4},{h4},{h4}a{r},{r},0,0,1,-{r},{r}h-{w4}-{w4}-{w4}-{w4}a{r},{r},0,0,1-{r}-{r}l0-{bottom}-{gap}-{gap},{gap}-{gap},0-{top}a{r},{r},0,0,1,{r}-{r}z', - left: 'M{x},{y}h{w4},{w4},{w4},{w4}a{r},{r},0,0,1,{r},{r}l0,{top},{gap},{gap}-{gap},{gap},0,{bottom}a{r},{r},0,0,1,-{r},{r}h-{w4}-{w4}-{w4}-{w4}a{r},{r},0,0,1-{r}-{r}v-{h4}-{h4}-{h4}-{h4}a{r},{r},0,0,1,{r}-{r}z', - }, - offset = { - hx0: X - ( x + r + w - gap * 2 ), - hx1: X - ( x + r + w / 2 - gap ), - hx2: X - ( x + r + gap ), - vhy: Y - ( y + r + h + r + gap ), - '^hy': Y - ( y - gap ), - - }, - mask = [ { - x: x + r, - y: y, - w: w, - w4: w / 4, - h4: h / 4, - right: 0, - left: w - gap * 2, - bottom: 0, - top: h - gap * 2, - r: r, - h: h, - gap: gap, - }, { - x: x + r, - y: y, - w: w, - w4: w / 4, - h4: h / 4, - left: w / 2 - gap, - right: w / 2 - gap, - top: h / 2 - gap, - bottom: h / 2 - gap, - r: r, - h: h, - gap: gap, - }, { - x: x + r, - y: y, - w: w, - w4: w / 4, - h4: h / 4, - left: 0, - right: w - gap * 2, - top: 0, - bottom: h - gap * 2, - r: r, - h: h, - gap: gap, - } ][pos[1] == 'middle' ? 1 : ( pos[1] == 'top' || pos[1] == 'left' ) * 2]; - var dx = 0, - dy = 0, - out = this.path( fill( shapes[pos[0]], mask ) ).insertBefore( set ); - switch ( pos[0] ) { - case 'top': - dx = X - ( x + r + mask.left + gap ); - dy = Y - ( y + r + h + r + gap ); - break; - case 'bottom': - dx = X - ( x + r + mask.left + gap ); - dy = Y - ( y - gap ); - break; - case 'left': - dx = X - ( x + r + w + r + gap ); - dy = Y - ( y + r + mask.top + gap ); - break; - case 'right': - dx = X - ( x - gap ); - dy = Y - ( y + r + mask.top + gap ); - break; - } - out.translate( dx, dy ); - if ( ret ) { - ret = out.attr( 'path' ); - out.remove(); - return { - path: ret, - dx: dx, - dy: dy, - }; - } - set.translate( dx, dy ); - return out; -}; - -function getAnchors( p1x, p1y, p2x, p2y, p3x, p3y ) { - var l1 = ( p2x - p1x ) / 2, - l2 = ( p3x - p2x ) / 2, - a = Math.atan( ( p2x - p1x ) / Math.abs( p2y - p1y ) ), - b = Math.atan( ( p3x - p2x ) / Math.abs( p2y - p3y ) ); - a = p1y < p2y ? Math.PI - a : a; - b = p3y < p2y ? Math.PI - b : b; - var alpha = Math.PI / 2 - ( ( a + b ) % ( Math.PI * 2 ) ) / 2, - dx1 = l1 * Math.sin( alpha + a ), - dy1 = l1 * Math.cos( alpha + a ), - dx2 = l2 * Math.sin( alpha + b ), - dy2 = l2 * Math.cos( alpha + b ); - return { - x1: p2x - dx1, - y1: p2y + dy1, - x2: p2x + dx2, - y2: p2y + dy2, - }; -} diff --git a/js/raphael.min.js b/js/raphael.min.js deleted file mode 100644 index 2fb91046..00000000 --- a/js/raphael.min.js +++ /dev/null @@ -1,3 +0,0 @@ -!function t(e,r){"object"==typeof exports&&"object"==typeof module?module.exports=r():"function"==typeof define&&define.amd?define([],r):"object"==typeof exports?exports.Raphael=r():e.Raphael=r()}(this,function(){return function(t){function e(i){if(r[i])return r[i].exports;var n=r[i]={exports:{},id:i,loaded:!1};return t[i].call(n.exports,n,n.exports,e),n.loaded=!0,n.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var i,n;i=[r(1),r(3),r(4)],n=function(t){return t}.apply(e,i),!(void 0!==n&&(t.exports=n))},function(t,e,r){var i,n;i=[r(2)],n=function(t){function e(r){if(e.is(r,"function"))return w?r():t.on("raphael.DOMload",r);if(e.is(r,Q))return e._engine.create[z](e,r.splice(0,3+e.is(r[0],$))).add(r);var i=Array.prototype.slice.call(arguments,0);if(e.is(i[i.length-1],"function")){var n=i.pop();return w?n.call(e._engine.create[z](e,i)):t.on("raphael.DOMload",function(){n.call(e._engine.create[z](e,i))})}return e._engine.create[z](e,arguments)}function r(t){if("function"==typeof t||Object(t)!==t)return t;var e=new t.constructor;for(var i in t)t[A](i)&&(e[i]=r(t[i]));return e}function i(t,e){for(var r=0,i=t.length;r=1e3&&delete o[l.shift()],l.push(s),o[s]=t[z](e,a),r?r(o[s]):o[s])}return n}function a(){return this.hex}function s(t,e){for(var r=[],i=0,n=t.length;n-2*!e>i;i+=2){var a=[{x:+t[i-2],y:+t[i-1]},{x:+t[i],y:+t[i+1]},{x:+t[i+2],y:+t[i+3]},{x:+t[i+4],y:+t[i+5]}];e?i?n-4==i?a[3]={x:+t[0],y:+t[1]}:n-2==i&&(a[2]={x:+t[0],y:+t[1]},a[3]={x:+t[2],y:+t[3]}):a[0]={x:+t[n-2],y:+t[n-1]}:n-4==i?a[3]=a[2]:i||(a[0]={x:+t[i],y:+t[i+1]}),r.push(["C",(-a[0].x+6*a[1].x+a[2].x)/6,(-a[0].y+6*a[1].y+a[2].y)/6,(a[1].x+6*a[2].x-a[3].x)/6,(a[1].y+6*a[2].y-a[3].y)/6,a[2].x,a[2].y])}return r}function o(t,e,r,i,n){var a=-3*e+9*r-9*i+3*n,s=t*a+6*e-12*r+6*i;return t*s-3*e+3*r}function l(t,e,r,i,n,a,s,l,h){null==h&&(h=1),h=h>1?1:h<0?0:h;for(var u=h/2,c=12,f=[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],p=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],d=0,g=0;gd;)c/=2,f+=(pW(n,s)||W(e,i)W(a,o))){var l=(t*i-e*r)*(n-s)-(t-r)*(n*o-a*s),h=(t*i-e*r)*(a-o)-(e-i)*(n*o-a*s),u=(t-r)*(a-o)-(e-i)*(n-s);if(u){var c=l/u,f=h/u,p=+c.toFixed(2),d=+f.toFixed(2);if(!(p<+G(t,r).toFixed(2)||p>+W(t,r).toFixed(2)||p<+G(n,s).toFixed(2)||p>+W(n,s).toFixed(2)||d<+G(e,i).toFixed(2)||d>+W(e,i).toFixed(2)||d<+G(a,o).toFixed(2)||d>+W(a,o).toFixed(2)))return{x:c,y:f}}}}function c(t,e){return p(t,e)}function f(t,e){return p(t,e,1)}function p(t,r,i){var n=e.bezierBBox(t),a=e.bezierBBox(r);if(!e.isBBoxIntersect(n,a))return i?0:[];for(var s=l.apply(0,t),o=l.apply(0,r),h=W(~~(s/5),1),c=W(~~(o/5),1),f=[],p=[],d={},g=i?0:[],v=0;v=0&&S<=1.001&&A>=0&&A<=1.001&&(i?g++:g.push({x:C.x,y:C.y,t1:G(S,1),t2:G(A,1)}))}}return g}function d(t,r,i){t=e._path2curve(t),r=e._path2curve(r);for(var n,a,s,o,l,h,u,c,f,d,g=i?0:[],v=0,x=t.length;vi)return i;for(;ra?r=n:i=n,n=(i-r)/2+r}return n}var h=3*e,u=3*(i-e)-h,c=1-h-u,f=3*r,p=3*(n-r)-f,d=1-f-p;return o(t,1/(200*a))}function m(t,e){var r=[],i={};if(this.ms=e,this.times=1,t){for(var n in t)t[A](n)&&(i[ht(n)]=t[n],r.push(ht(n)));r.sort(Bt)}this.anim=i,this.top=r[r.length-1],this.percents=r}function b(r,i,n,a,s,o){n=ht(n);var l,h,u,c=[],f,p,d,v=r.ms,x={},m={},b={};if(a)for(w=0,B=Ee.length;wa*r.top){n=r.percents[w],p=r.percents[w-1]||0,v=v/r.top*(n-p),f=r.percents[w+1],l=r.anim[n];break}a&&i.attr(r.anim[r.percents[w]])}if(l){if(h)h.initstatus=a,h.start=new Date-h.ms*a;else{for(var C in l)if(l[A](C)&&(pt[A](C)||i.paper.customAttributes[A](C)))switch(x[C]=i.attr(C),null==x[C]&&(x[C]=ft[C]),m[C]=l[C],pt[C]){case $:b[C]=(m[C]-x[C])/v;break;case"colour":x[C]=e.getRGB(x[C]);var S=e.getRGB(m[C]);b[C]={r:(S.r-x[C].r)/v,g:(S.g-x[C].g)/v,b:(S.b-x[C].b)/v};break;case"path":var T=Qt(x[C],m[C]),E=T[1];for(x[C]=T[0],b[C]=[],w=0,B=x[C].length;w',Lt=Nt.firstChild,Lt.style.behavior="url(#default#VML)",!Lt||"object"!=typeof Lt.adj)return e.type=R;Nt=null}e.svg=!(e.vml="VML"==e.type),e._Paper=M,e.fn=N=M.prototype=e.prototype,e._id=0,e.is=function(t,e){return e=O.call(e),"finite"==e?!at[A](+t):"array"==e?t instanceof Array:"null"==e&&null===t||e==typeof t&&null!==t||"object"==e&&t===Object(t)||"array"==e&&Array.isArray&&Array.isArray(t)||tt.call(t).slice(8,-1).toLowerCase()==e},e.angle=function(t,r,i,n,a,s){if(null==a){var o=t-i,l=r-n;return o||l?(180+180*Y.atan2(-l,-o)/U+360)%360:0}return e.angle(t,r,a,s)-e.angle(i,n,a,s)},e.rad=function(t){return t%360*U/180},e.deg=function(t){return Math.round(180*t/U%360*1e3)/1e3},e.snapTo=function(t,r,i){if(i=e.is(i,"finite")?i:10,e.is(t,Q)){for(var n=t.length;n--;)if(H(t[n]-r)<=i)return t[n]}else{t=+t;var a=r%t;if(at-i)return r-a+t}return r};var zt=e.createUUID=function(t,e){return function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(t,e).toUpperCase()}}(/[xy]/g,function(t){var e=16*Y.random()|0,r="x"==t?e:3&e|8;return r.toString(16)});e.setWindow=function(r){t("raphael.setWindow",e,T.win,r),T.win=r,T.doc=T.win.document,e._engine.initWin&&e._engine.initWin(T.win)};var Pt=function(t){if(e.vml){var r=/^\s+|\s+$/g,i;try{var a=new ActiveXObject("htmlfile");a.write(""),a.close(),i=a.body}catch(s){i=createPopup().document.body}var o=i.createTextRange();Pt=n(function(t){try{i.style.color=I(t).replace(r,R);var e=o.queryCommandValue("ForeColor");return e=(255&e)<<16|65280&e|(16711680&e)>>>16,"#"+("000000"+e.toString(16)).slice(-6)}catch(n){return"none"}})}else{var l=T.doc.createElement("i");l.title="Raphaël Colour Picker",l.style.display="none",T.doc.body.appendChild(l),Pt=n(function(t){return l.style.color=t,T.doc.defaultView.getComputedStyle(l,R).getPropertyValue("color")})}return Pt(t)},Ft=function(){return"hsb("+[this.h,this.s,this.b]+")"},Rt=function(){return"hsl("+[this.h,this.s,this.l]+")"},jt=function(){return this.hex},It=function(t,r,i){if(null==r&&e.is(t,"object")&&"r"in t&&"g"in t&&"b"in t&&(i=t.b,r=t.g,t=t.r),null==r&&e.is(t,Z)){var n=e.getRGB(t);t=n.r,r=n.g,i=n.b}return(t>1||r>1||i>1)&&(t/=255,r/=255,i/=255),[t,r,i]},qt=function(t,r,i,n){t*=255,r*=255,i*=255;var a={r:t,g:r,b:i,hex:e.rgb(t,r,i),toString:jt};return e.is(n,"finite")&&(a.opacity=n),a};e.color=function(t){var r;return e.is(t,"object")&&"h"in t&&"s"in t&&"b"in t?(r=e.hsb2rgb(t),t.r=r.r,t.g=r.g,t.b=r.b,t.hex=r.hex):e.is(t,"object")&&"h"in t&&"s"in t&&"l"in t?(r=e.hsl2rgb(t),t.r=r.r,t.g=r.g,t.b=r.b,t.hex=r.hex):(e.is(t,"string")&&(t=e.getRGB(t)),e.is(t,"object")&&"r"in t&&"g"in t&&"b"in t?(r=e.rgb2hsl(t),t.h=r.h,t.s=r.s,t.l=r.l,r=e.rgb2hsb(t),t.v=r.b):(t={hex:"none"},t.r=t.g=t.b=t.h=t.s=t.v=t.l=-1)),t.toString=jt,t},e.hsb2rgb=function(t,e,r,i){this.is(t,"object")&&"h"in t&&"s"in t&&"b"in t&&(r=t.b,e=t.s,i=t.o,t=t.h),t*=360;var n,a,s,o,l;return t=t%360/60,l=r*e,o=l*(1-H(t%2-1)),n=a=s=r-l,t=~~t,n+=[l,o,0,0,o,l][t],a+=[o,l,l,o,0,0][t],s+=[0,0,o,l,l,o][t],qt(n,a,s,i)},e.hsl2rgb=function(t,e,r,i){this.is(t,"object")&&"h"in t&&"s"in t&&"l"in t&&(r=t.l,e=t.s,t=t.h),(t>1||e>1||r>1)&&(t/=360,e/=100,r/=100),t*=360;var n,a,s,o,l;return t=t%360/60,l=2*e*(r<.5?r:1-r),o=l*(1-H(t%2-1)),n=a=s=r-l/2,t=~~t,n+=[l,o,0,0,o,l][t],a+=[o,l,l,o,0,0][t],s+=[0,0,o,l,l,o][t],qt(n,a,s,i)},e.rgb2hsb=function(t,e,r){r=It(t,e,r),t=r[0],e=r[1],r=r[2];var i,n,a,s;return a=W(t,e,r),s=a-G(t,e,r),i=0==s?null:a==t?(e-r)/s:a==e?(r-t)/s+2:(t-e)/s+4,i=(i+360)%6*60/360,n=0==s?0:s/a,{h:i,s:n,b:a,toString:Ft}},e.rgb2hsl=function(t,e,r){r=It(t,e,r),t=r[0],e=r[1],r=r[2];var i,n,a,s,o,l;return s=W(t,e,r),o=G(t,e,r),l=s-o,i=0==l?null:s==t?(e-r)/l:s==e?(r-t)/l+2:(t-e)/l+4,i=(i+360)%6*60/360,a=(s+o)/2,n=0==l?0:a<.5?l/(2*a):l/(2-2*a),{h:i,s:n,l:a,toString:Rt}},e._path2string=function(){return this.join(",").replace(xt,"$1")};var Dt=e._preload=function(t,e){var r=T.doc.createElement("img");r.style.cssText="position:absolute;left:-9999em;top:-9999em",r.onload=function(){e.call(this),this.onload=null,T.doc.body.removeChild(this)},r.onerror=function(){T.doc.body.removeChild(this)},T.doc.body.appendChild(r),r.src=t};e.getRGB=n(function(t){if(!t||(t=I(t)).indexOf("-")+1)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:a};if("none"==t)return{r:-1,g:-1,b:-1,hex:"none",toString:a};!(vt[A](t.toLowerCase().substring(0,2))||"#"==t.charAt())&&(t=Pt(t));var r,i,n,s,o,l,h,u=t.match(nt);return u?(u[2]&&(s=ut(u[2].substring(5),16),n=ut(u[2].substring(3,5),16),i=ut(u[2].substring(1,3),16)),u[3]&&(s=ut((l=u[3].charAt(3))+l,16),n=ut((l=u[3].charAt(2))+l,16),i=ut((l=u[3].charAt(1))+l,16)),u[4]&&(h=u[4][q](gt),i=ht(h[0]),"%"==h[0].slice(-1)&&(i*=2.55),n=ht(h[1]),"%"==h[1].slice(-1)&&(n*=2.55),s=ht(h[2]),"%"==h[2].slice(-1)&&(s*=2.55),"rgba"==u[1].toLowerCase().slice(0,4)&&(o=ht(h[3])),h[3]&&"%"==h[3].slice(-1)&&(o/=100)),u[5]?(h=u[5][q](gt),i=ht(h[0]),"%"==h[0].slice(-1)&&(i*=2.55),n=ht(h[1]),"%"==h[1].slice(-1)&&(n*=2.55),s=ht(h[2]),"%"==h[2].slice(-1)&&(s*=2.55),("deg"==h[0].slice(-3)||"°"==h[0].slice(-1))&&(i/=360),"hsba"==u[1].toLowerCase().slice(0,4)&&(o=ht(h[3])),h[3]&&"%"==h[3].slice(-1)&&(o/=100),e.hsb2rgb(i,n,s,o)):u[6]?(h=u[6][q](gt),i=ht(h[0]),"%"==h[0].slice(-1)&&(i*=2.55),n=ht(h[1]),"%"==h[1].slice(-1)&&(n*=2.55),s=ht(h[2]),"%"==h[2].slice(-1)&&(s*=2.55),("deg"==h[0].slice(-3)||"°"==h[0].slice(-1))&&(i/=360),"hsla"==u[1].toLowerCase().slice(0,4)&&(o=ht(h[3])),h[3]&&"%"==h[3].slice(-1)&&(o/=100),e.hsl2rgb(i,n,s,o)):(u={r:i,g:n,b:s,toString:a},u.hex="#"+(16777216|s|n<<8|i<<16).toString(16).slice(1),e.is(o,"finite")&&(u.opacity=o),u)):{r:-1,g:-1,b:-1,hex:"none",error:1,toString:a}},e),e.hsb=n(function(t,r,i){return e.hsb2rgb(t,r,i).hex}),e.hsl=n(function(t,r,i){return e.hsl2rgb(t,r,i).hex}),e.rgb=n(function(t,e,r){function i(t){return t+.5|0}return"#"+(16777216|i(r)|i(e)<<8|i(t)<<16).toString(16).slice(1)}),e.getColor=function(t){var e=this.getColor.start=this.getColor.start||{h:0,s:1,b:t||.75},r=this.hsb2rgb(e.h,e.s,e.b);return e.h+=.075,e.h>1&&(e.h=0,e.s-=.2,e.s<=0&&(this.getColor.start={h:0,s:1,b:e.b})),r.hex},e.getColor.reset=function(){delete this.start},e.parsePathString=function(t){if(!t)return null;var r=Vt(t);if(r.arr)return Yt(r.arr);var i={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0},n=[];return e.is(t,Q)&&e.is(t[0],Q)&&(n=Yt(t)),n.length||I(t).replace(yt,function(t,e,r){var a=[],s=e.toLowerCase();if(r.replace(bt,function(t,e){e&&a.push(+e)}),"m"==s&&a.length>2&&(n.push([e][P](a.splice(0,2))),s="l",e="m"==e?"l":"L"),"r"==s)n.push([e][P](a));else for(;a.length>=i[s]&&(n.push([e][P](a.splice(0,i[s]))),i[s]););}),n.toString=e._path2string,r.arr=Yt(n),n},e.parseTransformString=n(function(t){if(!t)return null;var r={r:3,s:4,t:2,m:6},i=[];return e.is(t,Q)&&e.is(t[0],Q)&&(i=Yt(t)),i.length||I(t).replace(mt,function(t,e,r){var n=[],a=O.call(e);r.replace(bt,function(t,e){e&&n.push(+e)}),i.push([e][P](n))}),i.toString=e._path2string,i});var Vt=function(t){var e=Vt.ps=Vt.ps||{};return e[t]?e[t].sleep=100:e[t]={sleep:100},setTimeout(function(){for(var r in e)e[A](r)&&r!=t&&(e[r].sleep--,!e[r].sleep&&delete e[r])}),e[t]};e.findDotsAtSegment=function(t,e,r,i,n,a,s,o,l){var h=1-l,u=X(h,3),c=X(h,2),f=l*l,p=f*l,d=u*t+3*c*l*r+3*h*l*l*n+p*s,g=u*e+3*c*l*i+3*h*l*l*a+p*o,v=t+2*l*(r-t)+f*(n-2*r+t),x=e+2*l*(i-e)+f*(a-2*i+e),y=r+2*l*(n-r)+f*(s-2*n+r),m=i+2*l*(a-i)+f*(o-2*a+i),b=h*t+l*r,_=h*e+l*i,w=h*n+l*s,k=h*a+l*o,B=90-180*Y.atan2(v-y,x-m)/U;return(v>y||x=t.x&&e<=t.x2&&r>=t.y&&r<=t.y2},e.isBBoxIntersect=function(t,r){var i=e.isPointInsideBBox;return i(r,t.x,t.y)||i(r,t.x2,t.y)||i(r,t.x,t.y2)||i(r,t.x2,t.y2)||i(t,r.x,r.y)||i(t,r.x2,r.y)||i(t,r.x,r.y2)||i(t,r.x2,r.y2)||(t.xr.x||r.xt.x)&&(t.yr.y||r.yt.y)},e.pathIntersection=function(t,e){return d(t,e)},e.pathIntersectionNumber=function(t,e){return d(t,e,1)},e.isPointInsidePath=function(t,r,i){var n=e.pathBBox(t);return e.isPointInsideBBox(n,r,i)&&d(t,[["M",r,i],["H",n.x2+10]],1)%2==1},e._removedFactory=function(e){return function(){t("raphael.log",null,"Raphaël: you are calling to method “"+e+"” of removed object",e)}};var Ot=e.pathBBox=function(t){var e=Vt(t);if(e.bbox)return r(e.bbox);if(!t)return{x:0,y:0,width:0,height:0,x2:0,y2:0};t=Qt(t);for(var i=0,n=0,a=[],s=[],o,l=0,h=t.length;l1&&(b=Y.sqrt(b),r=b*r,i=b*i);var _=r*r,w=i*i,k=(s==o?-1:1)*Y.sqrt(H((_*w-_*m*m-w*y*y)/(_*m*m+w*y*y))),B=k*r*m/i+(t+l)/2,C=k*-i*y/r+(e+h)/2,S=Y.asin(((e-C)/i).toFixed(9)),A=Y.asin(((h-C)/i).toFixed(9));S=tA&&(S-=2*U),!o&&A>S&&(A-=2*U)}var T=A-S;if(H(T)>c){var E=A,M=l,N=h;A=S+c*(o&&A>S?1:-1),l=B+r*Y.cos(A),h=C+i*Y.sin(A),p=Ut(l,h,r,i,a,0,o,M,N,[A,E,B,C])}T=A-S;var L=Y.cos(S),z=Y.sin(S),F=Y.cos(A),R=Y.sin(A),j=Y.tan(T/4),I=4/3*r*j,D=4/3*i*j,V=[t,e],O=[t+I*z,e-D*L],W=[l+I*R,h-D*F],G=[l,h];if(O[0]=2*V[0]-O[0],O[1]=2*V[1]-O[1],u)return[O,W,G][P](p);p=[O,W,G][P](p).join()[q](",");for(var X=[],$=0,Z=p.length;$"1e12"&&(c=.5),H(f)>"1e12"&&(f=.5),c>0&&c<1&&(g=$t(t,e,r,i,n,a,s,o,c),d.push(g.x),p.push(g.y)),f>0&&f<1&&(g=$t(t,e,r,i,n,a,s,o,f),d.push(g.x),p.push(g.y)),l=a-2*i+e-(o-2*a+i),h=2*(i-e)-2*(a-i),u=e-i,c=(-h+Y.sqrt(h*h-4*l*u))/2/l,f=(-h-Y.sqrt(h*h-4*l*u))/2/l,H(c)>"1e12"&&(c=.5),H(f)>"1e12"&&(f=.5),c>0&&c<1&&(g=$t(t,e,r,i,n,a,s,o,c),d.push(g.x),p.push(g.y)),f>0&&f<1&&(g=$t(t,e,r,i,n,a,s,o,f),d.push(g.x),p.push(g.y)),{min:{x:G[z](0,d),y:G[z](0,p)},max:{x:W[z](0,d),y:W[z](0,p)}}}),Qt=e._path2curve=n(function(t,e){var r=!e&&Vt(t);if(!e&&r.curve)return Yt(r.curve);for(var i=Gt(t),n=e&&Gt(e),a={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},s={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},o=(function(t,e,r){var i,n,a={T:1,Q:1};if(!t)return["C",e.x,e.y,e.x,e.y,e.x,e.y];switch(!(t[0]in a)&&(e.qx=e.qy=null),t[0]){case"M":e.X=t[1],e.Y=t[2];break;case"A":t=["C"][P](Ut[z](0,[e.x,e.y][P](t.slice(1))));break;case"S":"C"==r||"S"==r?(i=2*e.x-e.bx,n=2*e.y-e.by):(i=e.x,n=e.y),t=["C",i,n][P](t.slice(1));break;case"T":"Q"==r||"T"==r?(e.qx=2*e.x-e.qx,e.qy=2*e.y-e.qy):(e.qx=e.x,e.qy=e.y),t=["C"][P](Xt(e.x,e.y,e.qx,e.qy,t[1],t[2]));break;case"Q":e.qx=t[1],e.qy=t[2],t=["C"][P](Xt(e.x,e.y,t[1],t[2],t[3],t[4]));break;case"L":t=["C"][P](Ht(e.x,e.y,t[1],t[2]));break;case"H":t=["C"][P](Ht(e.x,e.y,t[1],e.y));break;case"V":t=["C"][P](Ht(e.x,e.y,e.x,t[1]));break;case"Z":t=["C"][P](Ht(e.x,e.y,e.X,e.Y))}return t}),l=function(t,e){if(t[e].length>7){t[e].shift();for(var r=t[e];r.length;)u[e]="A",n&&(c[e]="A"),t.splice(e++,0,["C"][P](r.splice(0,6)));t.splice(e,1),g=W(i.length,n&&n.length||0)}},h=function(t,e,r,a,s){t&&e&&"M"==t[s][0]&&"M"!=e[s][0]&&(e.splice(s,0,["M",a.x,a.y]),r.bx=0,r.by=0,r.x=t[s][1],r.y=t[s][2],g=W(i.length,n&&n.length||0))},u=[],c=[],f="",p="",d=0,g=W(i.length,n&&n.length||0);dn){if(r&&!c.start){if(f=ke(s,o,l[1],l[2],l[3],l[4],l[5],l[6],n-p),u+=["C"+f.start.x,f.start.y,f.m.x,f.m.y,f.x,f.y],a)return u;c.start=u,u=["M"+f.x,f.y+"C"+f.n.x,f.n.y,f.end.x,f.end.y,l[5],l[6]].join(),p+=h,s=+l[5],o=+l[6];continue}if(!t&&!r)return f=ke(s,o,l[1],l[2],l[3],l[4],l[5],l[6],n-p),{x:f.x,y:f.y,alpha:f.alpha}}p+=h,s=+l[5],o=+l[6]}u+=l.shift()+l}return c.end=u,f=t?p:r?c:e.findDotsAtSegment(s,o,l[0],l[1],l[2],l[3],l[4],l[5],1),f.alpha&&(f={x:f.x,y:f.y,alpha:f.alpha}),f}},Ce=Be(1),Se=Be(),Ae=Be(0,1);e.getTotalLength=Ce,e.getPointAtLength=Se,e.getSubpath=function(t,e,r){if(this.getTotalLength(t)-r<1e-6)return Ae(t,e).end;var i=Ae(t,r,1);return e?Ae(i,e).end:i},ye.getTotalLength=function(){var t=this.getPath();if(t)return this.node.getTotalLength?this.node.getTotalLength():Ce(t)},ye.getPointAtLength=function(t){var e=this.getPath();if(e)return Se(e,t)},ye.getPath=function(){var t,r=e._getPath[this.type];if("text"!=this.type&&"set"!=this.type)return r&&(t=r(this)),t},ye.getSubpath=function(t,r){var i=this.getPath();if(i)return e.getSubpath(i,t,r)};var Te=e.easing_formulas={linear:function(t){return t},"<":function(t){return X(t,1.7)},">":function(t){return X(t,.48)},"<>":function(t){var e=.48-t/1.04,r=Y.sqrt(.1734+e*e),i=r-e,n=X(H(i),1/3)*(i<0?-1:1),a=-r-e,s=X(H(a),1/3)*(a<0?-1:1),o=n+s+.5;return 3*(1-o)*o*o+o*o*o},backIn:function(t){var e=1.70158;return t*t*((e+1)*t-e)},backOut:function(t){t-=1;var e=1.70158;return t*t*((e+1)*t+e)+1},elastic:function(t){return t==!!t?t:X(2,-10*t)*Y.sin((t-.075)*(2*U)/.3)+1},bounce:function(t){var e=7.5625,r=2.75,i;return t<1/r?i=e*t*t:t<2/r?(t-=1.5/r,i=e*t*t+.75):t<2.5/r?(t-=2.25/r,i=e*t*t+.9375):(t-=2.625/r,i=e*t*t+.984375),i}};Te.easeIn=Te["ease-in"]=Te["<"],Te.easeOut=Te["ease-out"]=Te[">"],Te.easeInOut=Te["ease-in-out"]=Te["<>"],Te["back-in"]=Te.backIn,Te["back-out"]=Te.backOut;var Ee=[],Me=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){setTimeout(t,16)},Ne=function(){for(var r=+new Date,i=0;i1&&!n.next){for(v in u)u[A](v)&&(g[v]=n.totalOrigin[v]);n.el.attr(g),b(n.anim,n.el,n.anim.percents[0],null,n.totalOrigin,n.repeat-1)}n.next&&!n.stop&&b(n.anim,n.el,n.next,null,n.totalOrigin,n.repeat)}}}Ee.length&&Me(Ne)},Le=function(t){return t>255?255:t<0?0:t};ye.animateWith=function(t,r,i,n,a,s){var o=this;if(o.removed)return s&&s.call(o),o;var l=i instanceof m?i:e.animation(i,n,a,s),h,u;b(l,o,l.percents[0],null,o.attr());for(var c=0,f=Ee.length;cl&&(l=u)}l+="%",!t[l].callback&&(t[l].callback=n)}return new m(t,r)},ye.animate=function(t,r,i,n){var a=this;if(a.removed)return n&&n.call(a),a;var s=t instanceof m?t:e.animation(t,r,i,n);return b(s,a,s.percents[0],null,a.attr()),a},ye.setTime=function(t,e){return t&&null!=e&&this.status(t,G(e,t.ms)/t.ms),this},ye.status=function(t,e){var r=[],i=0,n,a;if(null!=e)return b(t,this,-1,G(e,1)),this;for(n=Ee.length;i1)for(var i=0,n=r.length;i.5)-1;l(f-.5,2)+l(p-.5,2)>.25&&(p=a.sqrt(.25-l(f-.5,2))*n+.5)&&.5!=p&&(p=p.toFixed(5)-1e-5*n)}return c}),n=n.split(/\s*\-\s*/),"linear"==h){var b=n.shift();if(b=-i(b),isNaN(b))return null;var _=[0,0,a.cos(t.rad(b)),a.sin(t.rad(b))],w=1/(s(o(_[2]),o(_[3]))||1);_[2]*=w,_[3]*=w,_[2]<0&&(_[0]=-_[2],_[2]=0),_[3]<0&&(_[1]=-_[3],_[3]=0)}var k=t._parseDots(n);if(!k)return null;if(u=u.replace(/[\(\)\s,\xb0#]/g,"_"),e.gradient&&u!=e.gradient.id&&(g.defs.removeChild(e.gradient),delete e.gradient),!e.gradient){y=v(h+"Gradient",{id:u}),e.gradient=y,v(y,"radial"==h?{fx:f,fy:p}:{x1:_[0],y1:_[1],x2:_[2],y2:_[3],gradientTransform:e.matrix.invert()}),g.defs.appendChild(y);for(var B=0,C=k.length;B1?z.opacity/100:z.opacity});case"stroke":z=t.getRGB(g),l.setAttribute(d,z.hex),"stroke"==d&&z[e]("opacity")&&v(l,{"stroke-opacity":z.opacity>1?z.opacity/100:z.opacity}),"stroke"==d&&i._.arrows&&("startString"in i._.arrows&&_(i,i._.arrows.startString),"endString"in i._.arrows&&_(i,i._.arrows.endString,1));break;case"gradient":("circle"==i.type||"ellipse"==i.type||"r"!=r(g).charAt())&&x(i,g);break;case"opacity":u.gradient&&!u[e]("stroke-opacity")&&v(l,{"stroke-opacity":g>1?g/100:g});case"fill-opacity":if(u.gradient){P=t._g.doc.getElementById(l.getAttribute("fill").replace(/^url\(#|\)$/g,c)),P&&(F=P.getElementsByTagName("stop"),v(F[F.length-1],{"stop-opacity":g}));break}default:"font-size"==d&&(g=n(g,10)+"px");var R=d.replace(/(\-.)/g,function(t){return t.substring(1).toUpperCase()});l.style[R]=g,i._.dirty=1,l.setAttribute(d,g)}}S(i,a),l.style.visibility=f},C=1.2,S=function(i,a){if("text"==i.type&&(a[e]("text")||a[e]("font")||a[e]("font-size")||a[e]("x")||a[e]("y"))){var s=i.attrs,o=i.node,l=o.firstChild?n(t._g.doc.defaultView.getComputedStyle(o.firstChild,c).getPropertyValue("font-size"),10):10;if(a[e]("text")){for(s.text=a.text;o.firstChild;)o.removeChild(o.firstChild);for(var h=r(a.text).split("\n"),u=[],f,p=0,d=h.length;p"));var Z=X.getBoundingClientRect();m.W=f.w=(Z.right-Z.left)/U,m.H=f.h=(Z.bottom-Z.top)/U,m.X=f.x,m.Y=f.y+m.H/2,("x"in l||"y"in l)&&(m.path.v=t.format("m{0},{1}l{2},{1}",a(f.x*b),a(f.y*b),a(f.x*b)+1));for(var Q=["x","y","text","font","font-family","font-weight","font-style","font-size"],J=0,K=Q.length;J.25&&(r=n.sqrt(.25-l(e-.5,2))*(2*(r>.5)-1)+.5),f=e+p+r),d}),a=a.split(/\s*\-\s*/),"linear"==c){var g=a.shift();if(g=-i(g),isNaN(g))return null}var v=t._parseDots(a);if(!v)return null;if(e=e.shape||e.node,v.length){e.removeChild(s),s.on=!0,s.method="none",s.color=v[0].color,s.color2=v[v.length-1].color;for(var x=[],y=0,m=v.length;y')}}catch(r){N=function(t){return e.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}},t._engine.initWin(t._g.win),t._engine.create=function(){var e=t._getContainer.apply(0,arguments),r=e.container,i=e.height,n,a=e.width,s=e.x,o=e.y;if(!r)throw new Error("VML container not found.");var l=new t._Paper,h=l.canvas=t._g.doc.createElement("div"),u=h.style;return s=s||0,o=o||0,a=a||512,i=i||342,l.width=a,l.height=i,a==+a&&(a+="px"),i==+i&&(i+="px"),l.coordsize=1e3*b+p+1e3*b,l.coordorigin="0 0",l.span=t._g.doc.createElement("span"),l.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;",h.appendChild(l.span),u.cssText=t.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",a,i),1==r?(t._g.doc.body.appendChild(h),u.left=s+"px",u.top=o+"px",u.position="absolute"):r.firstChild?r.insertBefore(h,r.firstChild):r.appendChild(h),l.renderfix=function(){},l},t.prototype.clear=function(){t.eve("raphael.clear",this),this.canvas.innerHTML=d,this.span=t._g.doc.createElement("span"),this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;",this.canvas.appendChild(this.span),this.bottom=this.top=null},t.prototype.remove=function(){t.eve("raphael.remove",this),this.canvas.parentNode.removeChild(this.canvas);for(var e in this)this[e]="function"==typeof this[e]?t._removedFactory(e):null;return!0};var L=t.st;for(var z in M)M[e](z)&&!L[e](z)&&(L[z]=function(t){return function(){var e=arguments;return this.forEach(function(r){r[t].apply(r,e)})}}(z))}}.apply(e,i),!(void 0!==n&&(t.exports=n))}])}); \ No newline at end of file diff --git a/js/scripts.js b/js/scripts.js deleted file mode 100644 index 545dd8d0..00000000 --- a/js/scripts.js +++ /dev/null @@ -1,20 +0,0 @@ -jQuery( document ).ready( - function( $ ) { - function ab_flag_spam() { - var $$ = $( '#ab_flag_spam' ), - nextAll = $$.parent( 'li' ).nextAll( '.ab_flag_spam_child' ); - - nextAll.css( - 'display', - ( $$.is( ':checked' ) ? 'list-item' : 'none' ) - ); - } - - $( '#ab_flag_spam' ).on( - 'change', - ab_flag_spam - ); - - ab_flag_spam(); - } -); diff --git a/package.json b/package.json index bebb03fe..5f32670d 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,7 @@ { - "private": true, - "devDependencies": { - "@wordpress/eslint-plugin": "^11.1.0", - "@wordpress/stylelint-config": "^20.0.0", - "eslint": "^8.4.1", - "prettier": "^2.3.0", - "stylelint": "^14.2.0" - } + "name": "@pluginkollektiv/antispam-bee", + "version": "3.0.0", + "description": "Antispam Bee blocks spam comments and trackbacks effectively and without captchas.", + "author": "pluginkollektiv", + "license": "GPL-2.0-or-later" } diff --git a/phpcs.xml b/phpcs.xml index e5554c64..efc76148 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -1,47 +1,94 @@ - - Coding standard for WordPress plugins + + Generally-applicable sniffs for WordPress plugins. + - - - - - - - - . - /node_modules/* - /tests/* - /vendor/* - *.css - *.js - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + . + + + + /build/ + /vendor/ + /node_modules/ + /tests/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 3047bcc1..a10ee074 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,25 +1,24 @@ - - - - - tests/Unit - - - tests/Integration - - - - - + + + + tests/Unit + tests/Unit/AntispamBeeTest.php + + + tests/Integration + + + + + diff --git a/readme.txt b/readme.txt index 2b332e83..0bc63b35 100755 --- a/readme.txt +++ b/readme.txt @@ -1,265 +1,288 @@ -# Antispam Bee # -* Contributors: pluginkollektiv, websupporter, schlessera, zodiac1978, swissspidy, krafit, kau-boy, florianbrinkmann, pfefferle -* Tags: anti-spam, antispam, block spam, comment, comments, comment spam, pingback, spam, spam filter, trackback, GDPR -* Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=TD4AMD2D8EMZW -* Requires at least: 4.5 -* Tested up to: 5.9 -* Requires PHP: 5.2 -* Stable tag: 2.11.0 -* License: GPLv2 or later -* License URI: https://www.gnu.org/licenses/gpl-2.0.html - -Antispam plugin with a sophisticated tool set for effective day to day comment and trackback spam-fighting. Build with data protection and privacy in mind. - -## Description ## -Say Goodbye to comment spam on your WordPress blog or website. *Antispam Bee* blocks spam comments and trackbacks effectively, without captchas and without sending personal information to third party services. It is free of charge, ad-free and 100% GDPR compliant. - -### Feature/Settings Overview ### -* Trust approved commenters. -* Trust commenters with a Gravatar. -* Consider the comment time. -* Allow comments only in a certain language. -* Block or allow commenters from certain countries. -* Treat BBCode links as spam. -* Validate the IP address of commenters. -* Use regular expressions. -* Search local spam database for commenters previously marked as spammers. -* Notify admins by e-mail about incoming spam. -* Delete existing spam after n days. -* Limit approval to comments/pings (will delete other comment types). -* Select spam indicators to send comments to deletion directly. -* Optionally exclude trackbacks and pingbacks from spam detection. -* Optionally spam-check comment forms on archive pages. -* Display spam statistics on the dashboard, including daily updates of spam detection rate and a total of blocked spam comments. - -### Support ### -* Community support via the [support forums on wordpress.org](https://wordpress.org/support/plugin/antispam-bee) -* Read [the documentation](https://antispambee.pluginkollektiv.org/documentation/) -* We don’t handle support via e-mail, Twitter, GitHub issues etc. - -### Contribute ### -* Active development of this plugin is handled [on GitHub](https://github.com/pluginkollektiv/antispam-bee). -* Pull requests for documented bugs are highly appreciated. -* If you think you’ve found a bug (e.g. you’re experiencing unexpected behavior), please post at the [support forums](https://wordpress.org/support/plugin/antispam-bee) first. -* If you want to help us translate this plugin you can do so [on WordPress Translate](https://translate.wordpress.org/projects/wp-plugins/antispam-bee). - -### Credits ### -* Author: [Sergej Müller](https://sergejmueller.github.io/) -* Maintainers: [pluginkollektiv](https://pluginkollektiv.org) - -## Installation ## -* If you don’t know how to install a plugin for WordPress, [here’s how](http://codex.wordpress.org/Managing_Plugins#Installing_Plugins). - -### Requirements ### -* PHP 5.2.4 or greater -* WordPress 4.5 or greater - -### Settings ### -After you have activated *Antispam Bee* the plugin will block spam comments out of the box. However, you may want to visit *Settings → Antispam Bee* to configure your custom set of anti-spam options that works best for your site. - -## Frequently Asked Questions ## - -### Does Antispam Bee prevents spam registrations or protects form plugins? ### -Antispam Bee works best with default WordPress comments. It does not help to protect form plugins and does not prevent spam registrations. Hopefully we can provide better hooks for third party plugins to use Antispam Bee to fill this gap in the forthcoming new major version. - -### Does Antispam Bee work with Jetpack, wpDiscuz, Disqus Comments and similar comment plugins? -Antispam Bee works best with default WordPress comments. It is not compatible with Jetpack, wpDiscuz or Disqus Comments as those plugins load a new comment form within an iframe. Thus Antispam Bee can not access the comment form directly. - -### Does Antispam Bee work with AJAX comment plugins or similar theme features? -Whether Antispam Bee works with a comment form submitted via AJAX depends on how the AJAX request is made. If the request goes to the file that usually also receives the comments, Antispam Bee could work with it out of the box (the [WP Ajaxify Comments](https://wordpress.org/plugins/wp-ajaxify-comments/) plugin does this, for example). - -If the comments are sent to the `admin-ajax.php`, the `antispam_bee_disallow_ajax_calls` filter must be used to run ASB for requests to that file as well. If the script does not send all form data to the file, but only some selected ones, further customization is probably necessary, as [exemplified in this post by Torsten Landsiedel](https://torstenlandsiedel.de/2020/10/04/ajaxifizierte-kommentare-und-antispam-bee/) (in German). - -### Does Antispam Bee store any private user data, and is it compliant with GDPR? ### -Antispam Bee is developed in Europe. You might have heard we can be a bit nitpicky over here when it comes to privacy. The plugin does not save private user data and is 100% compliant with GDPR. - -### Will I have to edit any theme templates to get Antispam Bee to work? ### -No, the plugin works as is. You may want to configure your favorite settings, though. - -### Does Antispam Bee work with shortened IPs? ### -Generally yes. However, commissioning the Antispam Bee plugin for canceled or shortened IP addresses in comment metadata is not recommended. Because the name and the e-mail address of the comments are not unique, an IP address is the only reliable measure. The more complete the stored IP addresses, the more reliable the assignment or detection of spam. - -### How can I submit undetected spam? ### -If the antispam plugin has passed some spam comments, these comments can be reported for analysis. A [Google table](http://goo.gl/forms/ITzVHXkLVL) was created for this purpose. - -### Antispam Bee with Varnish? ### -If WordPress is operated with Apache + Varnish, the actual IP address of the visitors does not appear in WordPress. Accordingly the Antispam-Plugin lacks the base for the correct functionality. An adaptation in the Varnish configuration file /etc/varnish/default.vcl provides a remedy and forwards the original (not from Apache) IP address in the HTTP header X-Forwarded-For: - -> if (req.restarts == 0) { -> set req.http.X-Forwarded-For = client.ip; -> } - -### Are there some paid services or limitations? ### -No, Antispam Bee is free forever, for both private and commercial projects. You can use it on as many sites as you want. There is no limitation to the number of sites you use the plugin on. - -A complete documentation is available on [pluginkollektiv.org](https://antispambee.pluginkollektiv.org/documentation/). - -## Changelog ## - -### 2.11.0 ### - * Fix: Allow empty comments if `allow_empty_comment` is set to true - * Fix: Add `aria-label` to work around bug in a11y testing tools - * Fix: Change priority for `comment_form_field_comment` from 10 to 99 - * Tweak: Updated some FAQ entries - * Tweak: Updated build tooling - -### 2.10.0 ### - * Fix: Switch from ip2country.info to iplocate.io for country check - * Enhancement: Use filter to add the honeypot field instead of output buffering for new installations and added option to switch between the both ways - * Tweak: Added comment user agent to regex pattern check - * Tweak: Make the ping detection filterable to support new comment types - * Tweak: Updated internal documentation links - * Tweak: Several updates and optimizations in the testing process - * Tweak: Adjust color palette to recent WP version - * Tweak: Adjust wording in variables and option names - * Readme: Add new contributor and clean up unused code - - -### 2.9.4 ### - * Enhancement: Add filter to allow ajax calls - * Tweak: Better wording for BBCode feature in plugin description - * Tweak: Better screenshots in the plugin directory - * Maintenance: Tested up to WordPress 5.7 - -### 2.9.3 ### - * Fixed: Compatibility with WordPress 5.5 - * Fixed: Undefined index on spam list page - * Tweak: Better wording on settings page - * Tweak: AMP compatibility - * Tweak: Protect CSS from overwrite through bad themes - -### 2.9.2 ### - * Fix: Delete comment meta for deleted old spam. For the cleanup of older orphaned comment meta we suggest the usage of [WP Sweep](https://wordpress.org/plugins/wp-sweep/) - * Fix: Statistic in dashboard showed wrong value - * Tweak: Change autocomplete attribute to "new-password" - * Tweak: Autoptimize compatibility improved - * Tweak: Renamed blacklist/whitelist to a better phrase - * Tweak: Added new pattern - * Tweak: UI and text optimizations - * Tweak: Better compatibility with some server configurations - * Tweak: Make spam reason sortable and filterable - * Tweak: Add spam reason for manually marked spam - * Maintenance: Deleted unused code - * Maintenance: Removed Fake IP check (unreliable and producing false positives) - * Maintenance: Fix some coding standard issues - * Maintenance: Tested up to WordPress 5.4 - * Maintenance: Tested up to PHP 7.4 - -### 2.9.1 ### - * Improved backend accessibility - * Prefilled comment textareas do now work with the honeypot - * Compatible with the AMP plugin (https://wordpress.org/plugins/amp/) - * Improved dashboard tooltips - * Improvements for the language detection API - * Scalable IP look up for local spam database - -### 2.9.0 ### - * Introduction of coding standards. - * Switch to franc language detection API for the language check. - * Do not longer overwrite the IP address WordPress saves with the comment by using `pre_comment_user_ip`. - * Do not show "Trust commenters with a Gravatar" if the "Show Gravatar" option is not set. - * Skip the checks, when I ping myself. - * Fixes some wrong usages of the translation functions. - * Use the regular expressions check also for trackbacks. - * Add option to delete Antispam Bee related data when plugin gets deleted via the admin interface. - * Save a hashed + salted IP for every comment - * New check for incoming trackbacks. - * Introduction of behat tests. - * Updates the used JavaScript library for the statistics widget. - * Bugfix in the "Comment form used outside of posts" option. - -### 2.8.1 ### - * PHP 5.3 compatibility - * Bugfix where a spam trackback produced a fatal error - * For more details see https://github.com/pluginkollektiv/antispam-bee/milestone/8?closed=1 - -### 2.8.0 ### - * Removed stopforumspam.com to avoid potential GDPR violation - * Improves IP handling to comply with GDPR - * Improves PHP7.2 compatibility - * Fixes small bug on mobile views - * Allow more than one language in language check - * Minor interface improvements - * Remove old russian and Dutch translation files - * For more details see https://github.com/pluginkollektiv/antispam-bee/milestone/4?closed=1 - -### 2.7.1 ### - * Fixes an incompatibility with Chrome autofill - * Fixes some incompatibilities with other plugins/themes where the comment field was left empty - * Support for RTL - * Solve some translation/language issues - * A new filter to add languages to the language check - * For more details see https://github.com/pluginkollektiv/antispam-bee/milestone/6?closed=1 - -### 2.7.0 ### - * Country check is back again (thanks to Sergej Müller for his amazing work and the service page) - * Improved Honeypot - * Language check through Google Translate API is back again (thanks to Simon Kraft of https://moenus.net/ for offering to cover the costs) - * More default Regexes - * Unit Test Framework - * Accessibility and GUI improvements - * An [english documentation](https://github.com/pluginkollektiv/antispam-bee/wiki) is now available, too. Some corrections in the german documentation. - * Some bugfixes - Among other things for WPML compatibility - * For more details see https://github.com/pluginkollektiv/antispam-bee/milestone/3?closed=1 - -### 2.6.9 ### - * Updates donation links throughout the plugin - * Fixes an error were JavaScript on the dashboard was erroneously being enqueued - * Ensures compatibility with the latest WordPress version - -### 2.6.8 ### - * added a POT file - * updated German translation, added formal version - * updated plugin text domain to include a dash instead of an underscore - * updated, translated + formatted README.md - * updated expired link URLs in plugin and languages files - * updated [plugin authors](https://pluginkollektiv.org/hello-world/) - -### 2.6.7 ### - * Removal of functions *Block comments from specific countries* and *Allow comments only in certain language* for financial reasons - [more information](https://antispambee.pluginkollektiv.org/news/2015/removal-of-allow-comments-only-in-certain-language/) - -### 2.6.6 ### - * Switch to the official Google Translation API - * *Release time investment (Development & QA): 2.5 h* - -### 2.6.5 ### - * Fix: Return parameters on `dashboard_glance_items` callback / thx [@toscho](https://twitter.com/toscho) - * New function: Trust commenters with a Gravatar / thx [@glueckpress](https://twitter.com/glueckpress) - * Additional plausibility checks and filters - * *Release time investment (Development & QA): 12 h* - -### 2.6.4 ### - * Consideration of the comment time (Spam if a comment was written in less than 5 seconds) - [more information](https://antispambee.pluginkollektiv.org/news/2014/antispam-bee-2-6-4/) - * *Release time investment (Development & QA): 6.25 h* - -### 2.6.3 ### - * Sorting for the Antispam Bee column in the spam comments overview - * Code refactoring around the use of REQUEST_URI - * *Release time investment (Development & QA): 2.75 h* - -### 2.6.2 ### - * Improving detection of fake IPs - * *Release time investment (Development & QA): 11 h* - -### 2.6.1 ### - * Code refactoring of options management - * Support for `HTTP_FORWARDED_FOR` header - * *Release time investment (Development & QA): 8.5 h* - -### 2.6.0 ### - * Optimizations for WordPress 3.8 - * Clear invalid UTF-8 characters in comment fields - * Spam reason as a column in the table with spam comments - -For the complete changelog, check out our [GitHub repository](https://github.com/pluginkollektiv/antispam-bee). - -== Upgrade Notice == - -= 2.8.0 = -This update makes sure your spam check is GDPR compliant, no matter the options you choose. Please make sure to update before May 25th! - -## Screenshots ## -1. Block or allow comments from specific countries. -2. Allow comments only in certain languages. -3. Add useful spam stats to your dashboard. -4. Tailor WordPress' spam management to your workflow. +# Antispam Bee # +* Contributors: pluginkollektiv, websupporter, schlessera, zodiac1978, swissspidy, krafit, kau-boy, florianbrinkmann, pfefferle +* Tags: anti-spam, antispam, block spam, comment, comments, comment spam, pingback, spam, spam filter, trackback, GDPR +* Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=TD4AMD2D8EMZW +* Requires at least: 4.5 +* Tested up to: 6.2 +* Requires PHP: 7.2 +* Stable tag: 2.11.0 +* License: GPLv2 or later +* License URI: https://www.gnu.org/licenses/gpl-2.0.html + +Antispam plugin with a sophisticated tool set for effective day to day comment and linkback spam-fighting. Build with data protection and privacy in mind. + +## Description ## +Say Goodbye to comment spam on your WordPress blog or website. *Antispam Bee* blocks spam comments and linkbacks effectively, without captchas and without sending personal information to third party services. It is free of charge, ad-free and 100% GDPR compliant. + +### Feature/Settings Overview ### +* Trust approved commenters. +* Trust commenters with a Gravatar. +* Consider the comment time. +* Allow comments only in a certain language. +* Block or allow commenters from certain countries. +* Treat BBCode links as spam. +* Validate the IP address of commenters. +* Use regular expressions. +* Search local spam database for commenters previously marked as spammers. +* Notify admins by e-mail about incoming spam. +* Delete existing spam after n days. +* Limit approval to comments/pings (will delete other comment types). +* Select spam indicators to send comments to deletion directly. +* Optionally exclude trackbacks and pingbacks from spam detection. +* Optionally spam-check comment forms on archive pages. +* Display spam statistics on the dashboard, including daily updates of spam detection rate and a total of blocked spam comments. + +### Support ### +* Community support via the [support forums on wordpress.org](https://wordpress.org/support/plugin/antispam-bee) +* Read [the documentation](https://antispambee.pluginkollektiv.org/documentation/) +* We don’t handle support via e-mail, Twitter, GitHub issues etc. + +### Contribute ### +* Active development of this plugin is handled [on GitHub](https://github.com/pluginkollektiv/antispam-bee). +* Pull requests for documented bugs are highly appreciated. +* If you think you’ve found a bug (e.g. you’re experiencing unexpected behavior), please post at the [support forums](https://wordpress.org/support/plugin/antispam-bee) first. +* If you want to help us translate this plugin you can do so [on WordPress Translate](https://translate.wordpress.org/projects/wp-plugins/antispam-bee). + +### Credits ### +* Author: [Sergej Müller](https://sergejmueller.github.io/) +* Maintainers: [pluginkollektiv](https://pluginkollektiv.org) + +## Installation ## +* If you don’t know how to install a plugin for WordPress, [here’s how](http://codex.wordpress.org/Managing_Plugins#Installing_Plugins). + +### Requirements ### +* PHP 7.0 or greater +* WordPress 4.5 or greater + +### Settings ### +After you have activated *Antispam Bee* the plugin will block spam comments out of the box. However, you may want to visit *Settings → Antispam Bee* to configure your custom set of anti-spam options that works best for your site. + +## Frequently Asked Questions ## + +### Does Antispam Bee prevents spam registrations or protects form plugins? ### +Antispam Bee works best with default WordPress comments. It does not help to protect form plugins and does not prevent spam registrations. Hopefully we can provide better hooks for third party plugins to use Antispam Bee to fill this gap in the forthcoming new major version. + +### Does Antispam Bee work with Jetpack, wpDiscuz, Disqus Comments and similar comment plugins? +Antispam Bee works best with default WordPress comments. It is not compatible with Jetpack, wpDiscuz or Disqus Comments as those plugins load a new comment form within an iframe. Thus Antispam Bee can not access the comment form directly. + +### Does Antispam Bee work with AJAX comment plugins or similar theme features? +Whether Antispam Bee works with a comment form submitted via AJAX depends on how the AJAX request is made. If the request goes to the file that usually also receives the comments, Antispam Bee could work with it out of the box (the [WP Ajaxify Comments](https://wordpress.org/plugins/wp-ajaxify-comments/) plugin does this, for example). + +If the comments are sent to the `admin-ajax.php`, the `antispam_bee_disallow_ajax_calls` filter must be used to run ASB for requests to that file as well. If the script does not send all form data to the file, but only some selected ones, further customization is probably necessary, as [exemplified in this post by Torsten Landsiedel](https://torstenlandsiedel.de/2020/10/04/ajaxifizierte-kommentare-und-antispam-bee/) (in German). + +### Does Antispam Bee store any private user data, and is it compliant with GDPR? ### +Antispam Bee is developed in Europe. You might have heard we can be a bit nitpicky over here when it comes to privacy. The plugin does not save private user data and is 100% compliant with GDPR. + +### Will I have to edit any theme templates to get Antispam Bee to work? ### +No, the plugin works as is. You may want to configure your favorite settings, though. + +### Does Antispam Bee work with shortened IPs? ### +Generally yes. However, commissioning the Antispam Bee plugin for canceled or shortened IP addresses in comment metadata is not recommended. Because the name and the e-mail address of the comments are not unique, an IP address is the only reliable measure. The more complete the stored IP addresses, the more reliable the assignment or detection of spam. + +### How can I submit undetected spam? ### +If the antispam plugin has passed some spam comments, these comments can be reported for analysis. A [Google table](http://goo.gl/forms/ITzVHXkLVL) was created for this purpose. + +### Antispam Bee with Varnish? ### +If WordPress is operated with Apache + Varnish, the actual IP address of the visitors does not appear in WordPress. Accordingly the Antispam-Plugin lacks the base for the correct functionality. An adaptation in the Varnish configuration file /etc/varnish/default.vcl provides a remedy and forwards the original (not from Apache) IP address in the HTTP header X-Forwarded-For: + +> if (req.restarts == 0) { +> set req.http.X-Forwarded-For = client.ip; +> } + +### Are there some paid services or limitations? ### +No, Antispam Bee is free forever, for both private and commercial projects. You can use it on as many sites as you want. There is no limitation to the number of sites you use the plugin on. + +A complete documentation is available on [pluginkollektiv.org](https://antispambee.pluginkollektiv.org/documentation/). + +## Changelog ## + +### 3.0.0 – WIP ### + * Complete code rewrite and backend UI overhaul + * Allows to extend Antispam Bee with own rules + * Allows to use Antispam Bee rules for other reactions than comments, for example, forms + +### 2.11.3 ### + * Fix: Multiselect for "Delete comments by spam reasons" was not saving values + * Fix: Fix broken link for ISO country codes + * Maintenance: Added test for PHP 8.2 + * Maintenance: Tested up to WordPress 6.2 + +### 2.11.2 ### + * Tweak: remove superfluous translations + * Tweak: make FAQ link an anchor link + * Fix: spam counter no longer raises a warning with PHP 8.1 if no spam is present yet + * Fix: spam reasons are now localized correctly + * Fix: Translations were loaded twice on some admin pages + * Maintenance: Tested up to WordPress 6.1 + +### 2.11.1 ### + * Tweak: remove superfluous type attribute from inline script tag + * Maintenance: Tested up to WordPress 6.0 + +### 2.11.0 ### + * Fix: Allow empty comments if `allow_empty_comment` is set to true + * Fix: Add `aria-label` to work around bug in a11y testing tools + * Fix: Change priority for `comment_form_field_comment` from 10 to 99 + * Tweak: Updated some FAQ entries + * Tweak: Updated build tooling + +### 2.10.0 ### + * Fix: Switch from ip2country.info to iplocate.io for country check + * Enhancement: Use filter to add the honeypot field instead of output buffering for new installations and added option to switch between the both ways + * Tweak: Added comment user agent to regex pattern check + * Tweak: Make the ping detection filterable to support new comment types + * Tweak: Updated internal documentation links + * Tweak: Several updates and optimizations in the testing process + * Tweak: Adjust color palette to recent WP version + * Tweak: Adjust wording in variables and option names + * Readme: Add new contributor and clean up unused code + + +### 2.9.4 ### + * Enhancement: Add filter to allow ajax calls + * Tweak: Better wording for BBCode feature in plugin description + * Tweak: Better screenshots in the plugin directory + * Maintenance: Tested up to WordPress 5.7 + +### 2.9.3 ### + * Fixed: Compatibility with WordPress 5.5 + * Fixed: Undefined index on spam list page + * Tweak: Better wording on settings page + * Tweak: AMP compatibility + * Tweak: Protect CSS from overwrite through bad themes + +### 2.9.2 ### + * Fix: Delete comment meta for deleted old spam. For the cleanup of older orphaned comment meta we suggest the usage of [WP Sweep](https://wordpress.org/plugins/wp-sweep/) + * Fix: Statistic in dashboard showed wrong value + * Tweak: Change autocomplete attribute to "new-password" + * Tweak: Autoptimize compatibility improved + * Tweak: Renamed blacklist/whitelist to a better phrase + * Tweak: Added new pattern + * Tweak: UI and text optimizations + * Tweak: Better compatibility with some server configurations + * Tweak: Make spam reason sortable and filterable + * Tweak: Add spam reason for manually marked spam + * Maintenance: Deleted unused code + * Maintenance: Removed Fake IP check (unreliable and producing false positives) + * Maintenance: Fix some coding standard issues + * Maintenance: Tested up to WordPress 5.4 + * Maintenance: Tested up to PHP 7.4 + +### 2.9.1 ### + * Improved backend accessibility + * Prefilled comment textareas do now work with the honeypot + * Compatible with the AMP plugin (https://wordpress.org/plugins/amp/) + * Improved dashboard tooltips + * Improvements for the language detection API + * Scalable IP look up for local spam database + +### 2.9.0 ### + * Introduction of coding standards. + * Switch to franc language detection API for the language check. + * Do not longer overwrite the IP address WordPress saves with the comment by using `pre_comment_user_ip`. + * Do not show "Trust commenters with a Gravatar" if the "Show Gravatar" option is not set. + * Skip the checks, when I ping myself. + * Fixes some wrong usages of the translation functions. + * Use the regular expressions check also for trackbacks. + * Add option to delete Antispam Bee related data when plugin gets deleted via the admin interface. + * Save a hashed + salted IP for every comment + * New check for incoming trackbacks. + * Introduction of behat tests. + * Updates the used JavaScript library for the statistics widget. + * Bugfix in the "Comment form used outside of posts" option. + +### 2.8.1 ### + * PHP 5.3 compatibility + * Bugfix where a spam trackback produced a fatal error + * For more details see https://github.com/pluginkollektiv/antispam-bee/milestone/8?closed=1 + +### 2.8.0 ### + * Removed stopforumspam.com to avoid potential GDPR violation + * Improves IP handling to comply with GDPR + * Improves PHP7.2 compatibility + * Fixes small bug on mobile views + * Allow more than one language in language check + * Minor interface improvements + * Remove old russian and Dutch translation files + * For more details see https://github.com/pluginkollektiv/antispam-bee/milestone/4?closed=1 + +### 2.7.1 ### + * Fixes an incompatibility with Chrome autofill + * Fixes some incompatibilities with other plugins/themes where the comment field was left empty + * Support for RTL + * Solve some translation/language issues + * A new filter to add languages to the language check + * For more details see https://github.com/pluginkollektiv/antispam-bee/milestone/6?closed=1 + +### 2.7.0 ### + * Country check is back again (thanks to Sergej Müller for his amazing work and the service page) + * Improved Honeypot + * Language check through Google Translate API is back again (thanks to Simon Kraft of https://moenus.net/ for offering to cover the costs) + * More default Regexes + * Unit Test Framework + * Accessibility and GUI improvements + * An [english documentation](https://github.com/pluginkollektiv/antispam-bee/wiki) is now available, too. Some corrections in the german documentation. + * Some bugfixes - Among other things for WPML compatibility + * For more details see https://github.com/pluginkollektiv/antispam-bee/milestone/3?closed=1 + +### 2.6.9 ### + * Updates donation links throughout the plugin + * Fixes an error were JavaScript on the dashboard was erroneously being enqueued + * Ensures compatibility with the latest WordPress version + +### 2.6.8 ### + * added a POT file + * updated German translation, added formal version + * updated plugin text domain to include a dash instead of an underscore + * updated, translated + formatted README.md + * updated expired link URLs in plugin and languages files + * updated [plugin authors](https://pluginkollektiv.org/hello-world/) + +### 2.6.7 ### + * Removal of functions *Block comments from specific countries* and *Allow comments only in certain language* for financial reasons - [more information](https://antispambee.pluginkollektiv.org/news/2015/removal-of-allow-comments-only-in-certain-language/) + +### 2.6.6 ### + * Switch to the official Google Translation API + * *Release time investment (Development & QA): 2.5 h* + +### 2.6.5 ### + * Fix: Return parameters on `dashboard_glance_items` callback / thx [@toscho](https://twitter.com/toscho) + * New function: Trust commenters with a Gravatar / thx [@glueckpress](https://twitter.com/glueckpress) + * Additional plausibility checks and filters + * *Release time investment (Development & QA): 12 h* + +### 2.6.4 ### + * Consideration of the comment time (Spam if a comment was written in less than 5 seconds) - [more information](https://antispambee.pluginkollektiv.org/news/2014/antispam-bee-2-6-4/) + * *Release time investment (Development & QA): 6.25 h* + +### 2.6.3 ### + * Sorting for the Antispam Bee column in the spam comments overview + * Code refactoring around the use of REQUEST_URI + * *Release time investment (Development & QA): 2.75 h* + +### 2.6.2 ### + * Improving detection of fake IPs + * *Release time investment (Development & QA): 11 h* + +### 2.6.1 ### + * Code refactoring of options management + * Support for `HTTP_FORWARDED_FOR` header + * *Release time investment (Development & QA): 8.5 h* + +### 2.6.0 ### + * Optimizations for WordPress 3.8 + * Clear invalid UTF-8 characters in comment fields + * Spam reason as a column in the table with spam comments + +For the complete changelog, check out our [GitHub repository](https://github.com/pluginkollektiv/antispam-bee). + +== Upgrade Notice == + += 2.8.0 = +This update makes sure your spam check is GDPR compliant, no matter the options you choose. Please make sure to update before May 25th! + +## Screenshots ## +1. Block or allow comments from specific countries. +2. Allow comments only in certain languages. +3. Add useful spam stats to your dashboard. +4. Tailor WordPress' spam management to your workflow. diff --git a/src/Admin/CommentsColumns.php b/src/Admin/CommentsColumns.php new file mode 100644 index 00000000..8dd3bf14 --- /dev/null +++ b/src/Admin/CommentsColumns.php @@ -0,0 +1,233 @@ + esc_html__( 'Spam Reason', 'antispam-bee' ), + ] + ); + } + + /** + * Display plugin column values on comments screen + * + * @param string $column Currently selected column. + * @param integer $comment_id Comment ID. + * + * @since 2.6.0 + * @change 2.6.0 + */ + public static function print_plugin_column( string $column, int $comment_id ): void { + if ( 'antispam_bee_reason' !== $column ) { + return; + } + + $spam_reason = get_comment_meta( $comment_id, $column, true ); + + if ( empty( $spam_reason ) ) { + echo esc_html_x( 'No data available', 'spam-reason-column-text', 'antispam-bee' ); + + return; + } + + $reasons = explode( ',', $spam_reason ); + $reason_texts = SpamReasonTextHelper::get_texts_by_slugs( $reasons ); + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- reason texts pre-sanitized. + echo implode( ',
', $reason_texts ); + } + + /** + * Register plugin sortable columns on comments screen + * + * @param array $columns Registered columns. + * + * @return array $columns Columns with AB field. + * @since 2.6.3 + * @change 2.6.3 + */ + public static function register_sortable_columns( array $columns ): array { + $columns['antispam_bee_reason'] = 'antispam_bee_reason'; + + return $columns; + } + + /** + * Adjust orderby query + * + * @param WP_Comment_Query $query Current WordPress query. + * + * @since 2.6.3 + * @change 2.6.3 + */ + public static function set_orderby_query( WP_Comment_Query $query ): void { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $orderby = isset( $_GET['orderby'] ) ? sanitize_text_field( wp_unslash( $_GET['orderby'] ) ) : ''; + + if ( empty( $orderby ) || 'antispam_bee_reason' !== $orderby ) { + return; + } + + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key + $query->query_vars['meta_key'] = 'antispam_bee_reason'; + $query->query_vars['orderby'] = 'meta_value'; + } + + /** + * Filter comments by the spam reason + * + * @global wpdb $wpdb + */ + public static function filter_columns(): void { + global $wpdb; + ?> + + + query_vars['meta_key'] = 'antispam_bee_reason'; + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value + $query->query_vars['meta_value'] = $spam_reason; + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_compare + $query->query_vars['meta_compare'] = 'LIKE'; + + return; + } + + $query->query_vars['meta_query'] = [ + 'relation' => 'OR', + [ + 'key' => 'antispam_bee_reason', + 'value' => $spam_reason, + 'compare' => 'LIKE', + ], + [ + 'key' => 'antispam_bee_reason', + 'value' => array_flip( $reasons_mapping )[ $spam_reason ], + 'compare' => 'LIKE', + ], + ]; + } + + /** + * Print CSS for the plugin column + * + * @since 2.6.1 + * @change 2.6.1 + */ + public static function print_column_styles(): void { + ?> + + #dashboard_right_now .ab-count::before {content: "\f117"} #dashboard_right_now .ab-current-spam::before {content: "\f17e"}'; + + $items[] = '' . esc_html( + sprintf( + // translators: The number of spam comments Antispam Bee blocked so far. + __( '%s comments blocked', 'antispam-bee' ), + self::get_spam_count() + ) + ) . ''; + + $link = add_query_arg( 'comment_status', 'spam', admin_url( 'edit-comments.php' ) ); + $comments_number = wp_count_comments(); + $items[] = '' . esc_html( + sprintf( + // translators: The number of spam comments in the local spam database. + __( '%s comments in local spam db', 'antispam-bee' ), + self::format_number( $comments_number->spam ) + ) + ) . ''; + + return $items; + } + + /** + * Return the number of spam comments + * + * @since 0.1 + * @since 2.4 + */ + private static function get_spam_count(): string { + $count = intval( Settings::get_option( 'spam_count', '' ) ); + + return self::format_number( $count ); + } + + /** + * Format a number. + * + * @param float|int $number Number to format. + * @return string + */ + private static function format_number( $number ): string { + return ( get_locale() === 'de_DE' ? number_format( $number, 0, '', '.' ) : number_format_i18n( $number ) ); + } + + /** + * Output the number of spam comments + * + * @since 0.1 + * @since 2.4 + */ + public static function the_spam_count(): void { + echo esc_html( self::get_spam_count() ); + } +} diff --git a/src/Admin/Fields/Checkbox.php b/src/Admin/Fields/Checkbox.php new file mode 100644 index 00000000..237930e2 --- /dev/null +++ b/src/Admin/Fields/Checkbox.php @@ -0,0 +1,36 @@ +get_label() ) ? sprintf( + '', + esc_attr( $this->get_name() ), + $this->get_label() + ) : ''; + + printf( + '%3$s', + esc_attr( $this->get_name() ), + checked( 'on', $this->get_value(), false ), + $label + ); + $this->maybe_show_description(); + } +} diff --git a/src/Admin/Fields/CheckboxGroup.php b/src/Admin/Fields/CheckboxGroup.php new file mode 100644 index 00000000..1daebaad --- /dev/null +++ b/src/Admin/Fields/CheckboxGroup.php @@ -0,0 +1,57 @@ +option['options'] ?? []; + if ( ! is_array( $options ) ) { + return; + } + + printf( + '

%s

', + $this->get_label() + ); + foreach ( $options as $key => $value ) { + printf( + '
', + esc_attr( $this->get_name() . '[' . $key . ']' ), + checked( 'on', $this->get_custom_value( $key ), false ), + esc_html( $value ) + ); + } + $this->maybe_show_description(); + } + + /** + * Get Value. + * + * @param string $key Option key. + * + * @return mixed Value stored in database. + */ + protected function get_custom_value( string $key ) { + $options = Settings::get_option( "{$this->controllable_option_name}", $this->type ); + + return $options[ $key ] ?? null; + } +} diff --git a/src/Admin/Fields/Field.php b/src/Admin/Fields/Field.php new file mode 100644 index 00000000..cbd9fa48 --- /dev/null +++ b/src/Admin/Fields/Field.php @@ -0,0 +1,131 @@ +type = $type; + $this->option = $option; + $this->controllable_option_name = $controllable::get_option_name( $this->option['option_name'] ); + } + + /** + * Get Name. + * + * @return string Name of the field. + */ + public function get_name() { + $option_name = Settings::OPTION_NAME; + $name = "{$option_name}[{$this->type}][{$this->controllable_option_name}]"; + + return str_replace( '-', '_', $name ); + } + + /** + * Get label. + * + * @return string Label of the field. + */ + public function get_label() { + $kses = $this->option['label_kses'] ?? []; + $label = $this->option['label'] ?? ''; + if ( ! $kses ) { + return esc_html( $label ); + } + return wp_kses( $label, $kses ); + } + + /** + * Get placeholder. + * + * @return string + */ + public function get_placeholder(): string { + return $this->option['placeholder'] ?? ''; + } + + /** + * Get Description. + * + * @return string Description of the field. + */ + public function get_description(): string { + return $this->option['description'] ?? ''; + } + + /** + * Get Value. + * + * @return mixed Value stored in database. + */ + protected function get_value() { + return Settings::get_option( $this->controllable_option_name, $this->type ); + } + + /** + * Get the option payload. + * + * @return array + */ + public function get_option(): array { + return $this->option; + } + + /** + * Show description if not empty. + */ + protected function maybe_show_description(): void { + if ( ! empty( $this->get_description() ) ) { + printf( + '

%s

', + wp_kses_post( $this->get_description() ) + ); + } + } + + /** + * Get HTML for field. + * + * @return void + */ + abstract public function render(): void; +} diff --git a/src/Admin/Fields/Inline.php b/src/Admin/Fields/Inline.php new file mode 100644 index 00000000..fbc245c9 --- /dev/null +++ b/src/Admin/Fields/Inline.php @@ -0,0 +1,45 @@ +option['input'] instanceof Field ) { + echo ''; + + return; + } + $inject_field_object = $this->option['input']; + $inject_markup = $inject_field_object->get_injectable_markup(); + $label_with_inline_field = sprintf( + $this->get_label(), + '' . $inject_markup . sprintf( + '