diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 6b5015a456..de1ff92c89 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -33,12 +33,6 @@ jobs:
strategy:
matrix:
image:
- - "php7.1-phpunit4.8-wordpress5.3"
- - "php7.2-phpunit4.8-wordpress5.4"
- - "php7.3-phpunit7.5-wordpress5.5"
- - "php7.3-phpunit7.5-wordpress5.6"
- - "php7.3-phpunit7.5-wordpress5.7"
- - "php7.3-phpunit7.5-wordpress5.8"
- "php7.4-phpunit7.5-wordpress5.9"
- "php8.0-phpunit7.5woo-wordpress5.6"
phpunit-xml:
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
index 550c1a6660..ae488067b2 100644
--- a/phpcs.xml.dist
+++ b/phpcs.xml.dist
@@ -96,11 +96,11 @@
'; printf( _n( @@ -200,7 +204,7 @@ protected function check_pastdue_actions() { ); echo '
' . $action->get_hook() . '
';
if ( 1 == $notification['success'] ) {
$class = 'updated';
switch ( $notification['row_action_type'] ) {
- case 'run':
+ case 'run' :
/* translators: %s: action HTML */
$action_message_html = sprintf( __( 'Successfully executed action: %s', 'action-scheduler' ), $action_hook_html );
break;
- case 'cancel':
+ case 'cancel' :
/* translators: %s: action HTML */
$action_message_html = sprintf( __( 'Successfully canceled action: %s', 'action-scheduler' ), $action_hook_html );
break;
- default:
+ default :
/* translators: %s: action HTML */
$action_message_html = sprintf( __( 'Successfully processed change for action: %s', 'action-scheduler' ), $action_hook_html );
break;
@@ -498,7 +497,7 @@ protected function get_schedule_display_string( ActionScheduler_Schedule $schedu
* Deletes actions based on their ID. This is the handler for the bulk delete. It assumes the data
* properly validated by the callee and it will delete the actions without any extra validation.
*
- * @param array $ids
+ * @param array $ids
* @param string $ids_sql Inherited and unused
*/
protected function bulk_delete( array $ids, $ids_sql ) {
@@ -548,23 +547,23 @@ protected function recreate_tables() {
/**
* Implements the logic behind processing an action once an action link is clicked on the list table.
*
- * @param int $action_id
+ * @param int $action_id
* @param string $row_action_type The type of action to perform on the action.
*/
protected function process_row_action( $action_id, $row_action_type ) {
try {
switch ( $row_action_type ) {
- case 'run':
+ case 'run' :
$this->runner->process_action( $action_id, 'Admin List Table' );
break;
- case 'cancel':
+ case 'cancel' :
$this->store->cancel_action( $action_id );
break;
}
- $success = 1;
+ $success = 1;
$error_message = '';
} catch ( Exception $e ) {
- $success = 0;
+ $success = 0;
$error_message = $e->getMessage();
}
@@ -627,13 +626,11 @@ public function prepare_items() {
);
}
- $this->set_pagination_args(
- array(
- 'total_items' => $total_items,
- 'per_page' => $per_page,
- 'total_pages' => ceil( $total_items / $per_page ),
- )
- );
+ $this->set_pagination_args( array(
+ 'total_items' => $total_items,
+ 'per_page' => $per_page,
+ 'total_pages' => ceil( $total_items / $per_page ),
+ ) );
}
/**
diff --git a/src/libraries/action-scheduler/classes/ActionScheduler_LogEntry.php b/src/libraries/action-scheduler/classes/ActionScheduler_LogEntry.php
index d958a56159..649636debf 100644
--- a/src/libraries/action-scheduler/classes/ActionScheduler_LogEntry.php
+++ b/src/libraries/action-scheduler/classes/ActionScheduler_LogEntry.php
@@ -8,12 +8,12 @@ class ActionScheduler_LogEntry {
/**
* @var int $action_id
*/
- protected $action_id = '';
+ protected $action_id = '';
/**
* @var string $message
*/
- protected $message = '';
+ protected $message = '';
/**
* @var Datetime $date
@@ -23,8 +23,8 @@ class ActionScheduler_LogEntry {
/**
* Constructor
*
- * @param mixed $action_id Action ID
- * @param string $message Message
+ * @param mixed $action_id Action ID
+ * @param string $message Message
* @param Datetime $date Datetime object with the time when this log entry was created. If this parameter is
* not provided a new Datetime object (with current time) will be created.
*/
@@ -44,7 +44,7 @@ public function __construct( $action_id, $message, $date = null ) {
$this->action_id = $action_id;
$this->message = $message;
- $this->date = $date ? $date : new Datetime();
+ $this->date = $date ? $date : new Datetime;
}
/**
diff --git a/src/libraries/action-scheduler/classes/ActionScheduler_NullLogEntry.php b/src/libraries/action-scheduler/classes/ActionScheduler_NullLogEntry.php
index b2c8df658c..6f8f218aab 100644
--- a/src/libraries/action-scheduler/classes/ActionScheduler_NullLogEntry.php
+++ b/src/libraries/action-scheduler/classes/ActionScheduler_NullLogEntry.php
@@ -8,4 +8,4 @@ public function __construct( $action_id = '', $message = '' ) {
// nothing to see here
}
}
-
+
\ No newline at end of file
diff --git a/src/libraries/action-scheduler/classes/ActionScheduler_OptionLock.php b/src/libraries/action-scheduler/classes/ActionScheduler_OptionLock.php
index 22b3da88cf..4bc9a3fc26 100644
--- a/src/libraries/action-scheduler/classes/ActionScheduler_OptionLock.php
+++ b/src/libraries/action-scheduler/classes/ActionScheduler_OptionLock.php
@@ -5,7 +5,6 @@
* for up-to a given duration.
*
* Class ActionScheduler_OptionLock
- *
* @since 3.0.0
*/
class ActionScheduler_OptionLock extends ActionScheduler_Lock {
diff --git a/src/libraries/action-scheduler/classes/ActionScheduler_QueueCleaner.php b/src/libraries/action-scheduler/classes/ActionScheduler_QueueCleaner.php
index 3b666d9b47..49cd44bb2a 100644
--- a/src/libraries/action-scheduler/classes/ActionScheduler_QueueCleaner.php
+++ b/src/libraries/action-scheduler/classes/ActionScheduler_QueueCleaner.php
@@ -25,13 +25,13 @@ class ActionScheduler_QueueCleaner {
* @param int $batch_size The batch size.
*/
public function __construct( ActionScheduler_Store $store = null, $batch_size = 20 ) {
- $this->store = $store ? $store : ActionScheduler_Store::instance();
+ $this->store = $store ? $store : ActionScheduler_Store::instance();
$this->batch_size = $batch_size;
}
public function delete_old_actions() {
$lifespan = apply_filters( 'action_scheduler_retention_period', $this->month_in_seconds );
- $cutoff = as_get_datetime_object( $lifespan . ' seconds ago' );
+ $cutoff = as_get_datetime_object($lifespan.' seconds ago');
$statuses_to_purge = array(
ActionScheduler_Store::STATUS_COMPLETE,
@@ -39,15 +39,13 @@ public function delete_old_actions() {
);
foreach ( $statuses_to_purge as $status ) {
- $actions_to_delete = $this->store->query_actions(
- array(
- 'status' => $status,
- 'modified' => $cutoff,
- 'modified_compare' => '<=',
- 'per_page' => $this->get_batch_size(),
- 'orderby' => 'none',
- )
- );
+ $actions_to_delete = $this->store->query_actions( array(
+ 'status' => $status,
+ 'modified' => $cutoff,
+ 'modified_compare' => '<=',
+ 'per_page' => $this->get_batch_size(),
+ 'orderby' => 'none',
+ ) );
foreach ( $actions_to_delete as $action_id ) {
try {
@@ -86,17 +84,15 @@ public function reset_timeouts( $time_limit = 300 ) {
if ( $timeout < 0 ) {
return;
}
- $cutoff = as_get_datetime_object( $timeout . ' seconds ago' );
- $actions_to_reset = $this->store->query_actions(
- array(
- 'status' => ActionScheduler_Store::STATUS_PENDING,
- 'modified' => $cutoff,
- 'modified_compare' => '<=',
- 'claimed' => true,
- 'per_page' => $this->get_batch_size(),
- 'orderby' => 'none',
- )
- );
+ $cutoff = as_get_datetime_object($timeout.' seconds ago');
+ $actions_to_reset = $this->store->query_actions( array(
+ 'status' => ActionScheduler_Store::STATUS_PENDING,
+ 'modified' => $cutoff,
+ 'modified_compare' => '<=',
+ 'claimed' => true,
+ 'per_page' => $this->get_batch_size(),
+ 'orderby' => 'none',
+ ) );
foreach ( $actions_to_reset as $action_id ) {
$this->store->unclaim_action( $action_id );
@@ -118,16 +114,14 @@ public function mark_failures( $time_limit = 300 ) {
if ( $timeout < 0 ) {
return;
}
- $cutoff = as_get_datetime_object( $timeout . ' seconds ago' );
- $actions_to_reset = $this->store->query_actions(
- array(
- 'status' => ActionScheduler_Store::STATUS_RUNNING,
- 'modified' => $cutoff,
- 'modified_compare' => '<=',
- 'per_page' => $this->get_batch_size(),
- 'orderby' => 'none',
- )
- );
+ $cutoff = as_get_datetime_object($timeout.' seconds ago');
+ $actions_to_reset = $this->store->query_actions( array(
+ 'status' => ActionScheduler_Store::STATUS_RUNNING,
+ 'modified' => $cutoff,
+ 'modified_compare' => '<=',
+ 'per_page' => $this->get_batch_size(),
+ 'orderby' => 'none',
+ ) );
foreach ( $actions_to_reset as $action_id ) {
$this->store->mark_failure( $action_id );
diff --git a/src/libraries/action-scheduler/classes/ActionScheduler_QueueRunner.php b/src/libraries/action-scheduler/classes/ActionScheduler_QueueRunner.php
index 38c02c6110..b890dca137 100644
--- a/src/libraries/action-scheduler/classes/ActionScheduler_QueueRunner.php
+++ b/src/libraries/action-scheduler/classes/ActionScheduler_QueueRunner.php
@@ -14,13 +14,16 @@ class ActionScheduler_QueueRunner extends ActionScheduler_Abstract_QueueRunner {
/** @var ActionScheduler_QueueRunner */
private static $runner = null;
+ /** @var int */
+ private $processed_actions_count = 0;
+
/**
* @return ActionScheduler_QueueRunner
* @codeCoverageIgnore
*/
public static function instance() {
- if ( empty( self::$runner ) ) {
- $class = apply_filters( 'action_scheduler_queue_runner_class', 'ActionScheduler_QueueRunner' );
+ if ( empty(self::$runner) ) {
+ $class = apply_filters('action_scheduler_queue_runner_class', 'ActionScheduler_QueueRunner');
self::$runner = new $class();
}
return self::$runner;
@@ -36,7 +39,7 @@ public static function instance() {
public function __construct( ActionScheduler_Store $store = null, ActionScheduler_FatalErrorMonitor $monitor = null, ActionScheduler_QueueCleaner $cleaner = null, ActionScheduler_AsyncRequest_QueueRunner $async_request = null ) {
parent::__construct( $store, $monitor, $cleaner );
- if ( $async_request === null ) {
+ if ( is_null( $async_request ) ) {
$async_request = new ActionScheduler_AsyncRequest_QueueRunner( $this->store );
}
@@ -114,7 +117,6 @@ public function maybe_dispatch_async_request() {
* that was the only context in which this method was run, and the self::WP_CRON_HOOK hook had no context
* passed along with it. New code calling this method directly, or by triggering the self::WP_CRON_HOOK,
* should set a context as the first parameter. For an example of this, refer to the code seen in
- *
* @see ActionScheduler_AsyncRequest_QueueRunner::handle()
*
* @param string $context Optional identifer for the context in which this action is being processed, e.g. 'WP CLI' or 'WP Cron'
@@ -126,17 +128,18 @@ public function run( $context = 'WP Cron' ) {
ActionScheduler_Compatibility::raise_time_limit( $this->get_time_limit() );
do_action( 'action_scheduler_before_process_queue' );
$this->run_cleanup();
- $processed_actions = 0;
+
+ $this->processed_actions_count = 0;
if ( false === $this->has_maximum_concurrent_batches() ) {
$batch_size = apply_filters( 'action_scheduler_queue_runner_batch_size', 25 );
do {
- $processed_actions_in_batch = $this->do_batch( $batch_size, $context );
- $processed_actions += $processed_actions_in_batch;
- } while ( $processed_actions_in_batch > 0 && ! $this->batch_limits_exceeded( $processed_actions ) ); // keep going until we run out of actions, time, or memory
+ $processed_actions_in_batch = $this->do_batch( $batch_size, $context );
+ $this->processed_actions_count += $processed_actions_in_batch;
+ } while ( $processed_actions_in_batch > 0 && ! $this->batch_limits_exceeded( $this->processed_actions_count ) ); // keep going until we run out of actions, time, or memory
}
do_action( 'action_scheduler_after_process_queue' );
- return $processed_actions;
+ return $this->processed_actions_count;
}
/**
@@ -145,14 +148,14 @@ public function run( $context = 'WP Cron' ) {
* Actions are processed by claiming a set of pending actions then processing each one until either the batch
* size is completed, or memory or time limits are reached, defined by @see $this->batch_limits_exceeded().
*
- * @param int $size The maximum number of actions to process in the batch.
+ * @param int $size The maximum number of actions to process in the batch.
* @param string $context Optional identifer for the context in which this action is being processed, e.g. 'WP CLI' or 'WP Cron'
* Generally, this should be capitalised and not localised as it's a proper noun.
* @return int The number of actions processed.
*/
protected function do_batch( $size = 100, $context = '' ) {
- $claim = $this->store->stake_claim( $size );
- $this->monitor->attach( $claim );
+ $claim = $this->store->stake_claim($size);
+ $this->monitor->attach($claim);
$processed_actions = 0;
foreach ( $claim->get_actions() as $action_id ) {
@@ -163,11 +166,11 @@ protected function do_batch( $size = 100, $context = '' ) {
$this->process_action( $action_id, $context );
$processed_actions++;
- if ( $this->batch_limits_exceeded( $processed_actions ) ) {
+ if ( $this->batch_limits_exceeded( $processed_actions + $this->processed_actions_count ) ) {
break;
}
}
- $this->store->release_claim( $claim );
+ $this->store->release_claim($claim);
$this->monitor->detach();
$this->clear_caches();
return $processed_actions;
diff --git a/src/libraries/action-scheduler/classes/ActionScheduler_Versions.php b/src/libraries/action-scheduler/classes/ActionScheduler_Versions.php
index d8e538b1aa..915c2e6329 100644
--- a/src/libraries/action-scheduler/classes/ActionScheduler_Versions.php
+++ b/src/libraries/action-scheduler/classes/ActionScheduler_Versions.php
@@ -7,16 +7,16 @@ class ActionScheduler_Versions {
/**
* @var ActionScheduler_Versions
*/
- private static $instance = null;
+ private static $instance = NULL;
private $versions = array();
public function register( $version_string, $initialization_callback ) {
- if ( isset( $this->versions[ $version_string ] ) ) {
- return false;
+ if ( isset($this->versions[$version_string]) ) {
+ return FALSE;
}
- $this->versions[ $version_string ] = $initialization_callback;
- return true;
+ $this->versions[$version_string] = $initialization_callback;
+ return TRUE;
}
public function get_versions() {
@@ -24,20 +24,20 @@ public function get_versions() {
}
public function latest_version() {
- $keys = array_keys( $this->versions );
- if ( empty( $keys ) ) {
+ $keys = array_keys($this->versions);
+ if ( empty($keys) ) {
return false;
}
uasort( $keys, 'version_compare' );
- return end( $keys );
+ return end($keys);
}
public function latest_version_callback() {
$latest = $this->latest_version();
- if ( empty( $latest ) || ! isset( $this->versions[ $latest ] ) ) {
+ if ( empty($latest) || !isset($this->versions[$latest]) ) {
return '__return_null';
}
- return $this->versions[ $latest ];
+ return $this->versions[$latest];
}
/**
@@ -45,7 +45,7 @@ public function latest_version_callback() {
* @codeCoverageIgnore
*/
public static function instance() {
- if ( empty( self::$instance ) ) {
+ if ( empty(self::$instance) ) {
self::$instance = new self();
}
return self::$instance;
@@ -56,7 +56,7 @@ public static function instance() {
*/
public static function initialize_latest_version() {
$self = self::instance();
- call_user_func( $self->latest_version_callback() );
+ call_user_func($self->latest_version_callback());
}
}
-
+
\ No newline at end of file
diff --git a/src/libraries/action-scheduler/classes/ActionScheduler_WPCommentCleaner.php b/src/libraries/action-scheduler/classes/ActionScheduler_WPCommentCleaner.php
index 498e4f0104..1ba552c50b 100644
--- a/src/libraries/action-scheduler/classes/ActionScheduler_WPCommentCleaner.php
+++ b/src/libraries/action-scheduler/classes/ActionScheduler_WPCommentCleaner.php
@@ -66,13 +66,7 @@ public static function has_logs() {
* Attached to the migration complete hook 'action_scheduler/migration_complete'.
*/
public static function maybe_schedule_cleanup() {
- if ( (bool) get_comments(
- array(
- 'type' => ActionScheduler_wpCommentLogger::TYPE,
- 'number' => 1,
- 'fields' => 'ids',
- )
- ) ) {
+ if ( (bool) get_comments( array( 'type' => ActionScheduler_wpCommentLogger::TYPE, 'number' => 1, 'fields' => 'ids' ) ) ) {
update_option( self::$has_logs_option_key, 'yes' );
if ( ! as_next_scheduled_action( self::$cleanup_hook ) ) {
@@ -86,13 +80,7 @@ public static function maybe_schedule_cleanup() {
*/
public static function delete_all_action_comments() {
global $wpdb;
- $wpdb->delete(
- $wpdb->comments,
- array(
- 'comment_type' => ActionScheduler_wpCommentLogger::TYPE,
- 'comment_agent' => ActionScheduler_wpCommentLogger::AGENT,
- )
- );
+ $wpdb->delete( $wpdb->comments, array( 'comment_type' => ActionScheduler_wpCommentLogger::TYPE, 'comment_agent' => ActionScheduler_wpCommentLogger::AGENT ) );
delete_option( self::$has_logs_option_key );
}
@@ -102,7 +90,7 @@ public static function delete_all_action_comments() {
public static function register_admin_notice() {
add_action( 'admin_notices', array( __CLASS__, 'print_admin_notice' ) );
}
-
+
/**
* Prints details about the orphaned action logs and includes information on where to learn more.
*/
diff --git a/src/libraries/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_QueueRunner.php b/src/libraries/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_QueueRunner.php
index 06a27a8574..c33de68672 100644
--- a/src/libraries/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_QueueRunner.php
+++ b/src/libraries/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_QueueRunner.php
@@ -143,7 +143,7 @@ public function before_execute( $action_id ) {
*
* @author Jeremy Pry
*
- * @param int $action_id
+ * @param int $action_id
* @param null|ActionScheduler_Action $action The instance of the action. Default to null for backward compatibility.
*/
public function after_execute( $action_id, $action = null ) {
diff --git a/src/libraries/action-scheduler/classes/WP_CLI/Migration_Command.php b/src/libraries/action-scheduler/classes/WP_CLI/Migration_Command.php
index 73e2ccc8cf..066697e4e0 100644
--- a/src/libraries/action-scheduler/classes/WP_CLI/Migration_Command.php
+++ b/src/libraries/action-scheduler/classes/WP_CLI/Migration_Command.php
@@ -1,10 +1,12 @@
'Migrates actions to the DB tables store',
- 'synopsis' => array(
- array(
- 'type' => 'assoc',
- 'name' => 'batch-size',
- 'optional' => true,
- 'default' => 100,
- 'description' => 'The number of actions to process in each batch',
- ),
- array(
- 'type' => 'assoc',
- 'name' => 'free-memory-on',
- 'optional' => true,
- 'default' => 50,
- 'description' => 'The number of actions to process between freeing memory. 0 disables freeing memory',
- ),
- array(
- 'type' => 'assoc',
- 'name' => 'pause',
- 'optional' => true,
- 'default' => 0,
- 'description' => 'The number of seconds to pause when freeing memory',
- ),
- array(
- 'type' => 'flag',
- 'name' => 'dry-run',
- 'optional' => true,
- 'description' => 'Reports on the actions that would have been migrated, but does not change any data',
- ),
- ),
- )
- );
+ WP_CLI::add_command( 'action-scheduler migrate', [ $this, 'migrate' ], [
+ 'shortdesc' => 'Migrates actions to the DB tables store',
+ 'synopsis' => [
+ [
+ 'type' => 'assoc',
+ 'name' => 'batch-size',
+ 'optional' => true,
+ 'default' => 100,
+ 'description' => 'The number of actions to process in each batch',
+ ],
+ [
+ 'type' => 'assoc',
+ 'name' => 'free-memory-on',
+ 'optional' => true,
+ 'default' => 50,
+ 'description' => 'The number of actions to process between freeing memory. 0 disables freeing memory',
+ ],
+ [
+ 'type' => 'assoc',
+ 'name' => 'pause',
+ 'optional' => true,
+ 'default' => 0,
+ 'description' => 'The number of seconds to pause when freeing memory',
+ ],
+ [
+ 'type' => 'flag',
+ 'name' => 'dry-run',
+ 'optional' => true,
+ 'description' => 'Reports on the actions that would have been migrated, but does not change any data',
+ ],
+ ],
+ ] );
}
/**
@@ -83,14 +81,14 @@ public function migrate( $positional_args, $assoc_args ) {
$runner = new Runner( $config );
$runner->init_destination();
- $batch_size = isset( $assoc_args['batch-size'] ) ? (int) $assoc_args['batch-size'] : 100;
- $free_on = isset( $assoc_args['free-memory-on'] ) ? (int) $assoc_args['free-memory-on'] : 50;
- $sleep = isset( $assoc_args['pause'] ) ? (int) $assoc_args['pause'] : 0;
+ $batch_size = isset( $assoc_args[ 'batch-size' ] ) ? (int) $assoc_args[ 'batch-size' ] : 100;
+ $free_on = isset( $assoc_args[ 'free-memory-on' ] ) ? (int) $assoc_args[ 'free-memory-on' ] : 50;
+ $sleep = isset( $assoc_args[ 'pause' ] ) ? (int) $assoc_args[ 'pause' ] : 0;
\ActionScheduler_DataController::set_free_ticks( $free_on );
\ActionScheduler_DataController::set_sleep_time( $sleep );
do {
- $actions_processed = $runner->run( $batch_size );
+ $actions_processed = $runner->run( $batch_size );
$this->total_processed += $actions_processed;
} while ( $actions_processed > 0 );
@@ -111,15 +109,12 @@ public function migrate( $positional_args, $assoc_args ) {
* @return ActionScheduler\Migration\Config
*/
private function get_migration_config( $args ) {
- $args = wp_parse_args(
- $args,
- array(
- 'dry-run' => false,
- )
- );
+ $args = wp_parse_args( $args, [
+ 'dry-run' => false,
+ ] );
$config = Controller::instance()->get_migration_config_object();
- $config->set_dry_run( ! empty( $args['dry-run'] ) );
+ $config->set_dry_run( ! empty( $args[ 'dry-run' ] ) );
return $config;
}
@@ -128,61 +123,26 @@ private function get_migration_config( $args ) {
* Hook command line logging into migration actions.
*/
private function init_logging() {
- add_action(
- 'action_scheduler/migrate_action_dry_run',
- function ( $action_id ) {
- WP_CLI::debug( sprintf( 'Dry-run: migrated action %d', $action_id ) );
- },
- 10,
- 1
- );
- add_action(
- 'action_scheduler/no_action_to_migrate',
- function ( $action_id ) {
- WP_CLI::debug( sprintf( 'No action found to migrate for ID %d', $action_id ) );
- },
- 10,
- 1
- );
- add_action(
- 'action_scheduler/migrate_action_failed',
- function ( $action_id ) {
- WP_CLI::warning( sprintf( 'Failed migrating action with ID %d', $action_id ) );
- },
- 10,
- 1
- );
- add_action(
- 'action_scheduler/migrate_action_incomplete',
- function ( $source_id, $destination_id ) {
- WP_CLI::warning( sprintf( 'Unable to remove source action with ID %d after migrating to new ID %d', $source_id, $destination_id ) );
- },
- 10,
- 2
- );
- add_action(
- 'action_scheduler/migrated_action',
- function ( $source_id, $destination_id ) {
- WP_CLI::debug( sprintf( 'Migrated source action with ID %d to new store with ID %d', $source_id, $destination_id ) );
- },
- 10,
- 2
- );
- add_action(
- 'action_scheduler/migration_batch_starting',
- function ( $batch ) {
- WP_CLI::debug( 'Beginning migration of batch: ' . print_r( $batch, true ) );
- },
- 10,
- 1
- );
- add_action(
- 'action_scheduler/migration_batch_complete',
- function ( $batch ) {
- WP_CLI::log( sprintf( 'Completed migration of %d actions', count( $batch ) ) );
- },
- 10,
- 1
- );
+ add_action( 'action_scheduler/migrate_action_dry_run', function ( $action_id ) {
+ WP_CLI::debug( sprintf( 'Dry-run: migrated action %d', $action_id ) );
+ }, 10, 1 );
+ add_action( 'action_scheduler/no_action_to_migrate', function ( $action_id ) {
+ WP_CLI::debug( sprintf( 'No action found to migrate for ID %d', $action_id ) );
+ }, 10, 1 );
+ add_action( 'action_scheduler/migrate_action_failed', function ( $action_id ) {
+ WP_CLI::warning( sprintf( 'Failed migrating action with ID %d', $action_id ) );
+ }, 10, 1 );
+ add_action( 'action_scheduler/migrate_action_incomplete', function ( $source_id, $destination_id ) {
+ WP_CLI::warning( sprintf( 'Unable to remove source action with ID %d after migrating to new ID %d', $source_id, $destination_id ) );
+ }, 10, 2 );
+ add_action( 'action_scheduler/migrated_action', function ( $source_id, $destination_id ) {
+ WP_CLI::debug( sprintf( 'Migrated source action with ID %d to new store with ID %d', $source_id, $destination_id ) );
+ }, 10, 2 );
+ add_action( 'action_scheduler/migration_batch_starting', function ( $batch ) {
+ WP_CLI::debug( 'Beginning migration of batch: ' . print_r( $batch, true ) );
+ }, 10, 1 );
+ add_action( 'action_scheduler/migration_batch_complete', function ( $batch ) {
+ WP_CLI::log( sprintf( 'Completed migration of %d actions', count( $batch ) ) );
+ }, 10, 1 );
}
}
diff --git a/src/libraries/action-scheduler/classes/WP_CLI/ProgressBar.php b/src/libraries/action-scheduler/classes/WP_CLI/ProgressBar.php
index b801d2b8f2..c86c74e838 100644
--- a/src/libraries/action-scheduler/classes/WP_CLI/ProgressBar.php
+++ b/src/libraries/action-scheduler/classes/WP_CLI/ProgressBar.php
@@ -38,7 +38,7 @@ class ProgressBar {
* @param string $message Text to display before the progress bar.
* @param integer $count Total number of ticks to be performed.
* @param integer $interval Optional. The interval in milliseconds between updates. Default 100.
- *
+ *
* @throws Exception When this is not run within WP CLI
*/
public function __construct( $message, $count, $interval = 100 ) {
diff --git a/src/libraries/action-scheduler/classes/abstracts/ActionScheduler.php b/src/libraries/action-scheduler/classes/abstracts/ActionScheduler.php
index 4558e5a797..e8873f11e9 100644
--- a/src/libraries/action-scheduler/classes/abstracts/ActionScheduler.php
+++ b/src/libraries/action-scheduler/classes/abstracts/ActionScheduler.php
@@ -1,22 +1,21 @@
date_create( 'now', timezone_open( 'UTC' ) )->format( 'Y-m-d H:i:s' ),
'date_compare' => '<',
'per_page' => 1,
- 'offset' => $consistent_failure_threshold - 1,
+ 'offset' => $consistent_failure_threshold - 1
);
$first_failing_action_id = $this->store->query_actions( $query_args );
@@ -223,9 +223,14 @@ protected function get_execution_time() {
* @return bool
*/
protected function time_likely_to_be_exceeded( $processed_actions ) {
+ $execution_time = $this->get_execution_time();
+ $max_execution_time = $this->get_time_limit();
+
+ // Safety against division by zero errors.
+ if ( 0 === $processed_actions ) {
+ return $execution_time >= $max_execution_time;
+ }
- $execution_time = $this->get_execution_time();
- $max_execution_time = $this->get_time_limit();
$time_per_action = $execution_time / $processed_actions;
$estimated_time = $execution_time + ( $time_per_action * 3 );
$likely_to_be_exceeded = $estimated_time > $max_execution_time;
diff --git a/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Abstract_RecurringSchedule.php b/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Abstract_RecurringSchedule.php
index 430d91afa2..131d4757d8 100644
--- a/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Abstract_RecurringSchedule.php
+++ b/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Abstract_RecurringSchedule.php
@@ -15,14 +15,14 @@ abstract class ActionScheduler_Abstract_RecurringSchedule extends ActionSchedule
*
* @var DateTime
*/
- private $first_date = null;
+ private $first_date = NULL;
/**
* Timestamp equivalent of @see $this->first_date
*
* @var int
*/
- protected $first_timestamp = null;
+ protected $first_timestamp = NULL;
/**
* The recurrance between each time an action is run using this schedule.
@@ -35,8 +35,8 @@ abstract class ActionScheduler_Abstract_RecurringSchedule extends ActionSchedule
protected $recurrence;
/**
- * @param DateTime $date The date & time to run the action.
- * @param mixed $recurrence The data used to determine the schedule's recurrance.
+ * @param DateTime $date The date & time to run the action.
+ * @param mixed $recurrence The data used to determine the schedule's recurrance.
* @param DateTime|null $first (Optional) The date & time the first instance of this interval schedule ran. Default null, meaning this is the first instance.
*/
public function __construct( DateTime $date, $recurrence, DateTime $first = null ) {
@@ -70,19 +70,15 @@ public function get_recurrence() {
/**
* For PHP 5.2 compat, since DateTime objects can't be serialized
- *
* @return array
*/
public function __sleep() {
- $sleep_params = parent::__sleep();
+ $sleep_params = parent::__sleep();
$this->first_timestamp = $this->first_date->getTimestamp();
- return array_merge(
- $sleep_params,
- array(
- 'first_timestamp',
- 'recurrence',
- )
- );
+ return array_merge( $sleep_params, array(
+ 'first_timestamp',
+ 'recurrence'
+ ) );
}
/**
diff --git a/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schedule.php b/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schedule.php
index 369249f6b8..2631ef554f 100644
--- a/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schedule.php
+++ b/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schedule.php
@@ -10,14 +10,14 @@ abstract class ActionScheduler_Abstract_Schedule extends ActionScheduler_Schedul
*
* @var DateTime
*/
- private $scheduled_date = null;
+ private $scheduled_date = NULL;
/**
* Timestamp equivalent of @see $this->scheduled_date
*
* @var int
*/
- protected $scheduled_timestamp = null;
+ protected $scheduled_timestamp = NULL;
/**
* @param DateTime $date The date & time to run the action.
@@ -67,7 +67,6 @@ public function get_date() {
/**
* For PHP 5.2 compat, since DateTime objects can't be serialized
- *
* @return array
*/
public function __sleep() {
diff --git a/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schema.php b/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schema.php
index bf0ee92448..2334fda10e 100644
--- a/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schema.php
+++ b/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schema.php
@@ -1,5 +1,6 @@
get_table_definition( $table );
if ( $definition ) {
$updated = dbDelta( $definition );
@@ -147,7 +148,7 @@ private function update_table( $table ) {
* table prefix for the current blog
*/
protected function get_full_table_name( $table ) {
- return $GLOBALS['wpdb']->prefix . $table;
+ return $GLOBALS[ 'wpdb' ]->prefix . $table;
}
/**
diff --git a/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Lock.php b/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Lock.php
index e8e218021a..86e8528512 100644
--- a/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Lock.php
+++ b/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Lock.php
@@ -8,7 +8,7 @@
abstract class ActionScheduler_Lock {
/** @var ActionScheduler_Lock */
- private static $locker = null;
+ private static $locker = NULL;
/** @var int */
protected static $lock_duration = MINUTE_IN_SECONDS;
@@ -54,7 +54,7 @@ protected function get_duration( $lock_type ) {
*/
public static function instance() {
if ( empty( self::$locker ) ) {
- $class = apply_filters( 'action_scheduler_lock_class', 'ActionScheduler_OptionLock' );
+ $class = apply_filters( 'action_scheduler_lock_class', 'ActionScheduler_OptionLock' );
self::$locker = new $class();
}
return self::$locker;
diff --git a/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Logger.php b/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Logger.php
index 5dbd436467..c3afd04b63 100644
--- a/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Logger.php
+++ b/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Logger.php
@@ -2,31 +2,30 @@
/**
* Class ActionScheduler_Logger
- *
* @codeCoverageIgnore
*/
abstract class ActionScheduler_Logger {
- private static $logger = null;
+ private static $logger = NULL;
/**
* @return ActionScheduler_Logger
*/
public static function instance() {
- if ( empty( self::$logger ) ) {
- $class = apply_filters( 'action_scheduler_logger_class', 'ActionScheduler_wpCommentLogger' );
+ if ( empty(self::$logger) ) {
+ $class = apply_filters('action_scheduler_logger_class', 'ActionScheduler_wpCommentLogger');
self::$logger = new $class();
}
return self::$logger;
}
/**
- * @param string $action_id
- * @param string $message
+ * @param string $action_id
+ * @param string $message
* @param DateTime $date
*
* @return string The log entry ID
*/
- abstract public function log( $action_id, $message, DateTime $date = null );
+ abstract public function log( $action_id, $message, DateTime $date = NULL );
/**
* @param string $entry_id
@@ -42,6 +41,7 @@ abstract public function get_entry( $entry_id );
*/
abstract public function get_logs( $action_id );
+
/**
* @codeCoverageIgnore
*/
@@ -86,7 +86,7 @@ public function log_started_action( $action_id, $context = '' ) {
$this->log( $action_id, $message );
}
- public function log_completed_action( $action_id, $action = null, $context = '' ) {
+ public function log_completed_action( $action_id, $action = NULL, $context = '' ) {
if ( ! empty( $context ) ) {
/* translators: %s: context */
$message = sprintf( __( 'action complete via %s', 'action-scheduler' ), $context );
@@ -134,14 +134,14 @@ public function log_ignored_action( $action_id, $context = '' ) {
}
/**
- * @param string $action_id
+ * @param string $action_id
* @param Exception|NULL $exception The exception which occured when fetching the action. NULL by default for backward compatibility.
*
* @return ActionScheduler_LogEntry[]
*/
- public function log_failed_fetch_action( $action_id, Exception $exception = null ) {
+ public function log_failed_fetch_action( $action_id, Exception $exception = NULL ) {
- if ( $exception !== null ) {
+ if ( ! is_null( $exception ) ) {
/* translators: %s: exception message */
$log_message = sprintf( __( 'There was a failure fetching this action: %s', 'action-scheduler' ), $exception->getMessage() );
} else {
diff --git a/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Store.php b/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Store.php
index b00ad07218..a555293325 100644
--- a/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Store.php
+++ b/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_Store.php
@@ -2,7 +2,6 @@
/**
* Class ActionScheduler_Store
- *
* @codeCoverageIgnore
*/
abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
@@ -14,20 +13,20 @@ abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
const DEFAULT_CLASS = 'ActionScheduler_wpPostStore';
/** @var ActionScheduler_Store */
- private static $store = null;
+ private static $store = NULL;
/** @var int */
protected static $max_args_length = 191;
/**
* @param ActionScheduler_Action $action
- * @param DateTime $scheduled_date Optional Date of the first instance
- * to store. Otherwise uses the first date of the action's
- * schedule.
+ * @param DateTime $scheduled_date Optional Date of the first instance
+ * to store. Otherwise uses the first date of the action's
+ * schedule.
*
* @return int The action ID
*/
- abstract public function save_action( ActionScheduler_Action $action, DateTime $scheduled_date = null );
+ abstract public function save_action( ActionScheduler_Action $action, DateTime $scheduled_date = NULL );
/**
* @param string $action_id
@@ -142,13 +141,10 @@ abstract public function action_counts();
public function extra_action_counts() {
$extra_actions = array();
- $pastdue_action_counts = (int) $this->query_actions(
- array(
- 'status' => self::STATUS_PENDING,
- 'date' => as_get_datetime_object(),
- ),
- 'count'
- );
+ $pastdue_action_counts = ( int ) $this->query_actions( array(
+ 'status' => self::STATUS_PENDING,
+ 'date' => as_get_datetime_object(),
+ ), 'count' );
if ( $pastdue_action_counts ) {
$extra_actions['past-due'] = $pastdue_action_counts;
@@ -180,6 +176,7 @@ abstract public function delete_action( $action_id );
*/
abstract public function get_date( $action_id );
+
/**
* @param int $max_actions
* @param DateTime $before_date Claim only actions schedule before the given date. Defaults to now.
@@ -244,7 +241,7 @@ abstract public function find_actions_by_claim_id( $claim_id );
* @return string
*/
protected function validate_sql_comparator( $comparison_operator ) {
- if ( in_array( $comparison_operator, array( '!=', '>', '>=', '<', '<=', '=' ) ) ) {
+ if ( in_array( $comparison_operator, array('!=', '>', '>=', '<', '<=', '=') ) ) {
return $comparison_operator;
}
return '=';
@@ -254,13 +251,13 @@ protected function validate_sql_comparator( $comparison_operator ) {
* Get the time MySQL formated date/time string for an action's (next) scheduled date.
*
* @param ActionScheduler_Action $action
- * @param DateTime $scheduled_date (optional)
+ * @param DateTime $scheduled_date (optional)
* @return string
*/
- protected function get_scheduled_date_string( ActionScheduler_Action $action, DateTime $scheduled_date = null ) {
+ protected function get_scheduled_date_string( ActionScheduler_Action $action, DateTime $scheduled_date = NULL ) {
$next = null === $scheduled_date ? $action->get_schedule()->get_date() : $scheduled_date;
if ( ! $next ) {
- return '0000-00-00 00:00:00';
+ $next = date_create();
}
$next->setTimezone( new DateTimeZone( 'UTC' ) );
@@ -271,13 +268,13 @@ protected function get_scheduled_date_string( ActionScheduler_Action $action, Da
* Get the time MySQL formated date/time string for an action's (next) scheduled date.
*
* @param ActionScheduler_Action $action
- * @param DateTime $scheduled_date (optional)
+ * @param DateTime $scheduled_date (optional)
* @return string
*/
- protected function get_scheduled_date_string_local( ActionScheduler_Action $action, DateTime $scheduled_date = null ) {
+ protected function get_scheduled_date_string_local( ActionScheduler_Action $action, DateTime $scheduled_date = NULL ) {
$next = null === $scheduled_date ? $action->get_schedule()->get_date() : $scheduled_date;
if ( ! $next ) {
- return '0000-00-00 00:00:00';
+ $next = date_create();
}
ActionScheduler_TimezoneHelper::set_local_timezone( $next );
@@ -417,17 +414,15 @@ public function get_status_labels() {
* Check if there are any pending scheduled actions due to run.
*
* @param ActionScheduler_Action $action
- * @param DateTime $scheduled_date (optional)
+ * @param DateTime $scheduled_date (optional)
* @return string
*/
public function has_pending_actions_due() {
- $pending_actions = $this->query_actions(
- array(
- 'date' => as_get_datetime_object(),
- 'status' => self::STATUS_PENDING,
- 'orderby' => 'none',
- )
- );
+ $pending_actions = $this->query_actions( array(
+ 'date' => as_get_datetime_object(),
+ 'status' => ActionScheduler_Store::STATUS_PENDING,
+ 'orderby' => 'none',
+ ) );
return ! empty( $pending_actions );
}
@@ -447,7 +442,7 @@ public function mark_migrated( $action_id ) {}
*/
public static function instance() {
if ( empty( self::$store ) ) {
- $class = apply_filters( 'action_scheduler_store_class', self::DEFAULT_CLASS );
+ $class = apply_filters( 'action_scheduler_store_class', self::DEFAULT_CLASS );
self::$store = new $class();
}
return self::$store;
diff --git a/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_TimezoneHelper.php b/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_TimezoneHelper.php
index 73f0000dfe..fd01449412 100644
--- a/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_TimezoneHelper.php
+++ b/src/libraries/action-scheduler/classes/abstracts/ActionScheduler_TimezoneHelper.php
@@ -4,7 +4,7 @@
* Class ActionScheduler_TimezoneHelper
*/
abstract class ActionScheduler_TimezoneHelper {
- private static $local_timezone = null;
+ private static $local_timezone = NULL;
/**
* Set a DateTime's timezone to the WordPress site's timezone, or a UTC offset
@@ -99,21 +99,21 @@ protected static function get_local_timezone_offset() {
/**
* @deprecated 2.1.0
*/
- public static function get_local_timezone( $reset = false ) {
+ public static function get_local_timezone( $reset = FALSE ) {
_deprecated_function( __FUNCTION__, '2.1.0', 'ActionScheduler_TimezoneHelper::set_local_timezone()' );
if ( $reset ) {
- self::$local_timezone = null;
+ self::$local_timezone = NULL;
}
- if ( ! isset( self::$local_timezone ) ) {
- $tzstring = get_option( 'timezone_string' );
+ if ( !isset(self::$local_timezone) ) {
+ $tzstring = get_option('timezone_string');
- if ( empty( $tzstring ) ) {
- $gmt_offset = get_option( 'gmt_offset' );
+ if ( empty($tzstring) ) {
+ $gmt_offset = get_option('gmt_offset');
if ( $gmt_offset == 0 ) {
$tzstring = 'UTC';
} else {
$gmt_offset *= HOUR_IN_SECONDS;
- $tzstring = timezone_name_from_abbr( '', $gmt_offset, 1 );
+ $tzstring = timezone_name_from_abbr( '', $gmt_offset, 1 );
// If there's no timezone string, try again with no DST.
if ( false === $tzstring ) {
@@ -145,7 +145,7 @@ public static function get_local_timezone( $reset = false ) {
}
}
- self::$local_timezone = new DateTimeZone( $tzstring );
+ self::$local_timezone = new DateTimeZone($tzstring);
}
return self::$local_timezone;
}
diff --git a/src/libraries/action-scheduler/classes/actions/ActionScheduler_Action.php b/src/libraries/action-scheduler/classes/actions/ActionScheduler_Action.php
index 0e7e201b59..f538f506b5 100644
--- a/src/libraries/action-scheduler/classes/actions/ActionScheduler_Action.php
+++ b/src/libraries/action-scheduler/classes/actions/ActionScheduler_Action.php
@@ -7,15 +7,15 @@ class ActionScheduler_Action {
protected $hook = '';
protected $args = array();
/** @var ActionScheduler_Schedule */
- protected $schedule = null;
- protected $group = '';
+ protected $schedule = NULL;
+ protected $group = '';
- public function __construct( $hook, array $args = array(), ActionScheduler_Schedule $schedule = null, $group = '' ) {
+ public function __construct( $hook, array $args = array(), ActionScheduler_Schedule $schedule = NULL, $group = '' ) {
$schedule = empty( $schedule ) ? new ActionScheduler_NullSchedule() : $schedule;
- $this->set_hook( $hook );
- $this->set_schedule( $schedule );
- $this->set_args( $args );
- $this->set_group( $group );
+ $this->set_hook($hook);
+ $this->set_schedule($schedule);
+ $this->set_args($args);
+ $this->set_group($group);
}
/**
@@ -91,6 +91,6 @@ public function get_group() {
* @return bool If the action has been finished
*/
public function is_finished() {
- return false;
+ return FALSE;
}
}
diff --git a/src/libraries/action-scheduler/classes/actions/ActionScheduler_CanceledAction.php b/src/libraries/action-scheduler/classes/actions/ActionScheduler_CanceledAction.php
index 81510ddcc5..8bbc5d18d5 100644
--- a/src/libraries/action-scheduler/classes/actions/ActionScheduler_CanceledAction.php
+++ b/src/libraries/action-scheduler/classes/actions/ActionScheduler_CanceledAction.php
@@ -9,14 +9,14 @@
class ActionScheduler_CanceledAction extends ActionScheduler_FinishedAction {
/**
- * @param string $hook
- * @param array $args
+ * @param string $hook
+ * @param array $args
* @param ActionScheduler_Schedule $schedule
- * @param string $group
+ * @param string $group
*/
public function __construct( $hook, array $args = array(), ActionScheduler_Schedule $schedule = null, $group = '' ) {
parent::__construct( $hook, $args, $schedule, $group );
- if ( $schedule === null ) {
+ if ( is_null( $schedule ) ) {
$this->set_schedule( new ActionScheduler_NullSchedule() );
}
}
diff --git a/src/libraries/action-scheduler/classes/actions/ActionScheduler_FinishedAction.php b/src/libraries/action-scheduler/classes/actions/ActionScheduler_FinishedAction.php
index 7895dc0c36..b23a56c66b 100644
--- a/src/libraries/action-scheduler/classes/actions/ActionScheduler_FinishedAction.php
+++ b/src/libraries/action-scheduler/classes/actions/ActionScheduler_FinishedAction.php
@@ -10,7 +10,7 @@ public function execute() {
}
public function is_finished() {
- return true;
+ return TRUE;
}
}
-
+
\ No newline at end of file
diff --git a/src/libraries/action-scheduler/classes/actions/ActionScheduler_NullAction.php b/src/libraries/action-scheduler/classes/actions/ActionScheduler_NullAction.php
index f70c08dc4b..cd5dc3b0f9 100644
--- a/src/libraries/action-scheduler/classes/actions/ActionScheduler_NullAction.php
+++ b/src/libraries/action-scheduler/classes/actions/ActionScheduler_NullAction.php
@@ -5,7 +5,7 @@
*/
class ActionScheduler_NullAction extends ActionScheduler_Action {
- public function __construct( $hook = '', array $args = array(), ActionScheduler_Schedule $schedule = null ) {
+ public function __construct( $hook = '', array $args = array(), ActionScheduler_Schedule $schedule = NULL ) {
$this->set_schedule( new ActionScheduler_NullSchedule() );
}
@@ -13,4 +13,4 @@ public function execute() {
// don't execute
}
}
-
+
\ No newline at end of file
diff --git a/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_DBLogger.php b/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_DBLogger.php
index 31e6efd28b..37bfd0d44e 100644
--- a/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_DBLogger.php
+++ b/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_DBLogger.php
@@ -72,7 +72,7 @@ private function create_entry_from_db_record( $record ) {
return new ActionScheduler_NullLogEntry();
}
- if ( $record->log_date_gmt === null ) {
+ if ( is_null( $record->log_date_gmt ) ) {
$date = as_get_datetime_object( ActionScheduler_StoreSchema::DEFAULT_DATE );
} else {
$date = as_get_datetime_object( $record->log_date_gmt );
diff --git a/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php b/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php
index 5c0dd0b363..5009454f74 100644
--- a/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php
+++ b/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php
@@ -139,7 +139,7 @@ private function build_insert_sql( array $data, $unique ) {
$placeholder_sql = implode( ', ', $placeholders );
$where_clause = $this->build_where_clause_for_insert( $data, $table_name, $unique );
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $column_sql and $where_clause are already prepared. $placeholder_sql is hardcoded.
- $insert_query = $wpdb->prepare(
+ $insert_query = $wpdb->prepare(
"
INSERT INTO $table_name ( $column_sql )
SELECT $placeholder_sql FROM DUAL
@@ -310,7 +310,7 @@ public function fetch_action( $action_id ) {
'last_attempt_gmt',
);
foreach ( $date_fields as $date_field ) {
- if ( $data->$date_field === null ) {
+ if ( is_null( $data->$date_field ) ) {
$data->$date_field = ActionScheduler_StoreSchema::DEFAULT_DATE;
}
}
@@ -375,25 +375,22 @@ protected function get_query_actions_sql( array $query, $select_or_count = 'sele
throw new InvalidArgumentException( __( 'Invalid value for select or count parameter. Cannot query actions.', 'action-scheduler' ) );
}
- $query = wp_parse_args(
- $query,
- array(
- 'hook' => '',
- 'args' => null,
- 'partial_args_matching' => 'off', // can be 'like' or 'json'
- 'date' => null,
- 'date_compare' => '<=',
- 'modified' => null,
- 'modified_compare' => '<=',
- 'group' => '',
- 'status' => '',
- 'claimed' => null,
- 'per_page' => 5,
- 'offset' => 0,
- 'orderby' => 'date',
- 'order' => 'ASC',
- )
- );
+ $query = wp_parse_args( $query, array(
+ 'hook' => '',
+ 'args' => null,
+ 'partial_args_matching' => 'off', // can be 'like' or 'json'
+ 'date' => null,
+ 'date_compare' => '<=',
+ 'modified' => null,
+ 'modified_compare' => '<=',
+ 'group' => '',
+ 'status' => '',
+ 'claimed' => null,
+ 'per_page' => 5,
+ 'offset' => 0,
+ 'orderby' => 'date',
+ 'order' => 'ASC',
+ ) );
/** @var \wpdb $wpdb */
global $wpdb;
@@ -410,26 +407,26 @@ protected function get_query_actions_sql( array $query, $select_or_count = 'sele
}
$sql = ( 'count' === $select_or_count ) ? 'SELECT count(a.action_id)' : 'SELECT a.action_id';
- $sql .= " FROM {$wpdb->actionscheduler_actions} a";
+ $sql .= " FROM {$wpdb->actionscheduler_actions} a";
$sql_params = array();
if ( ! empty( $query['group'] ) || 'group' === $query['orderby'] ) {
$sql .= " LEFT JOIN {$wpdb->actionscheduler_groups} g ON g.group_id=a.group_id";
}
- $sql .= ' WHERE 1=1';
+ $sql .= " WHERE 1=1";
if ( ! empty( $query['group'] ) ) {
- $sql .= ' AND g.slug=%s';
+ $sql .= " AND g.slug=%s";
$sql_params[] = $query['group'];
}
if ( ! empty( $query['hook'] ) ) {
- $sql .= ' AND a.hook=%s';
+ $sql .= " AND a.hook=%s";
$sql_params[] = $query['hook'];
}
- if ( $query['args'] !== null ) {
+ if ( ! is_null( $query['args'] ) ) {
switch ( $query['partial_args_matching'] ) {
case 'json':
if ( ! $supports_json ) {
@@ -448,28 +445,26 @@ protected function get_query_actions_sql( array $query, $select_or_count = 'sele
}
$placeholder = isset( $supported_types[ $value_type ] ) ? $supported_types[ $value_type ] : false;
if ( ! $placeholder ) {
- throw new \RuntimeException(
- sprintf(
+ throw new \RuntimeException( sprintf(
/* translators: %s: provided value type */
- __( 'The value type for the JSON partial matching is not supported. Must be either integer, boolean, double or string. %s type provided.', 'action-scheduler' ),
- $value_type
- )
- );
+ __( 'The value type for the JSON partial matching is not supported. Must be either integer, boolean, double or string. %s type provided.', 'action-scheduler' ),
+ $value_type
+ ) );
}
- $sql .= ' AND JSON_EXTRACT(a.args, %s)=' . $placeholder;
- $sql_params[] = '$.' . $key;
+ $sql .= ' AND JSON_EXTRACT(a.args, %s)='.$placeholder;
+ $sql_params[] = '$.'.$key;
$sql_params[] = $value;
}
break;
case 'like':
foreach ( $query['args'] as $key => $value ) {
- $sql .= ' AND a.args LIKE %s';
+ $sql .= ' AND a.args LIKE %s';
$json_partial = $wpdb->esc_like( trim( json_encode( array( $key => $value ) ), '{}' ) );
$sql_params[] = "%{$json_partial}%";
}
break;
case 'off':
- $sql .= ' AND a.args=%s';
+ $sql .= " AND a.args=%s";
$sql_params[] = $this->get_args_for_query( $query['args'] );
break;
default:
@@ -506,7 +501,7 @@ protected function get_query_actions_sql( array $query, $select_or_count = 'sele
$sql .= ' AND a.claim_id != 0';
} elseif ( false === $query['claimed'] ) {
$sql .= ' AND a.claim_id = 0';
- } elseif ( $query['claimed'] !== null ) {
+ } elseif ( ! is_null( $query['claimed'] ) ) {
$sql .= ' AND a.claim_id = %d';
$sql_params[] = $query['claimed'];
}
@@ -819,7 +814,7 @@ protected function claim_actions( $claim_id, $limit, \DateTime $before_date = nu
global $wpdb;
$now = as_get_datetime_object();
- $date = $before_date === null ? $now : clone $before_date;
+ $date = is_null( $before_date ) ? $now : clone $before_date;
// can't use $wpdb->update() because of the <= condition.
$update = "UPDATE {$wpdb->actionscheduler_actions} SET claim_id=%d, last_attempt_gmt=%s, last_attempt_local=%s";
@@ -835,7 +830,7 @@ protected function claim_actions( $claim_id, $limit, \DateTime $before_date = nu
if ( ! empty( $hooks ) ) {
$placeholders = array_fill( 0, count( $hooks ), '%s' );
- $where .= ' AND hook IN (' . join( ', ', $placeholders ) . ')';
+ $where .= ' AND hook IN (' . join( ', ', $placeholders ) . ')';
$params = array_merge( $params, array_values( $hooks ) );
}
@@ -849,7 +844,7 @@ protected function claim_actions( $claim_id, $limit, \DateTime $before_date = nu
throw new InvalidArgumentException( sprintf( __( 'The group "%s" does not exist.', 'action-scheduler' ), $group ) );
}
- $where .= ' AND group_id = %d';
+ $where .= ' AND group_id = %d';
$params[] = $group_id;
}
@@ -940,8 +935,31 @@ public function find_actions_by_claim_id( $claim_id ) {
public function release_claim( ActionScheduler_ActionClaim $claim ) {
/** @var \wpdb $wpdb */
global $wpdb;
- $wpdb->update( $wpdb->actionscheduler_actions, array( 'claim_id' => 0 ), array( 'claim_id' => $claim->get_id() ), array( '%d' ), array( '%d' ) );
+ /**
+ * Deadlock warning: This function modifies actions to release them from claims that have been processed. Earlier, we used to it in a atomic query, i.e. we would update all actions belonging to a particular claim_id with claim_id = 0.
+ * While this was functionally correct, it would cause deadlock, since this update query will hold a lock on the claim_id_.. index on the action table.
+ * This allowed the possibility of a race condition, where the claimer query is also running at the same time, then the claimer query will also try to acquire a lock on the claim_id_.. index, and in this case if claim release query has already progressed to the point of acquiring the lock, but have not updated yet, it would cause a deadlock.
+ *
+ * We resolve this by getting all the actions_id that we want to release claim from in a separate query, and then releasing the claim on each of them. This way, our lock is acquired on the action_id index instead of the claim_id index. Note that the lock on claim_id will still be acquired, but it will only when we actually make the update, rather than when we select the actions.
+ */
+ $action_ids = $wpdb->get_col( $wpdb->prepare( "SELECT action_id FROM {$wpdb->actionscheduler_actions} WHERE claim_id = %d", $claim->get_id() ) );
+
+ $row_updates = 0;
+ if ( count( $action_ids ) > 0 ) {
+ $action_id_string = implode( ',', array_map( 'absint', $action_ids ) );
+ $row_updates = $wpdb->query( "UPDATE {$wpdb->actionscheduler_actions} SET claim_id = 0 WHERE action_id IN ({$action_id_string})" ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+ }
+
$wpdb->delete( $wpdb->actionscheduler_claims, array( 'claim_id' => $claim->get_id() ), array( '%d' ) );
+
+ if ( $row_updates < count( $action_ids ) ) {
+ throw new RuntimeException(
+ sprintf(
+ __( 'Unable to release actions from claim id %d.', 'woocommerce' ),
+ $claim->get_id()
+ )
+ );
+ }
}
/**
diff --git a/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_HybridStore.php b/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_HybridStore.php
index d8e01e23fc..22d61a606a 100644
--- a/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_HybridStore.php
+++ b/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_HybridStore.php
@@ -1,9 +1,9 @@
primary_store->init();
$this->secondary_store->init();
- remove_action( 'action_scheduler/created_table', array( $this, 'set_autoincrement' ), 10 );
+ remove_action( 'action_scheduler/created_table', [ $this, 'set_autoincrement' ], 10 );
}
/**
@@ -78,7 +78,7 @@ public function set_autoincrement( $table_name, $table_suffix ) {
/** @var \wpdb $wpdb */
global $wpdb;
/**
- * A default date of '0000-00-00 00:00:00' is invalid in MySQL 5.7 when configured with
+ * A default date of '0000-00-00 00:00:00' is invalid in MySQL 5.7 when configured with
* sql_mode including both STRICT_TRANS_TABLES and NO_ZERO_DATE.
*/
$default_date = new DateTime( 'tomorrow' );
@@ -88,7 +88,7 @@ public function set_autoincrement( $table_name, $table_suffix ) {
$row_count = $wpdb->insert(
$wpdb->{ActionScheduler_StoreSchema::ACTIONS_TABLE},
- array(
+ [
'action_id' => $this->demarkation_id,
'hook' => '',
'status' => '',
@@ -96,12 +96,12 @@ public function set_autoincrement( $table_name, $table_suffix ) {
'scheduled_date_local' => $date_local,
'last_attempt_gmt' => $date_gmt,
'last_attempt_local' => $date_local,
- )
+ ]
);
if ( $row_count > 0 ) {
$wpdb->delete(
$wpdb->{ActionScheduler_StoreSchema::ACTIONS_TABLE},
- array( 'action_id' => $this->demarkation_id )
+ [ 'action_id' => $this->demarkation_id ]
);
}
}
@@ -140,10 +140,10 @@ private function set_demarkation_id( $id = null ) {
*
* @return string
*/
- public function find_action( $hook, $params = array() ) {
+ public function find_action( $hook, $params = [] ) {
$found_unmigrated_action = $this->secondary_store->find_action( $hook, $params );
if ( ! empty( $found_unmigrated_action ) ) {
- $this->migrate( array( $found_unmigrated_action ) );
+ $this->migrate( [ $found_unmigrated_action ] );
}
return $this->primary_store->find_action( $hook, $params );
@@ -154,12 +154,12 @@ public function find_action( $hook, $params = array() ) {
* If any are found, migrate them immediately. Then the secondary
* store will contain the canonical results.
*
- * @param array $query
+ * @param array $query
* @param string $query_type Whether to select or count the results. Default, select.
*
* @return int[]
*/
- public function query_actions( $query = array(), $query_type = 'select' ) {
+ public function query_actions( $query = [], $query_type = 'select' ) {
$found_unmigrated_actions = $this->secondary_store->query_actions( $query, 'select' );
if ( ! empty( $found_unmigrated_actions ) ) {
$this->migrate( $found_unmigrated_actions );
@@ -352,19 +352,19 @@ public function get_status( $action_id ) {
*/
protected function get_store_from_action_id( $action_id, $primary_first = false ) {
if ( $primary_first ) {
- $stores = array(
+ $stores = [
$this->primary_store,
$this->secondary_store,
- );
+ ];
} elseif ( $action_id < $this->demarkation_id ) {
- $stores = array(
+ $stores = [
$this->secondary_store,
$this->primary_store,
- );
+ ];
} else {
- $stores = array(
+ $stores = [
$this->primary_store,
- );
+ ];
}
foreach ( $stores as $store ) {
@@ -376,8 +376,7 @@ protected function get_store_from_action_id( $action_id, $primary_first = false
return null;
}
- /*
- * * * * * * * * * * * * * * * * * * * * * * * * * *
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * *
* All claim-related functions should operate solely
* on the primary store.
* * * * * * * * * * * * * * * * * * * * * * * * * * */
diff --git a/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_wpCommentLogger.php b/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_wpCommentLogger.php
index a18b6662a7..7215ddd94a 100644
--- a/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_wpCommentLogger.php
+++ b/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_wpCommentLogger.php
@@ -5,17 +5,17 @@
*/
class ActionScheduler_wpCommentLogger extends ActionScheduler_Logger {
const AGENT = 'ActionScheduler';
- const TYPE = 'action_log';
+ const TYPE = 'action_log';
/**
- * @param string $action_id
- * @param string $message
+ * @param string $action_id
+ * @param string $message
* @param DateTime $date
*
* @return string The log entry ID
*/
- public function log( $action_id, $message, DateTime $date = null ) {
- if ( empty( $date ) ) {
+ public function log( $action_id, $message, DateTime $date = NULL ) {
+ if ( empty($date) ) {
$date = as_get_datetime_object();
} else {
$date = as_get_datetime_object( clone $date );
@@ -26,18 +26,18 @@ public function log( $action_id, $message, DateTime $date = null ) {
protected function create_wp_comment( $action_id, $message, DateTime $date ) {
- $comment_date_gmt = $date->format( 'Y-m-d H:i:s' );
+ $comment_date_gmt = $date->format('Y-m-d H:i:s');
ActionScheduler_TimezoneHelper::set_local_timezone( $date );
$comment_data = array(
- 'comment_post_ID' => $action_id,
- 'comment_date' => $date->format( 'Y-m-d H:i:s' ),
+ 'comment_post_ID' => $action_id,
+ 'comment_date' => $date->format('Y-m-d H:i:s'),
'comment_date_gmt' => $comment_date_gmt,
- 'comment_author' => self::AGENT,
- 'comment_content' => $message,
- 'comment_agent' => self::AGENT,
- 'comment_type' => self::TYPE,
+ 'comment_author' => self::AGENT,
+ 'comment_content' => $message,
+ 'comment_agent' => self::AGENT,
+ 'comment_type' => self::TYPE,
);
- return wp_insert_comment( $comment_data );
+ return wp_insert_comment($comment_data);
}
/**
@@ -47,7 +47,7 @@ protected function create_wp_comment( $action_id, $message, DateTime $date ) {
*/
public function get_entry( $entry_id ) {
$comment = $this->get_comment( $entry_id );
- if ( empty( $comment ) || $comment->comment_type != self::TYPE ) {
+ if ( empty($comment) || $comment->comment_type != self::TYPE ) {
return new ActionScheduler_NullLogEntry();
}
@@ -63,22 +63,20 @@ public function get_entry( $entry_id ) {
*/
public function get_logs( $action_id ) {
$status = 'all';
- if ( get_post_status( $action_id ) == 'trash' ) {
+ if ( get_post_status($action_id) == 'trash' ) {
$status = 'post-trashed';
}
- $comments = get_comments(
- array(
- 'post_id' => $action_id,
- 'orderby' => 'comment_date_gmt',
- 'order' => 'ASC',
- 'type' => self::TYPE,
- 'status' => $status,
- )
- );
- $logs = array();
+ $comments = get_comments(array(
+ 'post_id' => $action_id,
+ 'orderby' => 'comment_date_gmt',
+ 'order' => 'ASC',
+ 'type' => self::TYPE,
+ 'status' => $status,
+ ));
+ $logs = array();
foreach ( $comments as $c ) {
$entry = $this->get_entry( $c );
- if ( ! empty( $entry ) ) {
+ if ( !empty($entry) ) {
$logs[] = $entry;
}
}
@@ -89,27 +87,29 @@ protected function get_comment( $comment_id ) {
return get_comment( $comment_id );
}
+
+
/**
* @param WP_Comment_Query $query
*/
public function filter_comment_queries( $query ) {
- foreach ( array( 'ID', 'parent', 'post_author', 'post_name', 'post_parent', 'type', 'post_type', 'post_id', 'post_ID' ) as $key ) {
- if ( ! empty( $query->query_vars[ $key ] ) ) {
+ foreach ( array('ID', 'parent', 'post_author', 'post_name', 'post_parent', 'type', 'post_type', 'post_id', 'post_ID') as $key ) {
+ if ( !empty($query->query_vars[$key]) ) {
return; // don't slow down queries that wouldn't include action_log comments anyway
}
}
- $query->query_vars['action_log_filter'] = true;
+ $query->query_vars['action_log_filter'] = TRUE;
add_filter( 'comments_clauses', array( $this, 'filter_comment_query_clauses' ), 10, 2 );
}
/**
- * @param array $clauses
+ * @param array $clauses
* @param WP_Comment_Query $query
*
* @return array
*/
public function filter_comment_query_clauses( $clauses, $query ) {
- if ( ! empty( $query->query_vars['action_log_filter'] ) ) {
+ if ( !empty($query->query_vars['action_log_filter']) ) {
$clauses['where'] .= $this->get_where_clause();
}
return $clauses;
@@ -119,7 +119,7 @@ public function filter_comment_query_clauses( $clauses, $query ) {
* Make sure Action Scheduler logs are excluded from comment feeds, which use WP_Query, not
* the WP_Comment_Query class handled by @see self::filter_comment_queries().
*
- * @param string $where
+ * @param string $where
* @param WP_Query $query
*
* @return string
@@ -145,7 +145,7 @@ protected function get_where_clause() {
* Remove action log entries from wp_count_comments()
*
* @param array $stats
- * @param int $post_id
+ * @param int $post_id
*
* @return object
*/
@@ -174,15 +174,9 @@ protected function get_comment_count() {
$count = $wpdb->get_results( "SELECT comment_approved, COUNT( * ) AS num_comments FROM {$wpdb->comments} WHERE comment_type NOT IN('order_note','action_log') GROUP BY comment_approved", ARRAY_A );
- $total = 0;
- $stats = array();
- $approved = array(
- '0' => 'moderated',
- '1' => 'approved',
- 'spam' => 'spam',
- 'trash' => 'trash',
- 'post-trashed' => 'post-trashed',
- );
+ $total = 0;
+ $stats = array();
+ $approved = array( '0' => 'moderated', '1' => 'approved', 'spam' => 'spam', 'trash' => 'trash', 'post-trashed' => 'post-trashed' );
foreach ( (array) $count as $row ) {
// Don't count post-trashed toward totals
@@ -237,10 +231,10 @@ public function init() {
}
public function disable_comment_counting() {
- wp_defer_comment_counting( true );
+ wp_defer_comment_counting(true);
}
public function enable_comment_counting() {
- wp_defer_comment_counting( false );
+ wp_defer_comment_counting(false);
}
}
diff --git a/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php b/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php
index 8a90d982d4..7883ca82bf 100644
--- a/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php
+++ b/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php
@@ -364,7 +364,7 @@ protected function get_query_actions_sql( array $query, $select_or_count = 'sele
$sql .= ' AND p.post_title=%s';
$sql_params[] = $query['hook'];
}
- if ( $query['args'] !== null ) {
+ if ( ! is_null( $query['args'] ) ) {
$sql .= ' AND p.post_content=%s';
$sql_params[] = wp_json_encode( $query['args'] );
}
@@ -398,7 +398,7 @@ protected function get_query_actions_sql( array $query, $select_or_count = 'sele
$sql .= " AND p.post_password != ''";
} elseif ( false === $query['claimed'] ) {
$sql .= " AND p.post_password = ''";
- } elseif ( $query['claimed'] !== null ) {
+ } elseif ( ! is_null( $query['claimed'] ) ) {
$sql .= ' AND p.post_password = %s';
$sql_params[] = $query['claimed'];
}
diff --git a/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostStatusRegistrar.php b/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostStatusRegistrar.php
index 392980a369..246bc347bf 100644
--- a/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostStatusRegistrar.php
+++ b/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostStatusRegistrar.php
@@ -2,7 +2,6 @@
/**
* Class ActionScheduler_wpPostStore_PostStatusRegistrar
- *
* @codeCoverageIgnore
*/
class ActionScheduler_wpPostStore_PostStatusRegistrar {
diff --git a/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php b/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php
index ab61b0d349..8c63bd0f7a 100644
--- a/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php
+++ b/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php
@@ -2,7 +2,6 @@
/**
* Class ActionScheduler_wpPostStore_PostTypeRegistrar
- *
* @codeCoverageIgnore
*/
class ActionScheduler_wpPostStore_PostTypeRegistrar {
@@ -17,35 +16,35 @@ public function register() {
*/
protected function post_type_args() {
$args = array(
- 'label' => __( 'Scheduled Actions', 'action-scheduler' ),
- 'description' => __( 'Scheduled actions are hooks triggered on a cetain date and time.', 'action-scheduler' ),
- 'public' => false,
+ 'label' => __( 'Scheduled Actions', 'action-scheduler' ),
+ 'description' => __( 'Scheduled actions are hooks triggered on a cetain date and time.', 'action-scheduler' ),
+ 'public' => false,
'map_meta_cap' => true,
'hierarchical' => false,
- 'supports' => array( 'title', 'editor', 'comments' ),
- 'rewrite' => false,
- 'query_var' => false,
- 'can_export' => true,
- 'ep_mask' => EP_NONE,
- 'labels' => array(
- 'name' => __( 'Scheduled Actions', 'action-scheduler' ),
- 'singular_name' => __( 'Scheduled Action', 'action-scheduler' ),
- 'menu_name' => _x( 'Scheduled Actions', 'Admin menu name', 'action-scheduler' ),
- 'add_new' => __( 'Add', 'action-scheduler' ),
- 'add_new_item' => __( 'Add New Scheduled Action', 'action-scheduler' ),
- 'edit' => __( 'Edit', 'action-scheduler' ),
- 'edit_item' => __( 'Edit Scheduled Action', 'action-scheduler' ),
- 'new_item' => __( 'New Scheduled Action', 'action-scheduler' ),
- 'view' => __( 'View Action', 'action-scheduler' ),
- 'view_item' => __( 'View Action', 'action-scheduler' ),
- 'search_items' => __( 'Search Scheduled Actions', 'action-scheduler' ),
- 'not_found' => __( 'No actions found', 'action-scheduler' ),
+ 'supports' => array('title', 'editor','comments'),
+ 'rewrite' => false,
+ 'query_var' => false,
+ 'can_export' => true,
+ 'ep_mask' => EP_NONE,
+ 'labels' => array(
+ 'name' => __( 'Scheduled Actions', 'action-scheduler' ),
+ 'singular_name' => __( 'Scheduled Action', 'action-scheduler' ),
+ 'menu_name' => _x( 'Scheduled Actions', 'Admin menu name', 'action-scheduler' ),
+ 'add_new' => __( 'Add', 'action-scheduler' ),
+ 'add_new_item' => __( 'Add New Scheduled Action', 'action-scheduler' ),
+ 'edit' => __( 'Edit', 'action-scheduler' ),
+ 'edit_item' => __( 'Edit Scheduled Action', 'action-scheduler' ),
+ 'new_item' => __( 'New Scheduled Action', 'action-scheduler' ),
+ 'view' => __( 'View Action', 'action-scheduler' ),
+ 'view_item' => __( 'View Action', 'action-scheduler' ),
+ 'search_items' => __( 'Search Scheduled Actions', 'action-scheduler' ),
+ 'not_found' => __( 'No actions found', 'action-scheduler' ),
'not_found_in_trash' => __( 'No actions found in trash', 'action-scheduler' ),
),
);
- $args = apply_filters( 'action_scheduler_post_type_args', $args );
+ $args = apply_filters('action_scheduler_post_type_args', $args);
return $args;
}
}
-
+
\ No newline at end of file
diff --git a/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_TaxonomyRegistrar.php b/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_TaxonomyRegistrar.php
index f652dead8c..367401f7e2 100644
--- a/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_TaxonomyRegistrar.php
+++ b/src/libraries/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_TaxonomyRegistrar.php
@@ -2,7 +2,6 @@
/**
* Class ActionScheduler_wpPostStore_TaxonomyRegistrar
- *
* @codeCoverageIgnore
*/
class ActionScheduler_wpPostStore_TaxonomyRegistrar {
@@ -12,16 +11,16 @@ public function register() {
protected function taxonomy_args() {
$args = array(
- 'label' => __( 'Action Group', 'action-scheduler' ),
- 'public' => false,
- 'hierarchical' => false,
+ 'label' => __( 'Action Group', 'action-scheduler' ),
+ 'public' => false,
+ 'hierarchical' => false,
'show_admin_column' => true,
- 'query_var' => false,
- 'rewrite' => false,
+ 'query_var' => false,
+ 'rewrite' => false,
);
$args = apply_filters( 'action_scheduler_taxonomy_args', $args );
return $args;
}
}
-
+
\ No newline at end of file
diff --git a/src/libraries/action-scheduler/classes/migration/ActionMigrator.php b/src/libraries/action-scheduler/classes/migration/ActionMigrator.php
index 2ff8e64839..c77d0832cd 100644
--- a/src/libraries/action-scheduler/classes/migration/ActionMigrator.php
+++ b/src/libraries/action-scheduler/classes/migration/ActionMigrator.php
@@ -1,5 +1,6 @@
get_schedule()->get_date() ) {
+ if ( is_null( $action ) || empty( $status ) || ! $action->get_schedule()->get_date() ) {
// null action or empty status means the fetch operation failed or the action didn't exist
// null schedule means it's missing vital data
// delete it and move on
@@ -78,10 +79,10 @@ public function migrate( $source_action_id ) {
try {
switch ( $status ) {
- case \ActionScheduler_Store::STATUS_FAILED:
+ case \ActionScheduler_Store::STATUS_FAILED :
$this->destination->mark_failure( $destination_action_id );
break;
- case \ActionScheduler_Store::STATUS_CANCELED:
+ case \ActionScheduler_Store::STATUS_CANCELED :
$this->destination->cancel_action( $destination_action_id );
break;
}
diff --git a/src/libraries/action-scheduler/classes/migration/ActionScheduler_DBStoreMigrator.php b/src/libraries/action-scheduler/classes/migration/ActionScheduler_DBStoreMigrator.php
index 29793c62b6..41c21da256 100644
--- a/src/libraries/action-scheduler/classes/migration/ActionScheduler_DBStoreMigrator.php
+++ b/src/libraries/action-scheduler/classes/migration/ActionScheduler_DBStoreMigrator.php
@@ -17,13 +17,13 @@ class ActionScheduler_DBStoreMigrator extends ActionScheduler_DBStore {
* that when first saving the action.
*
* @param ActionScheduler_Action $action
- * @param \DateTime $scheduled_date Optional date of the first instance to store.
- * @param \DateTime $last_attempt_date Optional date the action was last attempted.
+ * @param \DateTime $scheduled_date Optional date of the first instance to store.
+ * @param \DateTime $last_attempt_date Optional date the action was last attempted.
*
* @return string The action ID
* @throws \RuntimeException When the action is not saved.
*/
- public function save_action( ActionScheduler_Action $action, \DateTime $scheduled_date = null, \DateTime $last_attempt_date = null ) {
+ public function save_action( ActionScheduler_Action $action, \DateTime $scheduled_date = null, \DateTime $last_attempt_date = null ){
try {
/** @var \wpdb $wpdb */
global $wpdb;
@@ -31,10 +31,10 @@ public function save_action( ActionScheduler_Action $action, \DateTime $schedule
$action_id = parent::save_action( $action, $scheduled_date );
if ( null !== $last_attempt_date ) {
- $data = array(
+ $data = [
'last_attempt_gmt' => $this->get_scheduled_date_string( $action, $last_attempt_date ),
'last_attempt_local' => $this->get_scheduled_date_string_local( $action, $last_attempt_date ),
- );
+ ];
$wpdb->update( $wpdb->actionscheduler_actions, $data, array( 'action_id' => $action_id ), array( '%s', '%s' ), array( '%d' ) );
}
diff --git a/src/libraries/action-scheduler/classes/migration/BatchFetcher.php b/src/libraries/action-scheduler/classes/migration/BatchFetcher.php
index 428047a532..48728010fe 100644
--- a/src/libraries/action-scheduler/classes/migration/BatchFetcher.php
+++ b/src/libraries/action-scheduler/classes/migration/BatchFetcher.php
@@ -1,7 +1,9 @@
$now,
'per_page' => $count,
'offset' => 0,
'orderby' => 'date',
'order' => 'ASC',
- );
+ ];
- $priorities = array(
+ $priorities = [
Store::STATUS_PENDING,
Store::STATUS_FAILED,
Store::STATUS_CANCELED,
Store::STATUS_COMPLETE,
Store::STATUS_RUNNING,
'', // any other unanticipated status
- );
+ ];
foreach ( $priorities as $status ) {
- yield wp_parse_args(
- array(
- 'status' => $status,
- 'date_compare' => '<=',
- ),
- $args
- );
- yield wp_parse_args(
- array(
- 'status' => $status,
- 'date_compare' => '>=',
- ),
- $args
- );
+ yield wp_parse_args( [
+ 'status' => $status,
+ 'date_compare' => '<=',
+ ], $args );
+ yield wp_parse_args( [
+ 'status' => $status,
+ 'date_compare' => '>=',
+ ], $args );
}
}
-}
+}
\ No newline at end of file
diff --git a/src/libraries/action-scheduler/classes/migration/Config.php b/src/libraries/action-scheduler/classes/migration/Config.php
index 9abf79749a..50f41ff49a 100644
--- a/src/libraries/action-scheduler/classes/migration/Config.php
+++ b/src/libraries/action-scheduler/classes/migration/Config.php
@@ -1,5 +1,6 @@
batch_fetcher->fetch( $batch_size );
+ $batch = $this->batch_fetcher->fetch( $batch_size );
$batch_size = count( $batch );
if ( ! $batch_size ) {
@@ -101,17 +102,14 @@ public function migrate_actions( array $action_ids ) {
foreach ( $action_ids as $source_action_id ) {
$destination_action_id = $this->action_migrator->migrate( $source_action_id );
if ( $destination_action_id ) {
- $this->destination_logger->log(
- $destination_action_id,
- sprintf(
+ $this->destination_logger->log( $destination_action_id, sprintf(
/* translators: 1: source action ID 2: source store class 3: destination action ID 4: destination store class */
- __( 'Migrated action with ID %1$d in %2$s to ID %3$d in %4$s', 'action-scheduler' ),
- $source_action_id,
- get_class( $this->source_store ),
- $destination_action_id,
- get_class( $this->destination_store )
- )
- );
+ __( 'Migrated action with ID %1$d in %2$s to ID %3$d in %4$s', 'action-scheduler' ),
+ $source_action_id,
+ get_class( $this->source_store ),
+ $destination_action_id,
+ get_class( $this->destination_store )
+ ) );
}
if ( $this->progress_bar ) {
diff --git a/src/libraries/action-scheduler/classes/migration/Scheduler.php b/src/libraries/action-scheduler/classes/migration/Scheduler.php
index c32d840377..dcbe2db5fa 100644
--- a/src/libraries/action-scheduler/classes/migration/Scheduler.php
+++ b/src/libraries/action-scheduler/classes/migration/Scheduler.php
@@ -1,5 +1,6 @@
__wakeup() for details.
**/
- private $timestamp = null;
+ private $timestamp = NULL;
/**
* @param DateTime $after
@@ -48,7 +48,7 @@ public function is_recurring() {
* map the old property names with matching visibility.
*/
public function __wakeup() {
- if ( $this->timestamp !== null ) {
+ if ( ! is_null( $this->timestamp ) ) {
$this->scheduled_timestamp = $this->timestamp;
unset( $this->timestamp );
}
diff --git a/src/libraries/action-scheduler/classes/schedules/ActionScheduler_CronSchedule.php b/src/libraries/action-scheduler/classes/schedules/ActionScheduler_CronSchedule.php
index f11bf19868..7859307ac8 100644
--- a/src/libraries/action-scheduler/classes/schedules/ActionScheduler_CronSchedule.php
+++ b/src/libraries/action-scheduler/classes/schedules/ActionScheduler_CronSchedule.php
@@ -8,20 +8,20 @@ class ActionScheduler_CronSchedule extends ActionScheduler_Abstract_RecurringSch
/**
* Deprecated property @see $this->__wakeup() for details.
**/
- private $start_timestamp = null;
+ private $start_timestamp = NULL;
/**
* Deprecated property @see $this->__wakeup() for details.
**/
- private $cron = null;
+ private $cron = NULL;
/**
* Wrapper for parent constructor to accept a cron expression string and map it to a CronExpression for this
* objects $recurrence property.
*
- * @param DateTime $start The date & time to run the action at or after. If $start aligns with the CronSchedule passed via $recurrence, it will be used. If it does not align, the first matching date after it will be used.
+ * @param DateTime $start The date & time to run the action at or after. If $start aligns with the CronSchedule passed via $recurrence, it will be used. If it does not align, the first matching date after it will be used.
* @param CronExpression|string $recurrence The CronExpression used to calculate the schedule's next instance.
- * @param DateTime|null $first (Optional) The date & time the first instance of this interval schedule ran. Default null, meaning this is the first instance.
+ * @param DateTime|null $first (Optional) The date & time the first instance of this interval schedule ran. Default null, meaning this is the first instance.
*/
public function __construct( DateTime $start, $recurrence, DateTime $first = null ) {
if ( ! is_a( $recurrence, 'CronExpression' ) ) {
@@ -75,13 +75,10 @@ public function __sleep() {
$this->start_timestamp = $this->scheduled_timestamp;
$this->cron = $this->recurrence;
- return array_merge(
- $sleep_params,
- array(
- 'start_timestamp',
- 'cron',
- )
- );
+ return array_merge( $sleep_params, array(
+ 'start_timestamp',
+ 'cron'
+ ) );
}
/**
@@ -90,12 +87,12 @@ public function __sleep() {
* For more background, @see ActionScheduler_Abstract_RecurringSchedule::__wakeup().
*/
public function __wakeup() {
- if ( $this->scheduled_timestamp === null && $this->start_timestamp !== null ) {
+ if ( is_null( $this->scheduled_timestamp ) && ! is_null( $this->start_timestamp ) ) {
$this->scheduled_timestamp = $this->start_timestamp;
unset( $this->start_timestamp );
}
- if ( $this->recurrence === null && $this->cron !== null ) {
+ if ( is_null( $this->recurrence ) && ! is_null( $this->cron ) ) {
$this->recurrence = $this->cron;
unset( $this->cron );
}
diff --git a/src/libraries/action-scheduler/classes/schedules/ActionScheduler_IntervalSchedule.php b/src/libraries/action-scheduler/classes/schedules/ActionScheduler_IntervalSchedule.php
index 94ebfe07c5..11a591e80b 100644
--- a/src/libraries/action-scheduler/classes/schedules/ActionScheduler_IntervalSchedule.php
+++ b/src/libraries/action-scheduler/classes/schedules/ActionScheduler_IntervalSchedule.php
@@ -8,12 +8,12 @@ class ActionScheduler_IntervalSchedule extends ActionScheduler_Abstract_Recurrin
/**
* Deprecated property @see $this->__wakeup() for details.
**/
- private $start_timestamp = null;
+ private $start_timestamp = NULL;
/**
* Deprecated property @see $this->__wakeup() for details.
**/
- private $interval_in_seconds = null;
+ private $interval_in_seconds = NULL;
/**
* Calculate when this schedule should start after a given date & time using
@@ -55,13 +55,10 @@ public function __sleep() {
$this->start_timestamp = $this->scheduled_timestamp;
$this->interval_in_seconds = $this->recurrence;
- return array_merge(
- $sleep_params,
- array(
- 'start_timestamp',
- 'interval_in_seconds',
- )
- );
+ return array_merge( $sleep_params, array(
+ 'start_timestamp',
+ 'interval_in_seconds'
+ ) );
}
/**
@@ -70,12 +67,12 @@ public function __sleep() {
* For more background, @see ActionScheduler_Abstract_RecurringSchedule::__wakeup().
*/
public function __wakeup() {
- if ( $this->scheduled_timestamp === null && $this->start_timestamp !== null ) {
+ if ( is_null( $this->scheduled_timestamp ) && ! is_null( $this->start_timestamp ) ) {
$this->scheduled_timestamp = $this->start_timestamp;
unset( $this->start_timestamp );
}
- if ( $this->recurrence === null && $this->interval_in_seconds !== null ) {
+ if ( is_null( $this->recurrence ) && ! is_null( $this->interval_in_seconds ) ) {
$this->recurrence = $this->interval_in_seconds;
unset( $this->interval_in_seconds );
}
diff --git a/src/libraries/action-scheduler/classes/schedules/ActionScheduler_NullSchedule.php b/src/libraries/action-scheduler/classes/schedules/ActionScheduler_NullSchedule.php
index 88d6196538..1b1afec021 100644
--- a/src/libraries/action-scheduler/classes/schedules/ActionScheduler_NullSchedule.php
+++ b/src/libraries/action-scheduler/classes/schedules/ActionScheduler_NullSchedule.php
@@ -5,6 +5,9 @@
*/
class ActionScheduler_NullSchedule extends ActionScheduler_SimpleSchedule {
+ /** @var DateTime|null */
+ protected $scheduled_date;
+
/**
* Make the $date param optional and default to null.
*
@@ -16,7 +19,6 @@ public function __construct( DateTime $date = null ) {
/**
* This schedule has no scheduled DateTime, so we need to override the parent __sleep()
- *
* @return array
*/
public function __sleep() {
diff --git a/src/libraries/action-scheduler/classes/schedules/ActionScheduler_Schedule.php b/src/libraries/action-scheduler/classes/schedules/ActionScheduler_Schedule.php
index bfead893cf..d61a9f7c92 100644
--- a/src/libraries/action-scheduler/classes/schedules/ActionScheduler_Schedule.php
+++ b/src/libraries/action-scheduler/classes/schedules/ActionScheduler_Schedule.php
@@ -8,11 +8,11 @@ interface ActionScheduler_Schedule {
* @param DateTime $after
* @return DateTime|null
*/
- public function next( DateTime $after = null );
+ public function next( DateTime $after = NULL );
/**
* @return bool
*/
public function is_recurring();
}
-
+
\ No newline at end of file
diff --git a/src/libraries/action-scheduler/classes/schedules/ActionScheduler_SimpleSchedule.php b/src/libraries/action-scheduler/classes/schedules/ActionScheduler_SimpleSchedule.php
index a1c8c33b66..454174c2ae 100644
--- a/src/libraries/action-scheduler/classes/schedules/ActionScheduler_SimpleSchedule.php
+++ b/src/libraries/action-scheduler/classes/schedules/ActionScheduler_SimpleSchedule.php
@@ -8,7 +8,7 @@ class ActionScheduler_SimpleSchedule extends ActionScheduler_Abstract_Schedule {
/**
* Deprecated property @see $this->__wakeup() for details.
**/
- private $timestamp = null;
+ private $timestamp = NULL;
/**
* @param DateTime $after
@@ -45,12 +45,9 @@ public function __sleep() {
$this->timestamp = $this->scheduled_timestamp;
- return array_merge(
- $sleep_params,
- array(
- 'timestamp',
- )
- );
+ return array_merge( $sleep_params, array(
+ 'timestamp',
+ ) );
}
/**
@@ -65,7 +62,7 @@ public function __sleep() {
*/
public function __wakeup() {
- if ( $this->scheduled_timestamp === null && $this->timestamp !== null ) {
+ if ( is_null( $this->scheduled_timestamp ) && ! is_null( $this->timestamp ) ) {
$this->scheduled_timestamp = $this->timestamp;
unset( $this->timestamp );
}
diff --git a/src/libraries/action-scheduler/classes/schema/ActionScheduler_LoggerSchema.php b/src/libraries/action-scheduler/classes/schema/ActionScheduler_LoggerSchema.php
index 5f139b0b83..c52d37ce0b 100644
--- a/src/libraries/action-scheduler/classes/schema/ActionScheduler_LoggerSchema.php
+++ b/src/libraries/action-scheduler/classes/schema/ActionScheduler_LoggerSchema.php
@@ -16,9 +16,9 @@ class ActionScheduler_LoggerSchema extends ActionScheduler_Abstract_Schema {
protected $schema_version = 3;
public function __construct() {
- $this->tables = array(
+ $this->tables = [
self::LOG_TABLE,
- );
+ ];
}
/**
@@ -30,11 +30,12 @@ public function init() {
protected function get_table_definition( $table ) {
global $wpdb;
- $table_name = $wpdb->$table;
- $charset_collate = $wpdb->get_charset_collate();
+ $table_name = $wpdb->$table;
+ $charset_collate = $wpdb->get_charset_collate();
switch ( $table ) {
case self::LOG_TABLE:
+
$default_date = ActionScheduler_StoreSchema::DEFAULT_DATE;
return "CREATE TABLE $table_name (
log_id bigint(20) unsigned NOT NULL auto_increment,
diff --git a/src/libraries/action-scheduler/classes/schema/ActionScheduler_StoreSchema.php b/src/libraries/action-scheduler/classes/schema/ActionScheduler_StoreSchema.php
index 9529e27638..d52f27f6fc 100644
--- a/src/libraries/action-scheduler/classes/schema/ActionScheduler_StoreSchema.php
+++ b/src/libraries/action-scheduler/classes/schema/ActionScheduler_StoreSchema.php
@@ -19,11 +19,11 @@ class ActionScheduler_StoreSchema extends ActionScheduler_Abstract_Schema {
protected $schema_version = 6;
public function __construct() {
- $this->tables = array(
+ $this->tables = [
self::ACTIONS_TABLE,
self::CLAIMS_TABLE,
self::GROUPS_TABLE,
- );
+ ];
}
/**
@@ -42,18 +42,19 @@ protected function get_table_definition( $table ) {
switch ( $table ) {
case self::ACTIONS_TABLE:
+
return "CREATE TABLE {$table_name} (
action_id bigint(20) unsigned NOT NULL auto_increment,
hook varchar(191) NOT NULL,
status varchar(20) NOT NULL,
- scheduled_date_gmt datetime NULL default '${default_date}',
- scheduled_date_local datetime NULL default '${default_date}',
+ scheduled_date_gmt datetime NULL default '{$default_date}',
+ scheduled_date_local datetime NULL default '{$default_date}',
args varchar($max_index_length),
schedule longtext,
group_id bigint(20) unsigned NOT NULL default '0',
attempts int(11) NOT NULL default '0',
- last_attempt_gmt datetime NULL default '${default_date}',
- last_attempt_local datetime NULL default '${default_date}',
+ last_attempt_gmt datetime NULL default '{$default_date}',
+ last_attempt_local datetime NULL default '{$default_date}',
claim_id bigint(20) unsigned NOT NULL default '0',
extended_args varchar(8000) DEFAULT NULL,
PRIMARY KEY (action_id),
@@ -67,14 +68,16 @@ protected function get_table_definition( $table ) {
) $charset_collate";
case self::CLAIMS_TABLE:
+
return "CREATE TABLE {$table_name} (
claim_id bigint(20) unsigned NOT NULL auto_increment,
- date_created_gmt datetime NULL default '${default_date}',
+ date_created_gmt datetime NULL default '{$default_date}',
PRIMARY KEY (claim_id),
KEY date_created_gmt (date_created_gmt)
) $charset_collate";
case self::GROUPS_TABLE:
+
return "CREATE TABLE {$table_name} (
group_id bigint(20) unsigned NOT NULL auto_increment,
slug varchar(255) NOT NULL,
@@ -108,16 +111,16 @@ public function update_schema_5_0( $table, $db_version ) {
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$table_name = $wpdb->prefix . 'actionscheduler_actions';
- $table_list = $wpdb->get_col( "SHOW TABLES LIKE '${table_name}'" );
+ $table_list = $wpdb->get_col( "SHOW TABLES LIKE '{$table_name}'" );
$default_date = self::DEFAULT_DATE;
if ( ! empty( $table_list ) ) {
$query = "
- ALTER TABLE ${table_name}
- MODIFY COLUMN scheduled_date_gmt datetime NULL default '${default_date}',
- MODIFY COLUMN scheduled_date_local datetime NULL default '${default_date}',
- MODIFY COLUMN last_attempt_gmt datetime NULL default '${default_date}',
- MODIFY COLUMN last_attempt_local datetime NULL default '${default_date}'
+ ALTER TABLE {$table_name}
+ MODIFY COLUMN scheduled_date_gmt datetime NULL default '{$default_date}',
+ MODIFY COLUMN scheduled_date_local datetime NULL default '{$default_date}',
+ MODIFY COLUMN last_attempt_gmt datetime NULL default '{$default_date}',
+ MODIFY COLUMN last_attempt_local datetime NULL default '{$default_date}'
";
$wpdb->query( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
}
diff --git a/src/libraries/action-scheduler/codecov.yml b/src/libraries/action-scheduler/codecov.yml
deleted file mode 100644
index fe69f96695..0000000000
--- a/src/libraries/action-scheduler/codecov.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-codecov:
- branch: master
-
-coverage:
- ignore:
- - tests/.*
- - lib/.*
- status:
- project: false
- patch: false
- changes: false
-
-comment: false
diff --git a/src/libraries/action-scheduler/composer.json b/src/libraries/action-scheduler/composer.json
deleted file mode 100644
index 2ab9bf5a0a..0000000000
--- a/src/libraries/action-scheduler/composer.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
- "name": "woocommerce/action-scheduler",
- "description": "Action Scheduler for WordPress and WooCommerce",
- "homepage": "https://actionscheduler.org/",
- "type": "wordpress-plugin",
- "license": "GPL-3.0-or-later",
- "prefer-stable": true,
- "minimum-stability": "dev",
- "require": {},
- "require-dev": {
- "phpunit/phpunit": "^7.5",
- "wp-cli/wp-cli": "~2.5.0",
- "woocommerce/woocommerce-sniffs": "0.1.0",
- "yoast/phpunit-polyfills": "^1.0"
- },
- "config": {
- "allow-plugins": {
- "dealerdirect/phpcodesniffer-composer-installer": true
- },
- "platform": {
- "php": "7.3"
- }
- },
- "archive": {
- "exclude": [
- "node_modules"
- ]
- },
- "scripts": {
- "test": [
- "./vendor/bin/phpunit tests -c tests/phpunit.xml.dist"
- ],
- "phpcs": [
- "phpcs -s -p"
- ],
- "phpcs-pre-commit": [
- "phpcs -s -p -n"
- ],
- "phpcbf": [
- "phpcbf -p"
- ]
- },
- "extra": {
- "scripts-description": {
- "test": "Run unit tests",
- "phpcs": "Analyze code against the WordPress coding standards with PHP_CodeSniffer",
- "phpcbf": "Fix coding standards warnings/errors automatically with PHP Code Beautifier"
- }
- }
-}
diff --git a/src/libraries/action-scheduler/composer.lock b/src/libraries/action-scheduler/composer.lock
deleted file mode 100644
index fd47cf9b51..0000000000
--- a/src/libraries/action-scheduler/composer.lock
+++ /dev/null
@@ -1,2602 +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": "70864a6e30dbbcb32cc2994aaf87a017",
- "packages": [],
- "packages-dev": [
- {
- "name": "dealerdirect/phpcodesniffer-composer-installer",
- "version": "v0.7.0",
- "source": {
- "type": "git",
- "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git",
- "reference": "e8d808670b8f882188368faaf1144448c169c0b7"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/e8d808670b8f882188368faaf1144448c169c0b7",
- "reference": "e8d808670b8f882188368faaf1144448c169c0b7",
- "shasum": ""
- },
- "require": {
- "composer-plugin-api": "^1.0 || ^2.0",
- "php": ">=5.3",
- "squizlabs/php_codesniffer": "^2 || ^3 || 4.0.x-dev"
- },
- "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-06-25T14:57:39+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": "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": "myclabs/deep-copy",
- "version": "1.10.2",
- "source": {
- "type": "git",
- "url": "https://github.com/myclabs/DeepCopy.git",
- "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220",
- "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220",
- "shasum": ""
- },
- "require": {
- "php": "^7.1 || ^8.0"
- },
- "replace": {
- "myclabs/deep-copy": "self.version"
- },
- "require-dev": {
- "doctrine/collections": "^1.0",
- "doctrine/common": "^2.6",
- "phpunit/phpunit": "^7.1"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "DeepCopy\\": "src/DeepCopy/"
- },
- "files": [
- "src/DeepCopy/deep_copy.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "description": "Create deep copies (clones) of your objects",
- "keywords": [
- "clone",
- "copy",
- "duplicate",
- "object",
- "object graph"
- ],
- "support": {
- "issues": "https://github.com/myclabs/DeepCopy/issues",
- "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2"
- },
- "funding": [
- {
- "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
- "type": "tidelift"
- }
- ],
- "time": "2020-11-13T09:40:50+00:00"
- },
- {
- "name": "phar-io/manifest",
- "version": "1.0.3",
- "source": {
- "type": "git",
- "url": "https://github.com/phar-io/manifest.git",
- "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
- "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
- "shasum": ""
- },
- "require": {
- "ext-dom": "*",
- "ext-phar": "*",
- "phar-io/version": "^2.0",
- "php": "^5.6 || ^7.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Arne Blankerts",
- "email": "arne@blankerts.de",
- "role": "Developer"
- },
- {
- "name": "Sebastian Heuer",
- "email": "sebastian@phpeople.de",
- "role": "Developer"
- },
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "Developer"
- }
- ],
- "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
- "support": {
- "issues": "https://github.com/phar-io/manifest/issues",
- "source": "https://github.com/phar-io/manifest/tree/master"
- },
- "time": "2018-07-08T19:23:20+00:00"
- },
- {
- "name": "phar-io/version",
- "version": "2.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/phar-io/version.git",
- "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6",
- "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6",
- "shasum": ""
- },
- "require": {
- "php": "^5.6 || ^7.0"
- },
- "type": "library",
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Arne Blankerts",
- "email": "arne@blankerts.de",
- "role": "Developer"
- },
- {
- "name": "Sebastian Heuer",
- "email": "sebastian@phpeople.de",
- "role": "Developer"
- },
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "Developer"
- }
- ],
- "description": "Library for handling version information and constraints",
- "support": {
- "issues": "https://github.com/phar-io/version/issues",
- "source": "https://github.com/phar-io/version/tree/master"
- },
- "time": "2018-07-08T19:19:57+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.0",
- "source": {
- "type": "git",
- "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git",
- "reference": "41bef18ba688af638b7310666db28e1ea9158b2f"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/41bef18ba688af638b7310666db28e1ea9158b2f",
- "reference": "41bef18ba688af638b7310666db28e1ea9158b2f",
- "shasum": ""
- },
- "require": {
- "phpcompatibility/php-compatibility": "^9.0",
- "phpcompatibility/phpcompatibility-paragonie": "^1.0"
- },
- "require-dev": {
- "dealerdirect/phpcodesniffer-composer-installer": "^0.5"
- },
- "suggest": {
- "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || 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": "2019-08-28T14:22:28+00:00"
- },
- {
- "name": "phpdocumentor/reflection-common",
- "version": "2.2.0",
- "source": {
- "type": "git",
- "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
- "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
- "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
- "shasum": ""
- },
- "require": {
- "php": "^7.2 || ^8.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-2.x": "2.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "phpDocumentor\\Reflection\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jaap van Otterdijk",
- "email": "opensource@ijaap.nl"
- }
- ],
- "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
- "homepage": "http://www.phpdoc.org",
- "keywords": [
- "FQSEN",
- "phpDocumentor",
- "phpdoc",
- "reflection",
- "static analysis"
- ],
- "support": {
- "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
- "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
- },
- "time": "2020-06-27T09:03:43+00:00"
- },
- {
- "name": "phpdocumentor/reflection-docblock",
- "version": "5.3.0",
- "source": {
- "type": "git",
- "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
- "reference": "622548b623e81ca6d78b721c5e029f4ce664f170"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170",
- "reference": "622548b623e81ca6d78b721c5e029f4ce664f170",
- "shasum": ""
- },
- "require": {
- "ext-filter": "*",
- "php": "^7.2 || ^8.0",
- "phpdocumentor/reflection-common": "^2.2",
- "phpdocumentor/type-resolver": "^1.3",
- "webmozart/assert": "^1.9.1"
- },
- "require-dev": {
- "mockery/mockery": "~1.3.2",
- "psalm/phar": "^4.8"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "phpDocumentor\\Reflection\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Mike van Riel",
- "email": "me@mikevanriel.com"
- },
- {
- "name": "Jaap van Otterdijk",
- "email": "account@ijaap.nl"
- }
- ],
- "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
- "support": {
- "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
- "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0"
- },
- "time": "2021-10-19T17:43:47+00:00"
- },
- {
- "name": "phpdocumentor/type-resolver",
- "version": "1.5.1",
- "source": {
- "type": "git",
- "url": "https://github.com/phpDocumentor/TypeResolver.git",
- "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae",
- "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae",
- "shasum": ""
- },
- "require": {
- "php": "^7.2 || ^8.0",
- "phpdocumentor/reflection-common": "^2.0"
- },
- "require-dev": {
- "ext-tokenizer": "*",
- "psalm/phar": "^4.8"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-1.x": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "phpDocumentor\\Reflection\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Mike van Riel",
- "email": "me@mikevanriel.com"
- }
- ],
- "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
- "support": {
- "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
- "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.1"
- },
- "time": "2021-10-02T14:08:47+00:00"
- },
- {
- "name": "phpspec/prophecy",
- "version": "1.14.0",
- "source": {
- "type": "git",
- "url": "https://github.com/phpspec/prophecy.git",
- "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e",
- "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e",
- "shasum": ""
- },
- "require": {
- "doctrine/instantiator": "^1.2",
- "php": "^7.2 || ~8.0, <8.2",
- "phpdocumentor/reflection-docblock": "^5.2",
- "sebastian/comparator": "^3.0 || ^4.0",
- "sebastian/recursion-context": "^3.0 || ^4.0"
- },
- "require-dev": {
- "phpspec/phpspec": "^6.0 || ^7.0",
- "phpunit/phpunit": "^8.0 || ^9.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Prophecy\\": "src/Prophecy"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Konstantin Kudryashov",
- "email": "ever.zet@gmail.com",
- "homepage": "http://everzet.com"
- },
- {
- "name": "Marcello Duarte",
- "email": "marcello.duarte@gmail.com"
- }
- ],
- "description": "Highly opinionated mocking framework for PHP 5.3+",
- "homepage": "https://github.com/phpspec/prophecy",
- "keywords": [
- "Double",
- "Dummy",
- "fake",
- "mock",
- "spy",
- "stub"
- ],
- "support": {
- "issues": "https://github.com/phpspec/prophecy/issues",
- "source": "https://github.com/phpspec/prophecy/tree/1.14.0"
- },
- "time": "2021-09-10T09:02:12+00:00"
- },
- {
- "name": "phpunit/php-code-coverage",
- "version": "6.1.4",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
- "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
- "shasum": ""
- },
- "require": {
- "ext-dom": "*",
- "ext-xmlwriter": "*",
- "php": "^7.1",
- "phpunit/php-file-iterator": "^2.0",
- "phpunit/php-text-template": "^1.2.1",
- "phpunit/php-token-stream": "^3.0",
- "sebastian/code-unit-reverse-lookup": "^1.0.1",
- "sebastian/environment": "^3.1 || ^4.0",
- "sebastian/version": "^2.0.1",
- "theseer/tokenizer": "^1.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^7.0"
- },
- "suggest": {
- "ext-xdebug": "^2.6.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "6.1-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "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": {
- "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
- "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/master"
- },
- "time": "2018-10-31T16:06:48+00:00"
- },
- {
- "name": "phpunit/php-file-iterator",
- "version": "2.0.4",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
- "reference": "28af674ff175d0768a5a978e6de83f697d4a7f05"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/28af674ff175d0768a5a978e6de83f697d4a7f05",
- "reference": "28af674ff175d0768a5a978e6de83f697d4a7f05",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^8.5"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "FilterIterator implementation that filters files based on a list of suffixes.",
- "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
- "keywords": [
- "filesystem",
- "iterator"
- ],
- "support": {
- "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
- "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.4"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2021-07-19T06:46:01+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": "2.1.3",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/php-timer.git",
- "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662",
- "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^8.5"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.1-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "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/2.1.3"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2020-11-30T08:20:02+00:00"
- },
- {
- "name": "phpunit/php-token-stream",
- "version": "3.1.3",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/php-token-stream.git",
- "reference": "9c1da83261628cb24b6a6df371b6e312b3954768"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/9c1da83261628cb24b6a6df371b6e312b3954768",
- "reference": "9c1da83261628cb24b6a6df371b6e312b3954768",
- "shasum": ""
- },
- "require": {
- "ext-tokenizer": "*",
- "php": ">=7.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^7.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.1-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/3.1.3"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "abandoned": true,
- "time": "2021-07-26T12:15:06+00:00"
- },
- {
- "name": "phpunit/phpunit",
- "version": "7.5.20",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "9467db479d1b0487c99733bb1e7944d32deded2c"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9467db479d1b0487c99733bb1e7944d32deded2c",
- "reference": "9467db479d1b0487c99733bb1e7944d32deded2c",
- "shasum": ""
- },
- "require": {
- "doctrine/instantiator": "^1.1",
- "ext-dom": "*",
- "ext-json": "*",
- "ext-libxml": "*",
- "ext-mbstring": "*",
- "ext-xml": "*",
- "myclabs/deep-copy": "^1.7",
- "phar-io/manifest": "^1.0.2",
- "phar-io/version": "^2.0",
- "php": "^7.1",
- "phpspec/prophecy": "^1.7",
- "phpunit/php-code-coverage": "^6.0.7",
- "phpunit/php-file-iterator": "^2.0.1",
- "phpunit/php-text-template": "^1.2.1",
- "phpunit/php-timer": "^2.1",
- "sebastian/comparator": "^3.0",
- "sebastian/diff": "^3.0",
- "sebastian/environment": "^4.0",
- "sebastian/exporter": "^3.1",
- "sebastian/global-state": "^2.0",
- "sebastian/object-enumerator": "^3.0.3",
- "sebastian/resource-operations": "^2.0",
- "sebastian/version": "^2.0.1"
- },
- "conflict": {
- "phpunit/phpunit-mock-objects": "*"
- },
- "require-dev": {
- "ext-pdo": "*"
- },
- "suggest": {
- "ext-soap": "*",
- "ext-xdebug": "*",
- "phpunit/php-invoker": "^2.0"
- },
- "bin": [
- "phpunit"
- ],
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "7.5-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/7.5.20"
- },
- "time": "2020-01-08T08:45:45+00:00"
- },
- {
- "name": "rmccue/requests",
- "version": "v1.8.1",
- "source": {
- "type": "git",
- "url": "https://github.com/WordPress/Requests.git",
- "reference": "82e6936366eac3af4d836c18b9d8c31028fe4cd5"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/WordPress/Requests/zipball/82e6936366eac3af4d836c18b9d8c31028fe4cd5",
- "reference": "82e6936366eac3af4d836c18b9d8c31028fe4cd5",
- "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.1"
- },
- "time": "2021-06-04T09:56:25+00:00"
- },
- {
- "name": "sebastian/code-unit-reverse-lookup",
- "version": "1.0.2",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
- "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619",
- "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619",
- "shasum": ""
- },
- "require": {
- "php": ">=5.6"
- },
- "require-dev": {
- "phpunit/phpunit": "^8.5"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Looks up which function or method a line of code belongs to",
- "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
- "support": {
- "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
- "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2020-11-30T08:15:22+00:00"
- },
- {
- "name": "sebastian/comparator",
- "version": "3.0.3",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/comparator.git",
- "reference": "1071dfcef776a57013124ff35e1fc41ccd294758"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758",
- "reference": "1071dfcef776a57013124ff35e1fc41ccd294758",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1",
- "sebastian/diff": "^3.0",
- "sebastian/exporter": "^3.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^8.5"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- },
- {
- "name": "Jeff Welch",
- "email": "whatthejeff@gmail.com"
- },
- {
- "name": "Volker Dusch",
- "email": "github@wallbash.com"
- },
- {
- "name": "Bernhard Schussek",
- "email": "bschussek@2bepublished.at"
- }
- ],
- "description": "Provides the functionality to compare PHP values for equality",
- "homepage": "https://github.com/sebastianbergmann/comparator",
- "keywords": [
- "comparator",
- "compare",
- "equality"
- ],
- "support": {
- "issues": "https://github.com/sebastianbergmann/comparator/issues",
- "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2020-11-30T08:04:30+00:00"
- },
- {
- "name": "sebastian/diff",
- "version": "3.0.3",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/diff.git",
- "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
- "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^7.5 || ^8.0",
- "symfony/process": "^2 || ^3.3 || ^4"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- },
- {
- "name": "Kore Nordmann",
- "email": "mail@kore-nordmann.de"
- }
- ],
- "description": "Diff implementation",
- "homepage": "https://github.com/sebastianbergmann/diff",
- "keywords": [
- "diff",
- "udiff",
- "unidiff",
- "unified diff"
- ],
- "support": {
- "issues": "https://github.com/sebastianbergmann/diff/issues",
- "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2020-11-30T07:59:04+00:00"
- },
- {
- "name": "sebastian/environment",
- "version": "4.2.4",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/environment.git",
- "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
- "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^7.5"
- },
- "suggest": {
- "ext-posix": "*"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-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/4.2.4"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2020-11-30T07:53:42+00:00"
- },
- {
- "name": "sebastian/exporter",
- "version": "3.1.3",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/exporter.git",
- "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/6b853149eab67d4da22291d36f5b0631c0fd856e",
- "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e",
- "shasum": ""
- },
- "require": {
- "php": ">=7.0",
- "sebastian/recursion-context": "^3.0"
- },
- "require-dev": {
- "ext-mbstring": "*",
- "phpunit/phpunit": "^6.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.1.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- },
- {
- "name": "Jeff Welch",
- "email": "whatthejeff@gmail.com"
- },
- {
- "name": "Volker Dusch",
- "email": "github@wallbash.com"
- },
- {
- "name": "Adam Harvey",
- "email": "aharvey@php.net"
- },
- {
- "name": "Bernhard Schussek",
- "email": "bschussek@gmail.com"
- }
- ],
- "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/3.1.3"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2020-11-30T07:47:53+00:00"
- },
- {
- "name": "sebastian/global-state",
- "version": "2.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/global-state.git",
- "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
- "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
- "shasum": ""
- },
- "require": {
- "php": "^7.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^6.0"
- },
- "suggest": {
- "ext-uopz": "*"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.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/2.0.0"
- },
- "time": "2017-04-27T15:39:26+00:00"
- },
- {
- "name": "sebastian/object-enumerator",
- "version": "3.0.4",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/object-enumerator.git",
- "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
- "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
- "shasum": ""
- },
- "require": {
- "php": ">=7.0",
- "sebastian/object-reflector": "^1.1.1",
- "sebastian/recursion-context": "^3.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^6.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.0.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Traverses array structures and object graphs to enumerate all referenced objects",
- "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
- "support": {
- "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
- "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2020-11-30T07:40:27+00:00"
- },
- {
- "name": "sebastian/object-reflector",
- "version": "1.1.2",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/object-reflector.git",
- "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
- "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
- "shasum": ""
- },
- "require": {
- "php": ">=7.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^6.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.1-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Allows reflection of object attributes, including inherited and non-public ones",
- "homepage": "https://github.com/sebastianbergmann/object-reflector/",
- "support": {
- "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
- "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2020-11-30T07:37:18+00:00"
- },
- {
- "name": "sebastian/recursion-context",
- "version": "3.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/recursion-context.git",
- "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb",
- "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb",
- "shasum": ""
- },
- "require": {
- "php": ">=7.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^6.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.0.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- },
- {
- "name": "Jeff Welch",
- "email": "whatthejeff@gmail.com"
- },
- {
- "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/3.0.1"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2020-11-30T07:34:24+00:00"
- },
- {
- "name": "sebastian/resource-operations",
- "version": "2.0.2",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/resource-operations.git",
- "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3",
- "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Provides a list of PHP built-in functions that operate on resources",
- "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
- "support": {
- "issues": "https://github.com/sebastianbergmann/resource-operations/issues",
- "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "abandoned": true,
- "time": "2020-11-30T07:30:19+00:00"
- },
- {
- "name": "sebastian/version",
- "version": "2.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/version.git",
- "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
- "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
- "shasum": ""
- },
- "require": {
- "php": ">=5.6"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "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/master"
- },
- "time": "2016-10-03T07:35:21+00:00"
- },
- {
- "name": "squizlabs/php_codesniffer",
- "version": "3.6.1",
- "source": {
- "type": "git",
- "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
- "reference": "f268ca40d54617c6e06757f83f699775c9b3ff2e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/f268ca40d54617c6e06757f83f699775c9b3ff2e",
- "reference": "f268ca40d54617c6e06757f83f699775c9b3ff2e",
- "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-10-11T04:00:11+00:00"
- },
- {
- "name": "symfony/finder",
- "version": "v5.3.7",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/finder.git",
- "reference": "a10000ada1e600d109a6c7632e9ac42e8bf2fb93"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/a10000ada1e600d109a6c7632e9ac42e8bf2fb93",
- "reference": "a10000ada1e600d109a6c7632e9ac42e8bf2fb93",
- "shasum": ""
- },
- "require": {
- "php": ">=7.2.5",
- "symfony/polyfill-php80": "^1.16"
- },
- "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.3.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-08-04T21:20:46+00:00"
- },
- {
- "name": "symfony/polyfill-ctype",
- "version": "v1.23.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce",
- "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "suggest": {
- "ext-ctype": "For best performance"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.23-dev"
- },
- "thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Polyfill\\Ctype\\": ""
- },
- "files": [
- "bootstrap.php"
- ]
- },
- "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.23.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-02-19T12:13:01+00:00"
- },
- {
- "name": "symfony/polyfill-php80",
- "version": "v1.23.1",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-php80.git",
- "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be",
- "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.23-dev"
- },
- "thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Polyfill\\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.23.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-07-28T13:41:28+00:00"
- },
- {
- "name": "theseer/tokenizer",
- "version": "1.2.1",
- "source": {
- "type": "git",
- "url": "https://github.com/theseer/tokenizer.git",
- "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
- "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
- "shasum": ""
- },
- "require": {
- "ext-dom": "*",
- "ext-tokenizer": "*",
- "ext-xmlwriter": "*",
- "php": "^7.2 || ^8.0"
- },
- "type": "library",
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Arne Blankerts",
- "email": "arne@blankerts.de",
- "role": "Developer"
- }
- ],
- "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
- "support": {
- "issues": "https://github.com/theseer/tokenizer/issues",
- "source": "https://github.com/theseer/tokenizer/tree/1.2.1"
- },
- "funding": [
- {
- "url": "https://github.com/theseer",
- "type": "github"
- }
- ],
- "time": "2021-07-28T10:34:58+00:00"
- },
- {
- "name": "webmozart/assert",
- "version": "1.10.0",
- "source": {
- "type": "git",
- "url": "https://github.com/webmozarts/assert.git",
- "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25",
- "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25",
- "shasum": ""
- },
- "require": {
- "php": "^7.2 || ^8.0",
- "symfony/polyfill-ctype": "^1.8"
- },
- "conflict": {
- "phpstan/phpstan": "<0.12.20",
- "vimeo/psalm": "<4.6.1 || 4.6.2"
- },
- "require-dev": {
- "phpunit/phpunit": "^8.5.13"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.10-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Webmozart\\Assert\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Bernhard Schussek",
- "email": "bschussek@gmail.com"
- }
- ],
- "description": "Assertions to validate method input/output with nice error messages.",
- "keywords": [
- "assert",
- "check",
- "validate"
- ],
- "support": {
- "issues": "https://github.com/webmozarts/assert/issues",
- "source": "https://github.com/webmozarts/assert/tree/1.10.0"
- },
- "time": "2021-03-09T10:59:23+00:00"
- },
- {
- "name": "woocommerce/woocommerce-sniffs",
- "version": "0.1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/woocommerce/woocommerce-sniffs.git",
- "reference": "b72b7dd2e70aa6aed16f80cdae5b1e6cce2e4c79"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/woocommerce/woocommerce-sniffs/zipball/b72b7dd2e70aa6aed16f80cdae5b1e6cce2e4c79",
- "reference": "b72b7dd2e70aa6aed16f80cdae5b1e6cce2e4c79",
- "shasum": ""
- },
- "require": {
- "dealerdirect/phpcodesniffer-composer-installer": "0.7.0",
- "php": ">=7.0",
- "phpcompatibility/phpcompatibility-wp": "2.1.0",
- "wp-coding-standards/wpcs": "2.3.0"
- },
- "type": "phpcodesniffer-standard",
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Claudio Sanches",
- "email": "claudio@automattic.com"
- }
- ],
- "description": "WooCommerce sniffs",
- "keywords": [
- "phpcs",
- "standards",
- "woocommerce",
- "wordpress"
- ],
- "support": {
- "issues": "https://github.com/woocommerce/woocommerce-sniffs/issues",
- "source": "https://github.com/woocommerce/woocommerce-sniffs/tree/master"
- },
- "time": "2020-08-06T18:23:45+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/php-cli-tools",
- "version": "v0.11.13",
- "source": {
- "type": "git",
- "url": "https://github.com/wp-cli/php-cli-tools.git",
- "reference": "a2866855ac1abc53005c102e901553ad5772dc04"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/a2866855ac1abc53005c102e901553ad5772dc04",
- "reference": "a2866855ac1abc53005c102e901553ad5772dc04",
- "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.13"
- },
- "time": "2021-07-01T15:08:16+00:00"
- },
- {
- "name": "wp-cli/wp-cli",
- "version": "v2.5.0",
- "source": {
- "type": "git",
- "url": "https://github.com/wp-cli/wp-cli.git",
- "reference": "0bcf0c54f4d35685211d435e25219cc7acbe6d48"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/wp-cli/wp-cli/zipball/0bcf0c54f4d35685211d435e25219cc7acbe6d48",
- "reference": "0bcf0c54f4d35685211d435e25219cc7acbe6d48",
- "shasum": ""
- },
- "require": {
- "ext-curl": "*",
- "mustache/mustache": "~2.13",
- "php": "^5.6 || ^7.0 || ^8.0",
- "rmccue/requests": "^1.8",
- "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": "^3.0.7"
- },
- "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.5.x-dev"
- }
- },
- "autoload": {
- "psr-0": {
- "WP_CLI\\": "php/"
- },
- "classmap": [
- "php/class-wp-cli.php",
- "php/class-wp-cli-command.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": "2021-05-14T13:44:51+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": "yoast/phpunit-polyfills",
- "version": "1.0.2",
- "source": {
- "type": "git",
- "url": "https://github.com/Yoast/PHPUnit-Polyfills.git",
- "reference": "1a582ab1d91e86aa450340c4d35631a85314ff9f"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/1a582ab1d91e86aa450340c4d35631a85314ff9f",
- "reference": "1a582ab1d91e86aa450340c4d35631a85314ff9f",
- "shasum": ""
- },
- "require": {
- "php": ">=5.4",
- "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0"
- },
- "require-dev": {
- "yoast/yoastcs": "^2.2.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.x-dev",
- "dev-develop": "1.x-dev"
- }
- },
- "autoload": {
- "files": [
- "phpunitpolyfills-autoload.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Team Yoast",
- "email": "support@yoast.com",
- "homepage": "https://yoast.com"
- },
- {
- "name": "Contributors",
- "homepage": "https://github.com/Yoast/PHPUnit-Polyfills/graphs/contributors"
- }
- ],
- "description": "Set of polyfills for changed PHPUnit functionality to allow for creating PHPUnit cross-version compatible tests",
- "homepage": "https://github.com/Yoast/PHPUnit-Polyfills",
- "keywords": [
- "phpunit",
- "polyfill",
- "testing"
- ],
- "support": {
- "issues": "https://github.com/Yoast/PHPUnit-Polyfills/issues",
- "source": "https://github.com/Yoast/PHPUnit-Polyfills"
- },
- "time": "2021-10-03T08:40:26+00:00"
- }
- ],
- "aliases": [],
- "minimum-stability": "dev",
- "stability-flags": [],
- "prefer-stable": true,
- "prefer-lowest": false,
- "platform": [],
- "platform-dev": [],
- "platform-overrides": {
- "php": "7.3"
- },
- "plugin-api-version": "2.2.0"
-}
diff --git a/src/libraries/action-scheduler/deprecated/ActionScheduler_AdminView_Deprecated.php b/src/libraries/action-scheduler/deprecated/ActionScheduler_AdminView_Deprecated.php
index 1d8f6fd4e1..69b46d7bd4 100644
--- a/src/libraries/action-scheduler/deprecated/ActionScheduler_AdminView_Deprecated.php
+++ b/src/libraries/action-scheduler/deprecated/ActionScheduler_AdminView_Deprecated.php
@@ -68,7 +68,7 @@ public static function list_table_sortable_columns( $columns ) {
* Print the content for our custom columns.
*
* @param string $column_name The key for the column for which we should output our content.
- * @param int $post_id The ID of the 'scheduled-action' post for which this row relates.
+ * @param int $post_id The ID of the 'scheduled-action' post for which this row relates.
*/
public static function list_table_column_content( $column_name, $post_id ) {
_deprecated_function( __METHOD__, '2.0.0' );
@@ -115,18 +115,18 @@ public static function admin_notices() {
/**
* Filter search queries to allow searching by Claim ID (i.e. post_password).
*
- * @param string $orderby MySQL orderby string.
+ * @param string $orderby MySQL orderby string.
* @param WP_Query $query Instance of a WP_Query object
* @return string MySQL orderby string.
*/
- public function custom_orderby( $orderby, $query ) {
+ public function custom_orderby( $orderby, $query ){
_deprecated_function( __METHOD__, '2.0.0' );
}
/**
* Filter search queries to allow searching by Claim ID (i.e. post_password).
*
- * @param string $search MySQL search string.
+ * @param string $search MySQL search string.
* @param WP_Query $query Instance of a WP_Query object
* @return string MySQL search string.
*/
@@ -144,4 +144,4 @@ public function post_updated_messages( $messages ) {
_deprecated_function( __METHOD__, '2.0.0' );
return $messages;
}
-}
+}
\ No newline at end of file
diff --git a/src/libraries/action-scheduler/deprecated/ActionScheduler_Store_Deprecated.php b/src/libraries/action-scheduler/deprecated/ActionScheduler_Store_Deprecated.php
index 02dc8b7c12..002dc75b41 100644
--- a/src/libraries/action-scheduler/deprecated/ActionScheduler_Store_Deprecated.php
+++ b/src/libraries/action-scheduler/deprecated/ActionScheduler_Store_Deprecated.php
@@ -2,7 +2,6 @@
/**
* Class ActionScheduler_Store_Deprecated
- *
* @codeCoverageIgnore
*/
abstract class ActionScheduler_Store_Deprecated {
diff --git a/src/libraries/action-scheduler/deprecated/functions.php b/src/libraries/action-scheduler/deprecated/functions.php
index 8a1c90f56d..f782c4b7f0 100644
--- a/src/libraries/action-scheduler/deprecated/functions.php
+++ b/src/libraries/action-scheduler/deprecated/functions.php
@@ -11,9 +11,9 @@
/**
* Schedule an action to run one time
*
- * @param int $timestamp When the job will run
+ * @param int $timestamp When the job will run
* @param string $hook The hook to trigger
- * @param array $args Arguments to pass when the hook triggers
+ * @param array $args Arguments to pass when the hook triggers
* @param string $group The group to assign this job to
*
* @return string The job ID
@@ -26,10 +26,10 @@ function wc_schedule_single_action( $timestamp, $hook, $args = array(), $group =
/**
* Schedule a recurring action
*
- * @param int $timestamp When the first instance of the job will run
- * @param int $interval_in_seconds How long to wait between runs
+ * @param int $timestamp When the first instance of the job will run
+ * @param int $interval_in_seconds How long to wait between runs
* @param string $hook The hook to trigger
- * @param array $args Arguments to pass when the hook triggers
+ * @param array $args Arguments to pass when the hook triggers
* @param string $group The group to assign this job to
*
* @deprecated 2.1.0
@@ -44,7 +44,7 @@ function wc_schedule_recurring_action( $timestamp, $interval_in_seconds, $hook,
/**
* Schedule an action that recurs on a cron-like schedule.
*
- * @param int $timestamp The schedule will start on or after this time
+ * @param int $timestamp The schedule will start on or after this time
* @param string $schedule A cron-link schedule string
* @see http://en.wikipedia.org/wiki/Cron
* * * * * * *
@@ -57,7 +57,7 @@ function wc_schedule_recurring_action( $timestamp, $interval_in_seconds, $hook,
* | +-------------------- hour (0 - 23)
* +------------------------- min (0 - 59)
* @param string $hook The hook to trigger
- * @param array $args Arguments to pass when the hook triggers
+ * @param array $args Arguments to pass when the hook triggers
* @param string $group The group to assign this job to
*
* @deprecated 2.1.0
@@ -73,7 +73,7 @@ function wc_schedule_cron_action( $timestamp, $schedule, $hook, $args = array(),
* Cancel the next occurrence of a job.
*
* @param string $hook The hook that the job will trigger
- * @param array $args Args that would have been passed to the job
+ * @param array $args Args that would have been passed to the job
* @param string $group
*
* @deprecated 2.1.0
@@ -85,14 +85,14 @@ function wc_unschedule_action( $hook, $args = array(), $group = '' ) {
/**
* @param string $hook
- * @param array $args
+ * @param array $args
* @param string $group
*
* @deprecated 2.1.0
*
* @return int|bool The timestamp for the next occurrence, or false if nothing was found
*/
-function wc_next_scheduled_action( $hook, $args = null, $group = '' ) {
+function wc_next_scheduled_action( $hook, $args = NULL, $group = '' ) {
_deprecated_function( __FUNCTION__, '2.1.0', 'as_next_scheduled_action()' );
return as_next_scheduled_action( $hook, $args, $group );
}
@@ -100,20 +100,20 @@ function wc_next_scheduled_action( $hook, $args = null, $group = '' ) {
/**
* Find scheduled actions
*
- * @param array $args Possible arguments, with their default values:
- * 'hook' => '' - the name of the action that will be triggered
- * 'args' => NULL - the args array that will be passed with the action
- * 'date' => NULL - the scheduled date of the action. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone.
- * 'date_compare' => '<=' - operator for testing "date". accepted values are '!=', '>', '>=', '<', '<=', '='
- * 'modified' => NULL - the date the action was last updated. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone.
- * 'modified_compare' => '<=' - operator for testing "modified". accepted values are '!=', '>', '>=', '<', '<=', '='
- * 'group' => '' - the group the action belongs to
- * 'status' => '' - ActionScheduler_Store::STATUS_COMPLETE or ActionScheduler_Store::STATUS_PENDING
- * 'claimed' => NULL - TRUE to find claimed actions, FALSE to find unclaimed actions, a string to find a specific claim ID
- * 'per_page' => 5 - Number of results to return
- * 'offset' => 0
- * 'orderby' => 'date' - accepted values are 'hook', 'group', 'modified', or 'date'
- * 'order' => 'ASC'
+ * @param array $args Possible arguments, with their default values:
+ * 'hook' => '' - the name of the action that will be triggered
+ * 'args' => NULL - the args array that will be passed with the action
+ * 'date' => NULL - the scheduled date of the action. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone.
+ * 'date_compare' => '<=' - operator for testing "date". accepted values are '!=', '>', '>=', '<', '<=', '='
+ * 'modified' => NULL - the date the action was last updated. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone.
+ * 'modified_compare' => '<=' - operator for testing "modified". accepted values are '!=', '>', '>=', '<', '<=', '='
+ * 'group' => '' - the group the action belongs to
+ * 'status' => '' - ActionScheduler_Store::STATUS_COMPLETE or ActionScheduler_Store::STATUS_PENDING
+ * 'claimed' => NULL - TRUE to find claimed actions, FALSE to find unclaimed actions, a string to find a specific claim ID
+ * 'per_page' => 5 - Number of results to return
+ * 'offset' => 0
+ * 'orderby' => 'date' - accepted values are 'hook', 'group', 'modified', or 'date'
+ * 'order' => 'ASC'
* @param string $return_format OBJECT, ARRAY_A, or ids
*
* @deprecated 2.1.0
diff --git a/src/libraries/action-scheduler/docs/CNAME b/src/libraries/action-scheduler/docs/CNAME
deleted file mode 100644
index 3b480b54c7..0000000000
--- a/src/libraries/action-scheduler/docs/CNAME
+++ /dev/null
@@ -1 +0,0 @@
-actionscheduler.org
\ No newline at end of file
diff --git a/src/libraries/action-scheduler/docs/_config.yml b/src/libraries/action-scheduler/docs/_config.yml
deleted file mode 100644
index fe521d98c3..0000000000
--- a/src/libraries/action-scheduler/docs/_config.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-title: Action Scheduler - Job Queue for WordPress
-description: A scalable, traceable job queue for background processing large queues of tasks in WordPress. Designed for distribution in WordPress plugins - no server access required.
-theme: jekyll-theme-hacker
-permalink: /:slug/
-plugins:
- - jekyll-seo-tag
- - jekyll-sitemap
diff --git a/src/libraries/action-scheduler/docs/_layouts/default.html b/src/libraries/action-scheduler/docs/_layouts/default.html
deleted file mode 100644
index 3559804820..0000000000
--- a/src/libraries/action-scheduler/docs/_layouts/default.html
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-{% seo %}
-
-
-
-
- Usage | Admin | WP-CLI | Background Processing at Scale | API | FAQ | Version 3.0 -
+ */ +interface CacheInterface +{ + /** + * Fetches a value from the pool or computes it if not found. + * + * On cache misses, a callback is called that should return the missing value. + * This callback is given a PSR-6 CacheItemInterface instance corresponding to the + * requested key, that could be used e.g. for expiration control. It could also + * be an ItemInterface instance when its additional features are needed. + * + * @param string $key The key of the item to retrieve from the cache + * @param callable|CallbackInterface $callback Should return the computed value for the given key/item + * @param float|null $beta A float that, as it grows, controls the likeliness of triggering + * early expiration. 0 disables it, INF forces immediate expiration. + * The default (or providing null) is implementation dependent but should + * typically be 1.0, which should provide optimal stampede protection. + * See https://en.wikipedia.org/wiki/Cache_stampede#Probabilistic_early_expiration + * @param array &$metadata The metadata of the cached item {@see ItemInterface::getMetadata()} + * + * @return mixed + * + * @throws InvalidArgumentException When $key is not valid or when $beta is negative + */ + public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null); + /** + * Removes an item from the pool. + * + * @param string $key The key to delete + * + * @return bool True if the item was successfully removed, false if there was any error + * + * @throws InvalidArgumentException When $key is not valid + */ + public function delete(string $key): bool; +} diff --git a/src/modules/common/third-party/vendor/symfony/cache-contracts/CacheTrait.php b/src/modules/common/third-party/vendor/symfony/cache-contracts/CacheTrait.php new file mode 100644 index 0000000000..ff7be0a42e --- /dev/null +++ b/src/modules/common/third-party/vendor/symfony/cache-contracts/CacheTrait.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace Wordlift\Modules\Common\Symfony\Contracts\Cache; + +use Wordlift\Modules\Common\Psr\Cache\CacheItemPoolInterface; +use Wordlift\Modules\Common\Psr\Cache\InvalidArgumentException; +use Wordlift\Modules\Common\Psr\Log\LoggerInterface; +// Help opcache.preload discover always-needed symbols +class_exists(InvalidArgumentException::class); +/** + * An implementation of CacheInterface for PSR-6 CacheItemPoolInterface classes. + * + * @author Nicolas Grekas
+ */ +trait CacheTrait +{ + /** + * {@inheritdoc} + * + * @return mixed + */ + public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null) + { + return $this->doGet($this, $key, $callback, $beta, $metadata); + } + /** + * {@inheritdoc} + */ + public function delete(string $key): bool + { + return $this->deleteItem($key); + } + private function doGet(CacheItemPoolInterface $pool, string $key, callable $callback, ?float $beta, ?array &$metadata = null, ?LoggerInterface $logger = null) + { + if (0 > $beta = $beta ?? 1.0) { + throw new class(sprintf('Argument "$beta" provided to "%s::get()" must be a positive number, %f given.', static::class, $beta)) extends \InvalidArgumentException implements InvalidArgumentException + { + }; + } + $item = $pool->getItem($key); + $recompute = !$item->isHit() || \INF === $beta; + $metadata = ($item instanceof ItemInterface) ? $item->getMetadata() : []; + if (!$recompute && $metadata) { + $expiry = $metadata[ItemInterface::METADATA_EXPIRY] ?? \false; + $ctime = $metadata[ItemInterface::METADATA_CTIME] ?? \false; + if ($recompute = $ctime && $expiry && $expiry <= ($now = microtime(\true)) - $ctime / 1000 * $beta * log(random_int(1, \PHP_INT_MAX) / \PHP_INT_MAX)) { + // force applying defaultLifetime to expiry + $item->expiresAt(null); + $logger && $logger->info('Item "{key}" elected for early recomputation {delta}s before its expiration', ['key' => $key, 'delta' => sprintf('%.1f', $expiry - $now)]); + } + } + if ($recompute) { + $save = \true; + $item->set($callback($item, $save)); + if ($save) { + $pool->save($item); + } + } + return $item->get(); + } +} diff --git a/src/modules/common/third-party/vendor/symfony/cache-contracts/CallbackInterface.php b/src/modules/common/third-party/vendor/symfony/cache-contracts/CallbackInterface.php new file mode 100644 index 0000000000..6d46f040c2 --- /dev/null +++ b/src/modules/common/third-party/vendor/symfony/cache-contracts/CallbackInterface.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace Wordlift\Modules\Common\Symfony\Contracts\Cache; + +use Wordlift\Modules\Common\Psr\Cache\CacheItemInterface; +/** + * Computes and returns the cached value of an item. + * + * @author Nicolas Grekas
+ */ +interface CallbackInterface +{ + /** + * @param CacheItemInterface|ItemInterface $item The item to compute the value for + * @param bool &$save Should be set to false when the value should not be saved in the pool + * + * @return mixed The computed value for the passed item + */ + public function __invoke(CacheItemInterface $item, bool &$save); +} diff --git a/src/modules/common/third-party/vendor/symfony/cache-contracts/ItemInterface.php b/src/modules/common/third-party/vendor/symfony/cache-contracts/ItemInterface.php new file mode 100644 index 0000000000..c6c0f4f920 --- /dev/null +++ b/src/modules/common/third-party/vendor/symfony/cache-contracts/ItemInterface.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace Wordlift\Modules\Common\Symfony\Contracts\Cache; + +use Wordlift\Modules\Common\Psr\Cache\CacheException; +use Wordlift\Modules\Common\Psr\Cache\CacheItemInterface; +use Wordlift\Modules\Common\Psr\Cache\InvalidArgumentException; +/** + * Augments PSR-6's CacheItemInterface with support for tags and metadata. + * + * @author Nicolas Grekas
+ */ +interface ItemInterface extends CacheItemInterface +{ + /** + * References the Unix timestamp stating when the item will expire. + */ + public const METADATA_EXPIRY = 'expiry'; + /** + * References the time the item took to be created, in milliseconds. + */ + public const METADATA_CTIME = 'ctime'; + /** + * References the list of tags that were assigned to the item, as string[]. + */ + public const METADATA_TAGS = 'tags'; + /** + * Reserved characters that cannot be used in a key or tag. + */ + public const RESERVED_CHARACTERS = '{}()/\@:'; + /** + * Adds a tag to a cache item. + * + * Tags are strings that follow the same validation rules as keys. + * + * @param string|string[] $tags A tag or array of tags + * + * @return $this + * + * @throws InvalidArgumentException When $tag is not valid + * @throws CacheException When the item comes from a pool that is not tag-aware + */ + public function tag($tags): self; + /** + * Returns a list of metadata info that were saved alongside with the cached value. + * + * See ItemInterface::METADATA_* consts for keys potentially found in the returned array. + */ + public function getMetadata(): array; +} diff --git a/src/modules/common/third-party/vendor/symfony/cache-contracts/TagAwareCacheInterface.php b/src/modules/common/third-party/vendor/symfony/cache-contracts/TagAwareCacheInterface.php new file mode 100644 index 0000000000..3932e29a69 --- /dev/null +++ b/src/modules/common/third-party/vendor/symfony/cache-contracts/TagAwareCacheInterface.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace Wordlift\Modules\Common\Symfony\Contracts\Cache; + +use Wordlift\Modules\Common\Psr\Cache\InvalidArgumentException; +/** + * Allows invalidating cached items using tags. + * + * @author Nicolas Grekas
+ */ +interface TagAwareCacheInterface extends CacheInterface +{ + /** + * Invalidates cached items using tags. + * + * When implemented on a PSR-6 pool, invalidation should not apply + * to deferred items. Instead, they should be committed as usual. + * This allows replacing old tagged values by new ones without + * race conditions. + * + * @param string[] $tags An array of tags to invalidate + * + * @return bool True on success + * + * @throws InvalidArgumentException When $tags is not valid + */ + public function invalidateTags(array $tags); +} diff --git a/src/modules/common/third-party/vendor/symfony/cache-contracts/composer.json b/src/modules/common/third-party/vendor/symfony/cache-contracts/composer.json new file mode 100644 index 0000000000..68212e3581 --- /dev/null +++ b/src/modules/common/third-party/vendor/symfony/cache-contracts/composer.json @@ -0,0 +1,47 @@ +{ + "name": "symfony\/cache-contracts", + "type": "library", + "description": "Generic abstractions related to caching", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "homepage": "https:\/\/symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "require": { + "php": ">=7.2.5", + "psr\/cache": "^1.0|^2.0|^3.0" + }, + "suggest": { + "symfony\/cache-implementation": "" + }, + "autoload": { + "psr-4": { + "Wordlift\\Modules\\Common\\Symfony\\Contracts\\Cache\\": "" + } + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony\/contracts", + "url": "https:\/\/github.com\/symfony\/contracts" + } + } +} \ No newline at end of file diff --git a/src/modules/common/third-party/vendor/symfony/cache/Adapter/AbstractAdapter.php b/src/modules/common/third-party/vendor/symfony/cache/Adapter/AbstractAdapter.php new file mode 100644 index 0000000000..3be6fbbb63 --- /dev/null +++ b/src/modules/common/third-party/vendor/symfony/cache/Adapter/AbstractAdapter.php @@ -0,0 +1,180 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace Wordlift\Modules\Common\Symfony\Component\Cache\Adapter; + +use Wordlift\Modules\Common\Psr\Log\LoggerAwareInterface; +use Wordlift\Modules\Common\Psr\Log\LoggerInterface; +use Wordlift\Modules\Common\Symfony\Component\Cache\CacheItem; +use Wordlift\Modules\Common\Symfony\Component\Cache\Exception\InvalidArgumentException; +use Wordlift\Modules\Common\Symfony\Component\Cache\ResettableInterface; +use Wordlift\Modules\Common\Symfony\Component\Cache\Traits\AbstractAdapterTrait; +use Wordlift\Modules\Common\Symfony\Component\Cache\Traits\ContractsTrait; +use Wordlift\Modules\Common\Symfony\Contracts\Cache\CacheInterface; +/** + * @author Nicolas Grekas
+ */ +abstract class AbstractAdapter implements AdapterInterface, CacheInterface, LoggerAwareInterface, ResettableInterface +{ + use AbstractAdapterTrait; + use ContractsTrait; + /** + * @internal + */ + protected const NS_SEPARATOR = ':'; + private static $apcuSupported; + private static $phpFilesSupported; + protected function __construct(string $namespace = '', int $defaultLifetime = 0) + { + $this->namespace = ('' === $namespace) ? '' : (CacheItem::validateKey($namespace) . static::NS_SEPARATOR); + $this->defaultLifetime = $defaultLifetime; + if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) { + throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s").', $this->maxIdLength - 24, \strlen($namespace), $namespace)); + } + self::$createCacheItem ?? self::$createCacheItem = \Closure::bind(static function ($key, $value, $isHit) { + $item = new CacheItem(); + $item->key = $key; + $item->value = $v = $value; + $item->isHit = $isHit; + // Detect wrapped values that encode for their expiry and creation duration + // For compactness, these values are packed in the key of an array using + // magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F + if (\is_array($v) && 1 === \count($v) && 10 === \strlen($k = (string) array_key_first($v)) && "\x9d" === $k[0] && "\x00" === $k[5] && "_" === $k[9]) { + $item->value = $v[$k]; + $v = unpack('Ve/Nc', substr($k, 1, -1)); + $item->metadata[CacheItem::METADATA_EXPIRY] = $v['e'] + CacheItem::METADATA_EXPIRY_OFFSET; + $item->metadata[CacheItem::METADATA_CTIME] = $v['c']; + } + return $item; + }, null, CacheItem::class); + self::$mergeByLifetime ?? self::$mergeByLifetime = \Closure::bind(static function ($deferred, $namespace, &$expiredIds, $getId, $defaultLifetime) { + $byLifetime = []; + $now = microtime(\true); + $expiredIds = []; + foreach ($deferred as $key => $item) { + $key = (string) $key; + if (null === $item->expiry) { + $ttl = (0 < $defaultLifetime) ? $defaultLifetime : 0; + } elseif (!$item->expiry) { + $ttl = 0; + } elseif (0 >= $ttl = (int) (0.1 + $item->expiry - $now)) { + $expiredIds[] = $getId($key); + continue; + } + if (isset(($metadata = $item->newMetadata)[CacheItem::METADATA_TAGS])) { + unset($metadata[CacheItem::METADATA_TAGS]); + } + // For compactness, expiry and creation duration are packed in the key of an array, using magic numbers as separators + $byLifetime[$ttl][$getId($key)] = $metadata ? ["\x9d" . pack('VN', (int) (0.1 + $metadata[self::METADATA_EXPIRY] - self::METADATA_EXPIRY_OFFSET), $metadata[self::METADATA_CTIME]) . "_" => $item->value] : $item->value; + } + return $byLifetime; + }, null, CacheItem::class); + } + /** + * Returns the best possible adapter that your runtime supports. + * + * Using ApcuAdapter makes system caches compatible with read-only filesystems. + * + * @return AdapterInterface + */ + public static function createSystemCache(string $namespace, int $defaultLifetime, string $version, string $directory, ?LoggerInterface $logger = null) + { + $opcache = new PhpFilesAdapter($namespace, $defaultLifetime, $directory, \true); + if (null !== $logger) { + $opcache->setLogger($logger); + } + if (!self::$apcuSupported = self::$apcuSupported ?? ApcuAdapter::isSupported()) { + return $opcache; + } + if (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], \true) && !filter_var(\ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN)) { + return $opcache; + } + $apcu = new ApcuAdapter($namespace, intdiv($defaultLifetime, 5), $version); + if (null !== $logger) { + $apcu->setLogger($logger); + } + return new ChainAdapter([$apcu, $opcache]); + } + public static function createConnection(string $dsn, array $options = []) + { + if (str_starts_with($dsn, 'redis:') || str_starts_with($dsn, 'rediss:')) { + return RedisAdapter::createConnection($dsn, $options); + } + if (str_starts_with($dsn, 'memcached:')) { + return MemcachedAdapter::createConnection($dsn, $options); + } + if (0 === strpos($dsn, 'couchbase:')) { + if (CouchbaseBucketAdapter::isSupported()) { + return CouchbaseBucketAdapter::createConnection($dsn, $options); + } + return CouchbaseCollectionAdapter::createConnection($dsn, $options); + } + throw new InvalidArgumentException('Unsupported DSN: it does not start with "redis[s]:", "memcached:" nor "couchbase:".'); + } + /** + * {@inheritdoc} + * + * @return bool + */ + public function commit() + { + $ok = \true; + $byLifetime = (self::$mergeByLifetime)($this->deferred, $this->namespace, $expiredIds, \Closure::fromCallable([$this, 'getId']), $this->defaultLifetime); + $retry = $this->deferred = []; + if ($expiredIds) { + try { + $this->doDelete($expiredIds); + } catch (\Exception $e) { + $ok = \false; + CacheItem::log($this->logger, 'Failed to delete expired items: ' . $e->getMessage(), ['exception' => $e, 'cache-adapter' => get_debug_type($this)]); + } + } + foreach ($byLifetime as $lifetime => $values) { + try { + $e = $this->doSave($values, $lifetime); + } catch (\Exception $e) { + } + if (\true === $e || [] === $e) { + continue; + } + if (\is_array($e) || 1 === \count($values)) { + foreach (\is_array($e) ? $e : array_keys($values) as $id) { + $ok = \false; + $v = $values[$id]; + $type = get_debug_type($v); + $message = sprintf('Failed to save key "{key}" of type %s%s', $type, ($e instanceof \Exception) ? ': ' . $e->getMessage() : '.'); + CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => ($e instanceof \Exception) ? $e : null, 'cache-adapter' => get_debug_type($this)]); + } + } else { + foreach ($values as $id => $v) { + $retry[$lifetime][] = $id; + } + } + } + // When bulk-save failed, retry each item individually + foreach ($retry as $lifetime => $ids) { + foreach ($ids as $id) { + try { + $v = $byLifetime[$lifetime][$id]; + $e = $this->doSave([$id => $v], $lifetime); + } catch (\Exception $e) { + } + if (\true === $e || [] === $e) { + continue; + } + $ok = \false; + $type = get_debug_type($v); + $message = sprintf('Failed to save key "{key}" of type %s%s', $type, ($e instanceof \Exception) ? ': ' . $e->getMessage() : '.'); + CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => ($e instanceof \Exception) ? $e : null, 'cache-adapter' => get_debug_type($this)]); + } + } + return $ok; + } +} diff --git a/src/modules/common/third-party/vendor/symfony/cache/Adapter/AbstractTagAwareAdapter.php b/src/modules/common/third-party/vendor/symfony/cache/Adapter/AbstractTagAwareAdapter.php new file mode 100644 index 0000000000..27ef8097be --- /dev/null +++ b/src/modules/common/third-party/vendor/symfony/cache/Adapter/AbstractTagAwareAdapter.php @@ -0,0 +1,287 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace Wordlift\Modules\Common\Symfony\Component\Cache\Adapter; + +use Wordlift\Modules\Common\Psr\Log\LoggerAwareInterface; +use Wordlift\Modules\Common\Symfony\Component\Cache\CacheItem; +use Wordlift\Modules\Common\Symfony\Component\Cache\Exception\InvalidArgumentException; +use Wordlift\Modules\Common\Symfony\Component\Cache\ResettableInterface; +use Wordlift\Modules\Common\Symfony\Component\Cache\Traits\AbstractAdapterTrait; +use Wordlift\Modules\Common\Symfony\Component\Cache\Traits\ContractsTrait; +use Wordlift\Modules\Common\Symfony\Contracts\Cache\TagAwareCacheInterface; +/** + * Abstract for native TagAware adapters. + * + * To keep info on tags, the tags are both serialized as part of cache value and provided as tag ids + * to Adapters on operations when needed for storage to doSave(), doDelete() & doInvalidate(). + * + * @author Nicolas Grekas
+ * @author André Rømcke
+ */
+class ApcuAdapter extends AbstractAdapter
+{
+ private $marshaller;
+ /**
+ * @throws CacheException if APCu is not enabled
+ */
+ public function __construct(string $namespace = '', int $defaultLifetime = 0, ?string $version = null, ?MarshallerInterface $marshaller = null)
+ {
+ if (!static::isSupported()) {
+ throw new CacheException('APCu is not enabled.');
+ }
+ if ('cli' === \PHP_SAPI) {
+ ini_set('apc.use_request_time', 0);
+ }
+ parent::__construct($namespace, $defaultLifetime);
+ if (null !== $version) {
+ CacheItem::validateKey($version);
+ if (!apcu_exists($version . '@' . $namespace)) {
+ $this->doClear($namespace);
+ apcu_add($version . '@' . $namespace, null);
+ }
+ }
+ $this->marshaller = $marshaller;
+ }
+ public static function isSupported()
+ {
+ return \function_exists('apcu_fetch') && filter_var(\ini_get('apc.enabled'), \FILTER_VALIDATE_BOOLEAN);
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doFetch(array $ids)
+ {
+ $unserializeCallbackHandler = ini_set('unserialize_callback_func', __CLASS__ . '::handleUnserializeCallback');
+ try {
+ $values = [];
+ $ids = array_flip($ids);
+ foreach (apcu_fetch(array_keys($ids), $ok) ?: [] as $k => $v) {
+ if (!isset($ids[$k])) {
+ // work around https://github.com/krakjoe/apcu/issues/247
+ $k = key($ids);
+ }
+ unset($ids[$k]);
+ if (null !== $v || $ok) {
+ $values[$k] = (null !== $this->marshaller) ? $this->marshaller->unmarshall($v) : $v;
+ }
+ }
+ return $values;
+ } catch (\Error $e) {
+ throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine());
+ } finally {
+ ini_set('unserialize_callback_func', $unserializeCallbackHandler);
+ }
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doHave(string $id)
+ {
+ return apcu_exists($id);
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doClear(string $namespace)
+ {
+ return (isset($namespace[0]) && class_exists(\APCUIterator::class, \false) && ('cli' !== \PHP_SAPI || filter_var(\ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN))) ? apcu_delete(new \APCUIterator(sprintf('/^%s/', preg_quote($namespace, '/')), \APC_ITER_KEY)) : apcu_clear_cache();
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doDelete(array $ids)
+ {
+ foreach ($ids as $id) {
+ apcu_delete($id);
+ }
+ return \true;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doSave(array $values, int $lifetime)
+ {
+ if (null !== $this->marshaller && !$values = $this->marshaller->marshall($values, $failed)) {
+ return $failed;
+ }
+ try {
+ if (\false === $failures = apcu_store($values, null, $lifetime)) {
+ $failures = $values;
+ }
+ return array_keys($failures);
+ } catch (\Throwable $e) {
+ if (1 === \count($values)) {
+ // Workaround https://github.com/krakjoe/apcu/issues/170
+ apcu_delete(array_key_first($values));
+ }
+ throw $e;
+ }
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Adapter/ArrayAdapter.php b/src/modules/common/third-party/vendor/symfony/cache/Adapter/ArrayAdapter.php
new file mode 100644
index 0000000000..4a76359190
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Adapter/ArrayAdapter.php
@@ -0,0 +1,346 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Adapter;
+
+use Wordlift\Modules\Common\Psr\Cache\CacheItemInterface;
+use Wordlift\Modules\Common\Psr\Log\LoggerAwareInterface;
+use Wordlift\Modules\Common\Psr\Log\LoggerAwareTrait;
+use Wordlift\Modules\Common\Symfony\Component\Cache\CacheItem;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Exception\InvalidArgumentException;
+use Wordlift\Modules\Common\Symfony\Component\Cache\ResettableInterface;
+use Wordlift\Modules\Common\Symfony\Contracts\Cache\CacheInterface;
+/**
+ * An in-memory cache storage.
+ *
+ * Acts as a least-recently-used (LRU) storage when configured with a maximum number of items.
+ *
+ * @author Nicolas Grekas
+ */
+class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInterface, ResettableInterface
+{
+ use LoggerAwareTrait;
+ private $storeSerialized;
+ private $values = [];
+ private $expiries = [];
+ private $defaultLifetime;
+ private $maxLifetime;
+ private $maxItems;
+ private static $createCacheItem;
+ /**
+ * @param bool $storeSerialized Disabling serialization can lead to cache corruptions when storing mutable values but increases performance otherwise
+ */
+ public function __construct(int $defaultLifetime = 0, bool $storeSerialized = \true, float $maxLifetime = 0, int $maxItems = 0)
+ {
+ if (0 > $maxLifetime) {
+ throw new InvalidArgumentException(sprintf('Argument $maxLifetime must be positive, %F passed.', $maxLifetime));
+ }
+ if (0 > $maxItems) {
+ throw new InvalidArgumentException(sprintf('Argument $maxItems must be a positive integer, %d passed.', $maxItems));
+ }
+ $this->defaultLifetime = $defaultLifetime;
+ $this->storeSerialized = $storeSerialized;
+ $this->maxLifetime = $maxLifetime;
+ $this->maxItems = $maxItems;
+ self::$createCacheItem ?? self::$createCacheItem = \Closure::bind(static function ($key, $value, $isHit) {
+ $item = new CacheItem();
+ $item->key = $key;
+ $item->value = $value;
+ $item->isHit = $isHit;
+ return $item;
+ }, null, CacheItem::class);
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null)
+ {
+ $item = $this->getItem($key);
+ $metadata = $item->getMetadata();
+ // ArrayAdapter works in memory, we don't care about stampede protection
+ if (\INF === $beta || !$item->isHit()) {
+ $save = \true;
+ $item->set($callback($item, $save));
+ if ($save) {
+ $this->save($item);
+ }
+ }
+ return $item->get();
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function delete(string $key): bool
+ {
+ return $this->deleteItem($key);
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function hasItem($key)
+ {
+ if (\is_string($key) && isset($this->expiries[$key]) && $this->expiries[$key] > microtime(\true)) {
+ if ($this->maxItems) {
+ // Move the item last in the storage
+ $value = $this->values[$key];
+ unset($this->values[$key]);
+ $this->values[$key] = $value;
+ }
+ return \true;
+ }
+ \assert('' !== CacheItem::validateKey($key));
+ return isset($this->expiries[$key]) && !$this->deleteItem($key);
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function getItem($key)
+ {
+ if (!$isHit = $this->hasItem($key)) {
+ $value = null;
+ if (!$this->maxItems) {
+ // Track misses in non-LRU mode only
+ $this->values[$key] = null;
+ }
+ } else {
+ $value = $this->storeSerialized ? $this->unfreeze($key, $isHit) : $this->values[$key];
+ }
+ return (self::$createCacheItem)($key, $value, $isHit);
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function getItems(array $keys = [])
+ {
+ \assert(self::validateKeys($keys));
+ return $this->generateItems($keys, microtime(\true), self::$createCacheItem);
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function deleteItem($key)
+ {
+ \assert('' !== CacheItem::validateKey($key));
+ unset($this->values[$key], $this->expiries[$key]);
+ return \true;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function deleteItems(array $keys)
+ {
+ foreach ($keys as $key) {
+ $this->deleteItem($key);
+ }
+ return \true;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function save(CacheItemInterface $item)
+ {
+ if (!$item instanceof CacheItem) {
+ return \false;
+ }
+ $item = (array) $item;
+ $key = $item["\x00*\x00key"];
+ $value = $item["\x00*\x00value"];
+ $expiry = $item["\x00*\x00expiry"];
+ $now = microtime(\true);
+ if (null !== $expiry) {
+ if (!$expiry) {
+ $expiry = \PHP_INT_MAX;
+ } elseif ($expiry <= $now) {
+ $this->deleteItem($key);
+ return \true;
+ }
+ }
+ if ($this->storeSerialized && null === $value = $this->freeze($value, $key)) {
+ return \false;
+ }
+ if (null === $expiry && 0 < $this->defaultLifetime) {
+ $expiry = $this->defaultLifetime;
+ $expiry = $now + (($expiry > ($this->maxLifetime ?: $expiry)) ? $this->maxLifetime : $expiry);
+ } elseif ($this->maxLifetime && (null === $expiry || $expiry > $now + $this->maxLifetime)) {
+ $expiry = $now + $this->maxLifetime;
+ }
+ if ($this->maxItems) {
+ unset($this->values[$key]);
+ // Iterate items and vacuum expired ones while we are at it
+ foreach ($this->values as $k => $v) {
+ if ($this->expiries[$k] > $now && \count($this->values) < $this->maxItems) {
+ break;
+ }
+ unset($this->values[$k], $this->expiries[$k]);
+ }
+ }
+ $this->values[$key] = $value;
+ $this->expiries[$key] = $expiry ?? \PHP_INT_MAX;
+ return \true;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function saveDeferred(CacheItemInterface $item)
+ {
+ return $this->save($item);
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function commit()
+ {
+ return \true;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function clear(string $prefix = '')
+ {
+ if ('' !== $prefix) {
+ $now = microtime(\true);
+ foreach ($this->values as $key => $value) {
+ if (!isset($this->expiries[$key]) || $this->expiries[$key] <= $now || 0 === strpos($key, $prefix)) {
+ unset($this->values[$key], $this->expiries[$key]);
+ }
+ }
+ if ($this->values) {
+ return \true;
+ }
+ }
+ $this->values = $this->expiries = [];
+ return \true;
+ }
+ /**
+ * Returns all cached values, with cache miss as null.
+ *
+ * @return array
+ */
+ public function getValues()
+ {
+ if (!$this->storeSerialized) {
+ return $this->values;
+ }
+ $values = $this->values;
+ foreach ($values as $k => $v) {
+ if (null === $v || 'N;' === $v) {
+ continue;
+ }
+ if (!\is_string($v) || !isset($v[2]) || ':' !== $v[1]) {
+ $values[$k] = serialize($v);
+ }
+ }
+ return $values;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function reset()
+ {
+ $this->clear();
+ }
+ private function generateItems(array $keys, float $now, \Closure $f): \Generator
+ {
+ foreach ($keys as $i => $key) {
+ if (!$isHit = isset($this->expiries[$key]) && ($this->expiries[$key] > $now || !$this->deleteItem($key))) {
+ $value = null;
+ if (!$this->maxItems) {
+ // Track misses in non-LRU mode only
+ $this->values[$key] = null;
+ }
+ } else {
+ if ($this->maxItems) {
+ // Move the item last in the storage
+ $value = $this->values[$key];
+ unset($this->values[$key]);
+ $this->values[$key] = $value;
+ }
+ $value = $this->storeSerialized ? $this->unfreeze($key, $isHit) : $this->values[$key];
+ }
+ unset($keys[$i]);
+ yield $key => $f($key, $value, $isHit);
+ }
+ foreach ($keys as $key) {
+ yield $key => $f($key, null, \false);
+ }
+ }
+ private function freeze($value, string $key)
+ {
+ if (null === $value) {
+ return 'N;';
+ }
+ if (\is_string($value)) {
+ // Serialize strings if they could be confused with serialized objects or arrays
+ if ('N;' === $value || isset($value[2]) && ':' === $value[1]) {
+ return serialize($value);
+ }
+ } elseif (!\is_scalar($value)) {
+ try {
+ $serialized = serialize($value);
+ } catch (\Exception $e) {
+ unset($this->values[$key]);
+ $type = get_debug_type($value);
+ $message = sprintf('Failed to save key "{key}" of type %s: %s', $type, $e->getMessage());
+ CacheItem::log($this->logger, $message, ['key' => $key, 'exception' => $e, 'cache-adapter' => get_debug_type($this)]);
+ return;
+ }
+ // Keep value serialized if it contains any objects or any internal references
+ if ('C' === $serialized[0] || 'O' === $serialized[0] || preg_match('/;[OCRr]:[1-9]/', $serialized)) {
+ return $serialized;
+ }
+ }
+ return $value;
+ }
+ private function unfreeze(string $key, bool &$isHit)
+ {
+ if ('N;' === $value = $this->values[$key]) {
+ return null;
+ }
+ if (\is_string($value) && isset($value[2]) && ':' === $value[1]) {
+ try {
+ $value = unserialize($value);
+ } catch (\Exception $e) {
+ CacheItem::log($this->logger, 'Failed to unserialize key "{key}": ' . $e->getMessage(), ['key' => $key, 'exception' => $e, 'cache-adapter' => get_debug_type($this)]);
+ $value = \false;
+ }
+ if (\false === $value) {
+ $value = null;
+ $isHit = \false;
+ if (!$this->maxItems) {
+ $this->values[$key] = null;
+ }
+ }
+ }
+ return $value;
+ }
+ private function validateKeys(array $keys): bool
+ {
+ foreach ($keys as $key) {
+ if (!\is_string($key) || !isset($this->expiries[$key])) {
+ CacheItem::validateKey($key);
+ }
+ }
+ return \true;
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Adapter/ChainAdapter.php b/src/modules/common/third-party/vendor/symfony/cache/Adapter/ChainAdapter.php
new file mode 100644
index 0000000000..2e3cead96b
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Adapter/ChainAdapter.php
@@ -0,0 +1,287 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Adapter;
+
+use Wordlift\Modules\Common\Psr\Cache\CacheItemInterface;
+use Wordlift\Modules\Common\Psr\Cache\CacheItemPoolInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\CacheItem;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Exception\InvalidArgumentException;
+use Wordlift\Modules\Common\Symfony\Component\Cache\PruneableInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\ResettableInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Traits\ContractsTrait;
+use Wordlift\Modules\Common\Symfony\Contracts\Cache\CacheInterface;
+use Wordlift\Modules\Common\Symfony\Contracts\Service\ResetInterface;
+/**
+ * Chains several adapters together.
+ *
+ * Cached items are fetched from the first adapter having them in its data store.
+ * They are saved and deleted in all adapters at once.
+ *
+ * @author Kévin Dunglas
+ *
+ * @deprecated Since Symfony 5.4, use Doctrine\Common\Cache\Psr6\CacheAdapter instead
+ */
+class DoctrineAdapter extends AbstractAdapter
+{
+ private $provider;
+ public function __construct(CacheProvider $provider, string $namespace = '', int $defaultLifetime = 0)
+ {
+ trigger_deprecation('symfony/cache', '5.4', '"%s" is deprecated, use "%s" instead.', __CLASS__, CacheAdapter::class);
+ parent::__construct('', $defaultLifetime);
+ $this->provider = $provider;
+ $provider->setNamespace($namespace);
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function reset()
+ {
+ parent::reset();
+ $this->provider->setNamespace($this->provider->getNamespace());
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doFetch(array $ids)
+ {
+ $unserializeCallbackHandler = ini_set('unserialize_callback_func', parent::class . '::handleUnserializeCallback');
+ try {
+ return $this->provider->fetchMultiple($ids);
+ } catch (\Error $e) {
+ $trace = $e->getTrace();
+ if (isset($trace[0]['function']) && !isset($trace[0]['class'])) {
+ switch ($trace[0]['function']) {
+ case 'unserialize':
+ case 'apcu_fetch':
+ case 'apc_fetch':
+ throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine());
+ }
+ }
+ throw $e;
+ } finally {
+ ini_set('unserialize_callback_func', $unserializeCallbackHandler);
+ }
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doHave(string $id)
+ {
+ return $this->provider->contains($id);
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doClear(string $namespace)
+ {
+ $namespace = $this->provider->getNamespace();
+ return isset($namespace[0]) ? $this->provider->deleteAll() : $this->provider->flushAll();
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doDelete(array $ids)
+ {
+ $ok = \true;
+ foreach ($ids as $id) {
+ $ok = $this->provider->delete($id) && $ok;
+ }
+ return $ok;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doSave(array $values, int $lifetime)
+ {
+ return $this->provider->saveMultiple($values, $lifetime);
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Adapter/DoctrineDbalAdapter.php b/src/modules/common/third-party/vendor/symfony/cache/Adapter/DoctrineDbalAdapter.php
new file mode 100644
index 0000000000..531e36070b
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Adapter/DoctrineDbalAdapter.php
@@ -0,0 +1,358 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Adapter;
+
+use Wordlift\Modules\Common\Doctrine\DBAL\ArrayParameterType;
+use Wordlift\Modules\Common\Doctrine\DBAL\Configuration;
+use Wordlift\Modules\Common\Doctrine\DBAL\Connection;
+use Wordlift\Modules\Common\Doctrine\DBAL\Driver\ServerInfoAwareConnection;
+use Wordlift\Modules\Common\Doctrine\DBAL\DriverManager;
+use Wordlift\Modules\Common\Doctrine\DBAL\Exception as DBALException;
+use Wordlift\Modules\Common\Doctrine\DBAL\Exception\TableNotFoundException;
+use Wordlift\Modules\Common\Doctrine\DBAL\ParameterType;
+use Wordlift\Modules\Common\Doctrine\DBAL\Schema\DefaultSchemaManagerFactory;
+use Wordlift\Modules\Common\Doctrine\DBAL\Schema\Schema;
+use Wordlift\Modules\Common\Doctrine\DBAL\ServerVersionProvider;
+use Wordlift\Modules\Common\Doctrine\DBAL\Tools\DsnParser;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Exception\InvalidArgumentException;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Marshaller\DefaultMarshaller;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Marshaller\MarshallerInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\PruneableInterface;
+class DoctrineDbalAdapter extends AbstractAdapter implements PruneableInterface
+{
+ protected $maxIdLength = 255;
+ private $marshaller;
+ private $conn;
+ private $platformName;
+ private $serverVersion;
+ private $table = 'cache_items';
+ private $idCol = 'item_id';
+ private $dataCol = 'item_data';
+ private $lifetimeCol = 'item_lifetime';
+ private $timeCol = 'item_time';
+ private $namespace;
+ /**
+ * You can either pass an existing database Doctrine DBAL Connection or
+ * a DSN string that will be used to connect to the database.
+ *
+ * The cache table is created automatically when possible.
+ * Otherwise, use the createTable() method.
+ *
+ * List of available options:
+ * * db_table: The name of the table [default: cache_items]
+ * * db_id_col: The column where to store the cache id [default: item_id]
+ * * db_data_col: The column where to store the cache data [default: item_data]
+ * * db_lifetime_col: The column where to store the lifetime [default: item_lifetime]
+ * * db_time_col: The column where to store the timestamp [default: item_time]
+ *
+ * @param Connection|string $connOrDsn
+ *
+ * @throws InvalidArgumentException When namespace contains invalid characters
+ */
+ public function __construct($connOrDsn, string $namespace = '', int $defaultLifetime = 0, array $options = [], ?MarshallerInterface $marshaller = null)
+ {
+ if (isset($namespace[0]) && preg_match('#[^-+.A-Za-z0-9]#', $namespace, $match)) {
+ throw new InvalidArgumentException(sprintf('Namespace contains "%s" but only characters in [-+.A-Za-z0-9] are allowed.', $match[0]));
+ }
+ if ($connOrDsn instanceof Connection) {
+ $this->conn = $connOrDsn;
+ } elseif (\is_string($connOrDsn)) {
+ if (!class_exists(DriverManager::class)) {
+ throw new InvalidArgumentException('Failed to parse DSN. Try running "composer require doctrine/dbal".');
+ }
+ if (class_exists(DsnParser::class)) {
+ $params = (new DsnParser(['db2' => 'ibm_db2', 'mssql' => 'pdo_sqlsrv', 'mysql' => 'pdo_mysql', 'mysql2' => 'pdo_mysql', 'postgres' => 'pdo_pgsql', 'postgresql' => 'pdo_pgsql', 'pgsql' => 'pdo_pgsql', 'sqlite' => 'pdo_sqlite', 'sqlite3' => 'pdo_sqlite']))->parse($connOrDsn);
+ } else {
+ $params = ['url' => $connOrDsn];
+ }
+ $config = new Configuration();
+ if (class_exists(DefaultSchemaManagerFactory::class)) {
+ $config->setSchemaManagerFactory(new DefaultSchemaManagerFactory());
+ }
+ $this->conn = DriverManager::getConnection($params, $config);
+ } else {
+ throw new \TypeError(sprintf('Argument 1 passed to "%s()" must be "%s" or string, "%s" given.', __METHOD__, Connection::class, get_debug_type($connOrDsn)));
+ }
+ $this->table = $options['db_table'] ?? $this->table;
+ $this->idCol = $options['db_id_col'] ?? $this->idCol;
+ $this->dataCol = $options['db_data_col'] ?? $this->dataCol;
+ $this->lifetimeCol = $options['db_lifetime_col'] ?? $this->lifetimeCol;
+ $this->timeCol = $options['db_time_col'] ?? $this->timeCol;
+ $this->namespace = $namespace;
+ $this->marshaller = $marshaller ?? new DefaultMarshaller();
+ parent::__construct($namespace, $defaultLifetime);
+ }
+ /**
+ * Creates the table to store cache items which can be called once for setup.
+ *
+ * Cache ID are saved in a column of maximum length 255. Cache data is
+ * saved in a BLOB.
+ *
+ * @throws DBALException When the table already exists
+ */
+ public function createTable()
+ {
+ $schema = new Schema();
+ $this->addTableToSchema($schema);
+ foreach ($schema->toSql($this->conn->getDatabasePlatform()) as $sql) {
+ $this->conn->executeStatement($sql);
+ }
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function configureSchema(Schema $schema, Connection $forConnection): void
+ {
+ // only update the schema for this connection
+ if ($forConnection !== $this->conn) {
+ return;
+ }
+ if ($schema->hasTable($this->table)) {
+ return;
+ }
+ $this->addTableToSchema($schema);
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function prune(): bool
+ {
+ $deleteSql = "DELETE FROM {$this->table} WHERE {$this->lifetimeCol} + {$this->timeCol} <= ?";
+ $params = [time()];
+ $paramTypes = [ParameterType::INTEGER];
+ if ('' !== $this->namespace) {
+ $deleteSql .= " AND {$this->idCol} LIKE ?";
+ $params[] = sprintf('%s%%', $this->namespace);
+ $paramTypes[] = ParameterType::STRING;
+ }
+ try {
+ $this->conn->executeStatement($deleteSql, $params, $paramTypes);
+ } catch (TableNotFoundException $e) {
+ }
+ return \true;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doFetch(array $ids): iterable
+ {
+ $now = time();
+ $expired = [];
+ $sql = "SELECT {$this->idCol}, CASE WHEN {$this->lifetimeCol} IS NULL OR {$this->lifetimeCol} + {$this->timeCol} > ? THEN {$this->dataCol} ELSE NULL END FROM {$this->table} WHERE {$this->idCol} IN (?)";
+ $result = $this->conn->executeQuery($sql, [$now, $ids], [ParameterType::INTEGER, class_exists(ArrayParameterType::class) ? ArrayParameterType::STRING : Connection::PARAM_STR_ARRAY])->iterateNumeric();
+ foreach ($result as $row) {
+ if (null === $row[1]) {
+ $expired[] = $row[0];
+ } else {
+ yield $row[0] => $this->marshaller->unmarshall(\is_resource($row[1]) ? stream_get_contents($row[1]) : $row[1]);
+ }
+ }
+ if ($expired) {
+ $sql = "DELETE FROM {$this->table} WHERE {$this->lifetimeCol} + {$this->timeCol} <= ? AND {$this->idCol} IN (?)";
+ $this->conn->executeStatement($sql, [$now, $expired], [ParameterType::INTEGER, class_exists(ArrayParameterType::class) ? ArrayParameterType::STRING : Connection::PARAM_STR_ARRAY]);
+ }
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doHave(string $id): bool
+ {
+ $sql = "SELECT 1 FROM {$this->table} WHERE {$this->idCol} = ? AND ({$this->lifetimeCol} IS NULL OR {$this->lifetimeCol} + {$this->timeCol} > ?)";
+ $result = $this->conn->executeQuery($sql, [$id, time()], [ParameterType::STRING, ParameterType::INTEGER]);
+ return (bool) $result->fetchOne();
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doClear(string $namespace): bool
+ {
+ if ('' === $namespace) {
+ if ('sqlite' === $this->getPlatformName()) {
+ $sql = "DELETE FROM {$this->table}";
+ } else {
+ $sql = "TRUNCATE TABLE {$this->table}";
+ }
+ } else {
+ $sql = "DELETE FROM {$this->table} WHERE {$this->idCol} LIKE '{$namespace}%'";
+ }
+ try {
+ $this->conn->executeStatement($sql);
+ } catch (TableNotFoundException $e) {
+ }
+ return \true;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doDelete(array $ids): bool
+ {
+ $sql = "DELETE FROM {$this->table} WHERE {$this->idCol} IN (?)";
+ try {
+ $this->conn->executeStatement($sql, [array_values($ids)], [class_exists(ArrayParameterType::class) ? ArrayParameterType::STRING : Connection::PARAM_STR_ARRAY]);
+ } catch (TableNotFoundException $e) {
+ }
+ return \true;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doSave(array $values, int $lifetime)
+ {
+ if (!$values = $this->marshaller->marshall($values, $failed)) {
+ return $failed;
+ }
+ $platformName = $this->getPlatformName();
+ $insertSql = "INSERT INTO {$this->table} ({$this->idCol}, {$this->dataCol}, {$this->lifetimeCol}, {$this->timeCol}) VALUES (?, ?, ?, ?)";
+ switch (\true) {
+ case 'mysql' === $platformName:
+ $sql = $insertSql . " ON DUPLICATE KEY UPDATE {$this->dataCol} = VALUES({$this->dataCol}), {$this->lifetimeCol} = VALUES({$this->lifetimeCol}), {$this->timeCol} = VALUES({$this->timeCol})";
+ break;
+ case 'oci' === $platformName:
+ // DUAL is Oracle specific dummy table
+ $sql = "MERGE INTO {$this->table} USING DUAL ON ({$this->idCol} = ?) " . "WHEN NOT MATCHED THEN INSERT ({$this->idCol}, {$this->dataCol}, {$this->lifetimeCol}, {$this->timeCol}) VALUES (?, ?, ?, ?) " . "WHEN MATCHED THEN UPDATE SET {$this->dataCol} = ?, {$this->lifetimeCol} = ?, {$this->timeCol} = ?";
+ break;
+ case 'sqlsrv' === $platformName && version_compare($this->getServerVersion(), '10', '>='):
+ // MERGE is only available since SQL Server 2008 and must be terminated by semicolon
+ // It also requires HOLDLOCK according to http://weblogs.sqlteam.com/dang/archive/2009/01/31/UPSERT-Race-Condition-With-MERGE.aspx
+ $sql = "MERGE INTO {$this->table} WITH (HOLDLOCK) USING (SELECT 1 AS dummy) AS src ON ({$this->idCol} = ?) " . "WHEN NOT MATCHED THEN INSERT ({$this->idCol}, {$this->dataCol}, {$this->lifetimeCol}, {$this->timeCol}) VALUES (?, ?, ?, ?) " . "WHEN MATCHED THEN UPDATE SET {$this->dataCol} = ?, {$this->lifetimeCol} = ?, {$this->timeCol} = ?;";
+ break;
+ case 'sqlite' === $platformName:
+ $sql = 'INSERT OR REPLACE' . substr($insertSql, 6);
+ break;
+ case 'pgsql' === $platformName && version_compare($this->getServerVersion(), '9.5', '>='):
+ $sql = $insertSql . " ON CONFLICT ({$this->idCol}) DO UPDATE SET ({$this->dataCol}, {$this->lifetimeCol}, {$this->timeCol}) = (EXCLUDED.{$this->dataCol}, EXCLUDED.{$this->lifetimeCol}, EXCLUDED.{$this->timeCol})";
+ break;
+ default:
+ $platformName = null;
+ $sql = "UPDATE {$this->table} SET {$this->dataCol} = ?, {$this->lifetimeCol} = ?, {$this->timeCol} = ? WHERE {$this->idCol} = ?";
+ break;
+ }
+ $now = time();
+ $lifetime = $lifetime ?: null;
+ try {
+ $stmt = $this->conn->prepare($sql);
+ } catch (TableNotFoundException $e) {
+ if (!$this->conn->isTransactionActive() || \in_array($platformName, ['pgsql', 'sqlite', 'sqlsrv'], \true)) {
+ $this->createTable();
+ }
+ $stmt = $this->conn->prepare($sql);
+ }
+ if ('sqlsrv' === $platformName || 'oci' === $platformName) {
+ $bind = static function ($id, $data) use ($stmt) {
+ $stmt->bindValue(1, $id);
+ $stmt->bindValue(2, $id);
+ $stmt->bindValue(3, $data, ParameterType::LARGE_OBJECT);
+ $stmt->bindValue(6, $data, ParameterType::LARGE_OBJECT);
+ };
+ $stmt->bindValue(4, $lifetime, ParameterType::INTEGER);
+ $stmt->bindValue(5, $now, ParameterType::INTEGER);
+ $stmt->bindValue(7, $lifetime, ParameterType::INTEGER);
+ $stmt->bindValue(8, $now, ParameterType::INTEGER);
+ } elseif (null !== $platformName) {
+ $bind = static function ($id, $data) use ($stmt) {
+ $stmt->bindValue(1, $id);
+ $stmt->bindValue(2, $data, ParameterType::LARGE_OBJECT);
+ };
+ $stmt->bindValue(3, $lifetime, ParameterType::INTEGER);
+ $stmt->bindValue(4, $now, ParameterType::INTEGER);
+ } else {
+ $stmt->bindValue(2, $lifetime, ParameterType::INTEGER);
+ $stmt->bindValue(3, $now, ParameterType::INTEGER);
+ $insertStmt = $this->conn->prepare($insertSql);
+ $insertStmt->bindValue(3, $lifetime, ParameterType::INTEGER);
+ $insertStmt->bindValue(4, $now, ParameterType::INTEGER);
+ $bind = static function ($id, $data) use ($stmt, $insertStmt) {
+ $stmt->bindValue(1, $data, ParameterType::LARGE_OBJECT);
+ $stmt->bindValue(4, $id);
+ $insertStmt->bindValue(1, $id);
+ $insertStmt->bindValue(2, $data, ParameterType::LARGE_OBJECT);
+ };
+ }
+ foreach ($values as $id => $data) {
+ $bind($id, $data);
+ try {
+ $rowCount = $stmt->executeStatement();
+ } catch (TableNotFoundException $e) {
+ if (!$this->conn->isTransactionActive() || \in_array($platformName, ['pgsql', 'sqlite', 'sqlsrv'], \true)) {
+ $this->createTable();
+ }
+ $rowCount = $stmt->executeStatement();
+ }
+ if (null === $platformName && 0 === $rowCount) {
+ try {
+ $insertStmt->executeStatement();
+ } catch (DBALException $e) {
+ // A concurrent write won, let it be
+ }
+ }
+ }
+ return $failed;
+ }
+ /**
+ * @internal
+ */
+ protected function getId($key)
+ {
+ if ('pgsql' !== $this->getPlatformName()) {
+ return parent::getId($key);
+ }
+ if (str_contains($key, "\x00") || str_contains($key, '%') || !preg_match('//u', $key)) {
+ $key = rawurlencode($key);
+ }
+ return parent::getId($key);
+ }
+ private function getPlatformName(): string
+ {
+ if (isset($this->platformName)) {
+ return $this->platformName;
+ }
+ $platform = $this->conn->getDatabasePlatform();
+ switch (\true) {
+ case $platform instanceof \Wordlift\Modules\Common\Doctrine\DBAL\Platforms\MySQLPlatform:
+ case $platform instanceof \Wordlift\Modules\Common\Doctrine\DBAL\Platforms\MySQL57Platform:
+ return $this->platformName = 'mysql';
+ case $platform instanceof \Wordlift\Modules\Common\Doctrine\DBAL\Platforms\SqlitePlatform:
+ return $this->platformName = 'sqlite';
+ case $platform instanceof \Wordlift\Modules\Common\Doctrine\DBAL\Platforms\PostgreSQLPlatform:
+ case $platform instanceof \Wordlift\Modules\Common\Doctrine\DBAL\Platforms\PostgreSQL94Platform:
+ return $this->platformName = 'pgsql';
+ case $platform instanceof \Wordlift\Modules\Common\Doctrine\DBAL\Platforms\OraclePlatform:
+ return $this->platformName = 'oci';
+ case $platform instanceof \Wordlift\Modules\Common\Doctrine\DBAL\Platforms\SQLServerPlatform:
+ case $platform instanceof \Wordlift\Modules\Common\Doctrine\DBAL\Platforms\SQLServer2012Platform:
+ return $this->platformName = 'sqlsrv';
+ default:
+ return $this->platformName = \get_class($platform);
+ }
+ }
+ private function getServerVersion(): string
+ {
+ if (isset($this->serverVersion)) {
+ return $this->serverVersion;
+ }
+ if ($this->conn instanceof ServerVersionProvider || $this->conn instanceof ServerInfoAwareConnection) {
+ return $this->serverVersion = $this->conn->getServerVersion();
+ }
+ // The condition should be removed once support for DBAL <3.3 is dropped
+ $conn = method_exists($this->conn, 'getNativeConnection') ? $this->conn->getNativeConnection() : $this->conn->getWrappedConnection();
+ return $this->serverVersion = $conn->getAttribute(\PDO::ATTR_SERVER_VERSION);
+ }
+ private function addTableToSchema(Schema $schema): void
+ {
+ $types = ['mysql' => 'binary', 'sqlite' => 'text'];
+ $table = $schema->createTable($this->table);
+ $table->addColumn($this->idCol, $types[$this->getPlatformName()] ?? 'string', ['length' => 255]);
+ $table->addColumn($this->dataCol, 'blob', ['length' => 16777215]);
+ $table->addColumn($this->lifetimeCol, 'integer', ['unsigned' => \true, 'notnull' => \false]);
+ $table->addColumn($this->timeCol, 'integer', ['unsigned' => \true]);
+ $table->setPrimaryKey([$this->idCol]);
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Adapter/FilesystemAdapter.php b/src/modules/common/third-party/vendor/symfony/cache/Adapter/FilesystemAdapter.php
new file mode 100644
index 0000000000..ce900d45fd
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Adapter/FilesystemAdapter.php
@@ -0,0 +1,26 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Adapter;
+
+use Wordlift\Modules\Common\Symfony\Component\Cache\Marshaller\DefaultMarshaller;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Marshaller\MarshallerInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\PruneableInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Traits\FilesystemTrait;
+class FilesystemAdapter extends AbstractAdapter implements PruneableInterface
+{
+ use FilesystemTrait;
+ public function __construct(string $namespace = '', int $defaultLifetime = 0, ?string $directory = null, ?MarshallerInterface $marshaller = null)
+ {
+ $this->marshaller = $marshaller ?? new DefaultMarshaller();
+ parent::__construct('', $defaultLifetime);
+ $this->init($namespace, $directory);
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Adapter/FilesystemTagAwareAdapter.php b/src/modules/common/third-party/vendor/symfony/cache/Adapter/FilesystemTagAwareAdapter.php
new file mode 100644
index 0000000000..6885d9af93
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Adapter/FilesystemTagAwareAdapter.php
@@ -0,0 +1,205 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Adapter;
+
+use Wordlift\Modules\Common\Symfony\Component\Cache\Marshaller\MarshallerInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Marshaller\TagAwareMarshaller;
+use Wordlift\Modules\Common\Symfony\Component\Cache\PruneableInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Traits\FilesystemTrait;
+/**
+ * Stores tag id <> cache id relationship as a symlink, and lookup on invalidation calls.
+ *
+ * @author Nicolas Grekas
+ * @author André Rømcke
+ */
+class MemcachedAdapter extends AbstractAdapter
+{
+ /**
+ * We are replacing characters that are illegal in Memcached keys with reserved characters from
+ * {@see \Symfony\Contracts\Cache\ItemInterface::RESERVED_CHARACTERS} that are legal in Memcached.
+ * Note: don’t use {@see \Symfony\Component\Cache\Adapter\AbstractAdapter::NS_SEPARATOR}.
+ */
+ private const RESERVED_MEMCACHED = " \n\r\t\v\f\x00";
+ private const RESERVED_PSR6 = '@()\{}/';
+ protected $maxIdLength = 250;
+ private $marshaller;
+ private $client;
+ private $lazyClient;
+ /**
+ * Using a MemcachedAdapter with a TagAwareAdapter for storing tags is discouraged.
+ * Using a RedisAdapter is recommended instead. If you cannot do otherwise, be aware that:
+ * - the Memcached::OPT_BINARY_PROTOCOL must be enabled
+ * (that's the default when using MemcachedAdapter::createConnection());
+ * - tags eviction by Memcached's LRU algorithm will break by-tags invalidation;
+ * your Memcached memory should be large enough to never trigger LRU.
+ *
+ * Using a MemcachedAdapter as a pure items store is fine.
+ */
+ public function __construct(\Memcached $client, string $namespace = '', int $defaultLifetime = 0, ?MarshallerInterface $marshaller = null)
+ {
+ if (!static::isSupported()) {
+ throw new CacheException('Memcached ' . ((\PHP_VERSION_ID >= 80100) ? '> 3.1.5' : '>= 2.2.0') . ' is required.');
+ }
+ if ('Memcached' === \get_class($client)) {
+ $opt = $client->getOption(\Memcached::OPT_SERIALIZER);
+ if (\Memcached::SERIALIZER_PHP !== $opt && \Memcached::SERIALIZER_IGBINARY !== $opt) {
+ throw new CacheException('MemcachedAdapter: "serializer" option must be "php" or "igbinary".');
+ }
+ $this->maxIdLength -= \strlen($client->getOption(\Memcached::OPT_PREFIX_KEY));
+ $this->client = $client;
+ } else {
+ $this->lazyClient = $client;
+ }
+ parent::__construct($namespace, $defaultLifetime);
+ $this->enableVersioning();
+ $this->marshaller = $marshaller ?? new DefaultMarshaller();
+ }
+ public static function isSupported()
+ {
+ return \extension_loaded('memcached') && version_compare(phpversion('memcached'), (\PHP_VERSION_ID >= 80100) ? '3.1.6' : '2.2.0', '>=');
+ }
+ /**
+ * Creates a Memcached instance.
+ *
+ * By default, the binary protocol, no block, and libketama compatible options are enabled.
+ *
+ * Examples for servers:
+ * - 'memcached://user:pass@localhost?weight=33'
+ * - [['localhost', 11211, 33]]
+ *
+ * @param array[]|string|string[] $servers An array of servers, a DSN, or an array of DSNs
+ *
+ * @return \Memcached
+ *
+ * @throws \ErrorException When invalid options or servers are provided
+ */
+ public static function createConnection($servers, array $options = [])
+ {
+ if (\is_string($servers)) {
+ $servers = [$servers];
+ } elseif (!\is_array($servers)) {
+ throw new InvalidArgumentException(sprintf('MemcachedAdapter::createClient() expects array or string as first argument, "%s" given.', get_debug_type($servers)));
+ }
+ if (!static::isSupported()) {
+ throw new CacheException('Memcached ' . ((\PHP_VERSION_ID >= 80100) ? '> 3.1.5' : '>= 2.2.0') . ' is required.');
+ }
+ set_error_handler(function ($type, $msg, $file, $line) {
+ throw new \ErrorException($msg, 0, $type, $file, $line);
+ });
+ try {
+ $client = new \Memcached($options['persistent_id'] ?? null);
+ $username = $options['username'] ?? null;
+ $password = $options['password'] ?? null;
+ // parse any DSN in $servers
+ foreach ($servers as $i => $dsn) {
+ if (\is_array($dsn)) {
+ continue;
+ }
+ if (!str_starts_with($dsn, 'memcached:')) {
+ throw new InvalidArgumentException('Invalid Memcached DSN: it does not start with "memcached:".');
+ }
+ $params = preg_replace_callback('#^memcached:(//)?(?:([^@]*+)@)?#', function ($m) use (&$username, &$password) {
+ if (!empty($m[2])) {
+ [$username, $password] = explode(':', $m[2], 2) + [1 => null];
+ $username = rawurldecode($username);
+ $password = (null !== $password) ? rawurldecode($password) : null;
+ }
+ return 'file:' . ($m[1] ?? '');
+ }, $dsn);
+ if (\false === $params = parse_url($params)) {
+ throw new InvalidArgumentException('Invalid Memcached DSN.');
+ }
+ $query = $hosts = [];
+ if (isset($params['query'])) {
+ parse_str($params['query'], $query);
+ if (isset($query['host'])) {
+ if (!\is_array($hosts = $query['host'])) {
+ throw new InvalidArgumentException('Invalid Memcached DSN: query parameter "host" must be an array.');
+ }
+ foreach ($hosts as $host => $weight) {
+ if (\false === $port = strrpos($host, ':')) {
+ $hosts[$host] = [$host, 11211, (int) $weight];
+ } else {
+ $hosts[$host] = [substr($host, 0, $port), (int) substr($host, 1 + $port), (int) $weight];
+ }
+ }
+ $hosts = array_values($hosts);
+ unset($query['host']);
+ }
+ if ($hosts && !isset($params['host']) && !isset($params['path'])) {
+ unset($servers[$i]);
+ $servers = array_merge($servers, $hosts);
+ continue;
+ }
+ }
+ if (!isset($params['host']) && !isset($params['path'])) {
+ throw new InvalidArgumentException('Invalid Memcached DSN: missing host or path.');
+ }
+ if (isset($params['path']) && preg_match('#/(\d+)$#', $params['path'], $m)) {
+ $params['weight'] = $m[1];
+ $params['path'] = substr($params['path'], 0, -\strlen($m[0]));
+ }
+ $params += ['host' => $params['host'] ?? $params['path'], 'port' => isset($params['host']) ? 11211 : null, 'weight' => 0];
+ if ($query) {
+ $params += $query;
+ $options = $query + $options;
+ }
+ $servers[$i] = [$params['host'], $params['port'], $params['weight']];
+ if ($hosts) {
+ $servers = array_merge($servers, $hosts);
+ }
+ }
+ // set client's options
+ unset($options['persistent_id'], $options['username'], $options['password'], $options['weight'], $options['lazy']);
+ $options = array_change_key_case($options, \CASE_UPPER);
+ $client->setOption(\Memcached::OPT_BINARY_PROTOCOL, \true);
+ $client->setOption(\Memcached::OPT_NO_BLOCK, \true);
+ $client->setOption(\Memcached::OPT_TCP_NODELAY, \true);
+ if (!\array_key_exists('LIBKETAMA_COMPATIBLE', $options) && !\array_key_exists(\Memcached::OPT_LIBKETAMA_COMPATIBLE, $options)) {
+ $client->setOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE, \true);
+ }
+ foreach ($options as $name => $value) {
+ if (\is_int($name)) {
+ continue;
+ }
+ if ('HASH' === $name || 'SERIALIZER' === $name || 'DISTRIBUTION' === $name) {
+ $value = \constant('Memcached::' . $name . '_' . strtoupper($value));
+ }
+ unset($options[$name]);
+ if (\defined('Memcached::OPT_' . $name)) {
+ $options[\constant('Memcached::OPT_' . $name)] = $value;
+ }
+ }
+ $client->setOptions($options + [\Memcached::OPT_SERIALIZER => \Memcached::SERIALIZER_PHP]);
+ // set client's servers, taking care of persistent connections
+ if (!$client->isPristine()) {
+ $oldServers = [];
+ foreach ($client->getServerList() as $server) {
+ $oldServers[] = [$server['host'], $server['port']];
+ }
+ $newServers = [];
+ foreach ($servers as $server) {
+ if (1 < \count($server)) {
+ $server = array_values($server);
+ unset($server[2]);
+ $server[1] = (int) $server[1];
+ }
+ $newServers[] = $server;
+ }
+ if ($oldServers !== $newServers) {
+ $client->resetServerList();
+ $client->addServers($servers);
+ }
+ } else {
+ $client->addServers($servers);
+ }
+ if (null !== $username || null !== $password) {
+ if (!method_exists($client, 'setSaslAuthData')) {
+ trigger_error('Missing SASL support: the memcached extension must be compiled with --enable-memcached-sasl.');
+ }
+ $client->setSaslAuthData($username, $password);
+ }
+ return $client;
+ } finally {
+ restore_error_handler();
+ }
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doSave(array $values, int $lifetime)
+ {
+ if (!$values = $this->marshaller->marshall($values, $failed)) {
+ return $failed;
+ }
+ if ($lifetime && $lifetime > 30 * 86400) {
+ $lifetime += time();
+ }
+ $encodedValues = [];
+ foreach ($values as $key => $value) {
+ $encodedValues[self::encodeKey($key)] = $value;
+ }
+ return $this->checkResultCode($this->getClient()->setMulti($encodedValues, $lifetime)) ? $failed : \false;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doFetch(array $ids)
+ {
+ try {
+ $encodedIds = array_map([__CLASS__, 'encodeKey'], $ids);
+ $encodedResult = $this->checkResultCode($this->getClient()->getMulti($encodedIds));
+ $result = [];
+ foreach ($encodedResult as $key => $value) {
+ $result[self::decodeKey($key)] = $this->marshaller->unmarshall($value);
+ }
+ return $result;
+ } catch (\Error $e) {
+ throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine());
+ }
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doHave(string $id)
+ {
+ return \false !== $this->getClient()->get(self::encodeKey($id)) || $this->checkResultCode(\Memcached::RES_SUCCESS === $this->client->getResultCode());
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doDelete(array $ids)
+ {
+ $ok = \true;
+ $encodedIds = array_map([__CLASS__, 'encodeKey'], $ids);
+ foreach ($this->checkResultCode($this->getClient()->deleteMulti($encodedIds)) as $result) {
+ if (\Memcached::RES_SUCCESS !== $result && \Memcached::RES_NOTFOUND !== $result) {
+ $ok = \false;
+ }
+ }
+ return $ok;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doClear(string $namespace)
+ {
+ return '' === $namespace && $this->getClient()->flush();
+ }
+ private function checkResultCode($result)
+ {
+ $code = $this->client->getResultCode();
+ if (\Memcached::RES_SUCCESS === $code || \Memcached::RES_NOTFOUND === $code) {
+ return $result;
+ }
+ throw new CacheException('MemcachedAdapter client error: ' . strtolower($this->client->getResultMessage()));
+ }
+ private function getClient(): \Memcached
+ {
+ if ($this->client) {
+ return $this->client;
+ }
+ $opt = $this->lazyClient->getOption(\Memcached::OPT_SERIALIZER);
+ if (\Memcached::SERIALIZER_PHP !== $opt && \Memcached::SERIALIZER_IGBINARY !== $opt) {
+ throw new CacheException('MemcachedAdapter: "serializer" option must be "php" or "igbinary".');
+ }
+ if ('' !== $prefix = (string) $this->lazyClient->getOption(\Memcached::OPT_PREFIX_KEY)) {
+ throw new CacheException(sprintf('MemcachedAdapter: "prefix_key" option must be empty when using proxified connections, "%s" given.', $prefix));
+ }
+ return $this->client = $this->lazyClient;
+ }
+ private static function encodeKey(string $key): string
+ {
+ return strtr($key, self::RESERVED_MEMCACHED, self::RESERVED_PSR6);
+ }
+ private static function decodeKey(string $key): string
+ {
+ return strtr($key, self::RESERVED_PSR6, self::RESERVED_MEMCACHED);
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Adapter/NullAdapter.php b/src/modules/common/third-party/vendor/symfony/cache/Adapter/NullAdapter.php
new file mode 100644
index 0000000000..b889268f19
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Adapter/NullAdapter.php
@@ -0,0 +1,130 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Adapter;
+
+use Wordlift\Modules\Common\Psr\Cache\CacheItemInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\CacheItem;
+use Wordlift\Modules\Common\Symfony\Contracts\Cache\CacheInterface;
+/**
+ * @author Titouan Galopin
+ */
+class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface
+{
+ use ContractsTrait;
+ use ProxyTrait;
+ private $file;
+ private $keys;
+ private $values;
+ private static $createCacheItem;
+ private static $valuesCache = [];
+ /**
+ * @param string $file The PHP file were values are cached
+ * @param AdapterInterface $fallbackPool A pool to fallback on when an item is not hit
+ */
+ public function __construct(string $file, AdapterInterface $fallbackPool)
+ {
+ $this->file = $file;
+ $this->pool = $fallbackPool;
+ self::$createCacheItem ?? self::$createCacheItem = \Closure::bind(static function ($key, $value, $isHit) {
+ $item = new CacheItem();
+ $item->key = $key;
+ $item->value = $value;
+ $item->isHit = $isHit;
+ return $item;
+ }, null, CacheItem::class);
+ }
+ /**
+ * This adapter takes advantage of how PHP stores arrays in its latest versions.
+ *
+ * @param string $file The PHP file were values are cached
+ * @param CacheItemPoolInterface $fallbackPool A pool to fallback on when an item is not hit
+ *
+ * @return CacheItemPoolInterface
+ */
+ public static function create(string $file, CacheItemPoolInterface $fallbackPool)
+ {
+ if (!$fallbackPool instanceof AdapterInterface) {
+ $fallbackPool = new ProxyAdapter($fallbackPool);
+ }
+ return new static($file, $fallbackPool);
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null)
+ {
+ if (null === $this->values) {
+ $this->initialize();
+ }
+ if (!isset($this->keys[$key])) {
+ get_from_pool:
+ if ($this->pool instanceof CacheInterface) {
+ return $this->pool->get($key, $callback, $beta, $metadata);
+ }
+ return $this->doGet($this->pool, $key, $callback, $beta, $metadata);
+ }
+ $value = $this->values[$this->keys[$key]];
+ if ('N;' === $value) {
+ return null;
+ }
+ try {
+ if ($value instanceof \Closure) {
+ return $value();
+ }
+ } catch (\Throwable $e) {
+ unset($this->keys[$key]);
+ goto get_from_pool;
+ }
+ return $value;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function getItem($key)
+ {
+ if (!\is_string($key)) {
+ throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
+ }
+ if (null === $this->values) {
+ $this->initialize();
+ }
+ if (!isset($this->keys[$key])) {
+ return $this->pool->getItem($key);
+ }
+ $value = $this->values[$this->keys[$key]];
+ $isHit = \true;
+ if ('N;' === $value) {
+ $value = null;
+ } elseif ($value instanceof \Closure) {
+ try {
+ $value = $value();
+ } catch (\Throwable $e) {
+ $value = null;
+ $isHit = \false;
+ }
+ }
+ return (self::$createCacheItem)($key, $value, $isHit);
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function getItems(array $keys = [])
+ {
+ foreach ($keys as $key) {
+ if (!\is_string($key)) {
+ throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
+ }
+ }
+ if (null === $this->values) {
+ $this->initialize();
+ }
+ return $this->generateItems($keys);
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function hasItem($key)
+ {
+ if (!\is_string($key)) {
+ throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
+ }
+ if (null === $this->values) {
+ $this->initialize();
+ }
+ return isset($this->keys[$key]) || $this->pool->hasItem($key);
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function deleteItem($key)
+ {
+ if (!\is_string($key)) {
+ throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
+ }
+ if (null === $this->values) {
+ $this->initialize();
+ }
+ return !isset($this->keys[$key]) && $this->pool->deleteItem($key);
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function deleteItems(array $keys)
+ {
+ $deleted = \true;
+ $fallbackKeys = [];
+ foreach ($keys as $key) {
+ if (!\is_string($key)) {
+ throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
+ }
+ if (isset($this->keys[$key])) {
+ $deleted = \false;
+ } else {
+ $fallbackKeys[] = $key;
+ }
+ }
+ if (null === $this->values) {
+ $this->initialize();
+ }
+ if ($fallbackKeys) {
+ $deleted = $this->pool->deleteItems($fallbackKeys) && $deleted;
+ }
+ return $deleted;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function save(CacheItemInterface $item)
+ {
+ if (null === $this->values) {
+ $this->initialize();
+ }
+ return !isset($this->keys[$item->getKey()]) && $this->pool->save($item);
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function saveDeferred(CacheItemInterface $item)
+ {
+ if (null === $this->values) {
+ $this->initialize();
+ }
+ return !isset($this->keys[$item->getKey()]) && $this->pool->saveDeferred($item);
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function commit()
+ {
+ return $this->pool->commit();
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function clear(string $prefix = '')
+ {
+ $this->keys = $this->values = [];
+ $cleared = @unlink($this->file) || !file_exists($this->file);
+ unset(self::$valuesCache[$this->file]);
+ if ($this->pool instanceof AdapterInterface) {
+ return $this->pool->clear($prefix) && $cleared;
+ }
+ return $this->pool->clear() && $cleared;
+ }
+ /**
+ * Store an array of cached values.
+ *
+ * @param array $values The cached values
+ *
+ * @return string[] A list of classes to preload on PHP 7.4+
+ */
+ public function warmUp(array $values)
+ {
+ if (file_exists($this->file)) {
+ if (!is_file($this->file)) {
+ throw new InvalidArgumentException(sprintf('Cache path exists and is not a file: "%s".', $this->file));
+ }
+ if (!is_writable($this->file)) {
+ throw new InvalidArgumentException(sprintf('Cache file is not writable: "%s".', $this->file));
+ }
+ } else {
+ $directory = \dirname($this->file);
+ if (!is_dir($directory) && !@mkdir($directory, 0777, \true)) {
+ throw new InvalidArgumentException(sprintf('Cache directory does not exist and cannot be created: "%s".', $directory));
+ }
+ if (!is_writable($directory)) {
+ throw new InvalidArgumentException(sprintf('Cache directory is not writable: "%s".', $directory));
+ }
+ }
+ $preload = [];
+ $dumpedValues = '';
+ $dumpedMap = [];
+ $dump = <<<'EOF'
+ $value) {
+ CacheItem::validateKey(\is_int($key) ? (string) $key : $key);
+ $isStaticValue = \true;
+ if (null === $value) {
+ $value = "'N;'";
+ } elseif (\is_object($value) || \is_array($value)) {
+ try {
+ $value = VarExporter::export($value, $isStaticValue, $preload);
+ } catch (\Exception $e) {
+ throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value)), 0, $e);
+ }
+ } elseif (\is_string($value)) {
+ // Wrap "N;" in a closure to not confuse it with an encoded `null`
+ if ('N;' === $value) {
+ $isStaticValue = \false;
+ }
+ $value = var_export($value, \true);
+ } elseif (!\is_scalar($value)) {
+ throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value)));
+ } else {
+ $value = var_export($value, \true);
+ }
+ if (!$isStaticValue) {
+ $value = str_replace("\n", "\n ", $value);
+ $value = "static function () {\n return {$value};\n}";
+ }
+ $hash = hash('md5', $value);
+ if (null === $id = $dumpedMap[$hash] ?? null) {
+ $id = $dumpedMap[$hash] = \count($dumpedMap);
+ $dumpedValues .= "{$id} => {$value},\n";
+ }
+ $dump .= var_export($key, \true) . " => {$id},\n";
+ }
+ $dump .= "\n], [\n\n{$dumpedValues}\n]];\n";
+ $tmpFile = uniqid($this->file, \true);
+ file_put_contents($tmpFile, $dump);
+ @chmod($tmpFile, 0666 & ~umask());
+ unset($serialized, $value, $dump);
+ @rename($tmpFile, $this->file);
+ unset(self::$valuesCache[$this->file]);
+ $this->initialize();
+ return $preload;
+ }
+ /**
+ * Load the cache file.
+ */
+ private function initialize()
+ {
+ if (isset(self::$valuesCache[$this->file])) {
+ $values = self::$valuesCache[$this->file];
+ } elseif (!is_file($this->file)) {
+ $this->keys = $this->values = [];
+ return;
+ } else {
+ $values = self::$valuesCache[$this->file] = (include $this->file) ?: [[], []];
+ }
+ if (2 !== \count($values) || !isset($values[0], $values[1])) {
+ $this->keys = $this->values = [];
+ } else {
+ [$this->keys, $this->values] = $values;
+ }
+ }
+ private function generateItems(array $keys): \Generator
+ {
+ $f = self::$createCacheItem;
+ $fallbackKeys = [];
+ foreach ($keys as $key) {
+ if (isset($this->keys[$key])) {
+ $value = $this->values[$this->keys[$key]];
+ if ('N;' === $value) {
+ yield $key => $f($key, null, \true);
+ } elseif ($value instanceof \Closure) {
+ try {
+ yield $key => $f($key, $value(), \true);
+ } catch (\Throwable $e) {
+ yield $key => $f($key, null, \false);
+ }
+ } else {
+ yield $key => $f($key, $value, \true);
+ }
+ } else {
+ $fallbackKeys[] = $key;
+ }
+ }
+ if ($fallbackKeys) {
+ yield from $this->pool->getItems($fallbackKeys);
+ }
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Adapter/PhpFilesAdapter.php b/src/modules/common/third-party/vendor/symfony/cache/Adapter/PhpFilesAdapter.php
new file mode 100644
index 0000000000..dfd6d4a6b7
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Adapter/PhpFilesAdapter.php
@@ -0,0 +1,284 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Adapter;
+
+use Wordlift\Modules\Common\Symfony\Component\Cache\Exception\CacheException;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Exception\InvalidArgumentException;
+use Wordlift\Modules\Common\Symfony\Component\Cache\PruneableInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Traits\FilesystemCommonTrait;
+use Wordlift\Modules\Common\Symfony\Component\VarExporter\VarExporter;
+/**
+ * @author Piotr Stankowski
+ * @author Rob Frawley 2nd
+ */
+class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface
+{
+ use ContractsTrait;
+ use ProxyTrait;
+ private $namespace = '';
+ private $namespaceLen;
+ private $poolHash;
+ private $defaultLifetime;
+ private static $createCacheItem;
+ private static $setInnerItem;
+ public function __construct(CacheItemPoolInterface $pool, string $namespace = '', int $defaultLifetime = 0)
+ {
+ $this->pool = $pool;
+ $this->poolHash = $poolHash = spl_object_hash($pool);
+ if ('' !== $namespace) {
+ \assert('' !== CacheItem::validateKey($namespace));
+ $this->namespace = $namespace;
+ }
+ $this->namespaceLen = \strlen($namespace);
+ $this->defaultLifetime = $defaultLifetime;
+ self::$createCacheItem ?? self::$createCacheItem = \Closure::bind(static function ($key, $innerItem, $poolHash) {
+ $item = new CacheItem();
+ $item->key = $key;
+ if (null === $innerItem) {
+ return $item;
+ }
+ $item->value = $v = $innerItem->get();
+ $item->isHit = $innerItem->isHit();
+ $item->innerItem = $innerItem;
+ $item->poolHash = $poolHash;
+ // Detect wrapped values that encode for their expiry and creation duration
+ // For compactness, these values are packed in the key of an array using
+ // magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F
+ if (\is_array($v) && 1 === \count($v) && 10 === \strlen($k = (string) array_key_first($v)) && "\x9d" === $k[0] && "\x00" === $k[5] && "_" === $k[9]) {
+ $item->value = $v[$k];
+ $v = unpack('Ve/Nc', substr($k, 1, -1));
+ $item->metadata[CacheItem::METADATA_EXPIRY] = $v['e'] + CacheItem::METADATA_EXPIRY_OFFSET;
+ $item->metadata[CacheItem::METADATA_CTIME] = $v['c'];
+ } elseif ($innerItem instanceof CacheItem) {
+ $item->metadata = $innerItem->metadata;
+ }
+ $innerItem->set(null);
+ return $item;
+ }, null, CacheItem::class);
+ self::$setInnerItem ?? self::$setInnerItem = \Closure::bind(
+ /**
+ * @param array $item A CacheItem cast to (array); accessing protected properties requires adding the "\0*\0" PHP prefix
+ */
+ static function (CacheItemInterface $innerItem, array $item) {
+ // Tags are stored separately, no need to account for them when considering this item's newly set metadata
+ if (isset(($metadata = $item["\x00*\x00newMetadata"])[CacheItem::METADATA_TAGS])) {
+ unset($metadata[CacheItem::METADATA_TAGS]);
+ }
+ if ($metadata) {
+ // For compactness, expiry and creation duration are packed in the key of an array, using magic numbers as separators
+ $item["\x00*\x00value"] = ["\x9d" . pack('VN', (int) (0.1 + $metadata[self::METADATA_EXPIRY] - self::METADATA_EXPIRY_OFFSET), $metadata[self::METADATA_CTIME]) . "_" => $item["\x00*\x00value"]];
+ }
+ $innerItem->set($item["\x00*\x00value"]);
+ $innerItem->expiresAt((null !== $item["\x00*\x00expiry"]) ? \DateTime::createFromFormat('U.u', sprintf('%.6F', $item["\x00*\x00expiry"])) : null);
+ },
+ null,
+ CacheItem::class
+ );
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null)
+ {
+ if (!$this->pool instanceof CacheInterface) {
+ return $this->doGet($this, $key, $callback, $beta, $metadata);
+ }
+ return $this->pool->get($this->getId($key), function ($innerItem, bool &$save) use ($key, $callback) {
+ $item = (self::$createCacheItem)($key, $innerItem, $this->poolHash);
+ $item->set($value = $callback($item, $save));
+ (self::$setInnerItem)($innerItem, (array) $item);
+ return $value;
+ }, $beta, $metadata);
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function getItem($key)
+ {
+ $item = $this->pool->getItem($this->getId($key));
+ return (self::$createCacheItem)($key, $item, $this->poolHash);
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function getItems(array $keys = [])
+ {
+ if ($this->namespaceLen) {
+ foreach ($keys as $i => $key) {
+ $keys[$i] = $this->getId($key);
+ }
+ }
+ return $this->generateItems($this->pool->getItems($keys));
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function hasItem($key)
+ {
+ return $this->pool->hasItem($this->getId($key));
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function clear(string $prefix = '')
+ {
+ if ($this->pool instanceof AdapterInterface) {
+ return $this->pool->clear($this->namespace . $prefix);
+ }
+ return $this->pool->clear();
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function deleteItem($key)
+ {
+ return $this->pool->deleteItem($this->getId($key));
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function deleteItems(array $keys)
+ {
+ if ($this->namespaceLen) {
+ foreach ($keys as $i => $key) {
+ $keys[$i] = $this->getId($key);
+ }
+ }
+ return $this->pool->deleteItems($keys);
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function save(CacheItemInterface $item)
+ {
+ return $this->doSave($item, __FUNCTION__);
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function saveDeferred(CacheItemInterface $item)
+ {
+ return $this->doSave($item, __FUNCTION__);
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function commit()
+ {
+ return $this->pool->commit();
+ }
+ private function doSave(CacheItemInterface $item, string $method)
+ {
+ if (!$item instanceof CacheItem) {
+ return \false;
+ }
+ $item = (array) $item;
+ if (null === $item["\x00*\x00expiry"] && 0 < $this->defaultLifetime) {
+ $item["\x00*\x00expiry"] = microtime(\true) + $this->defaultLifetime;
+ }
+ if ($item["\x00*\x00poolHash"] === $this->poolHash && $item["\x00*\x00innerItem"]) {
+ $innerItem = $item["\x00*\x00innerItem"];
+ } elseif ($this->pool instanceof AdapterInterface) {
+ // this is an optimization specific for AdapterInterface implementations
+ // so we can save a round-trip to the backend by just creating a new item
+ $innerItem = (self::$createCacheItem)($this->namespace . $item["\x00*\x00key"], null, $this->poolHash);
+ } else {
+ $innerItem = $this->pool->getItem($this->namespace . $item["\x00*\x00key"]);
+ }
+ (self::$setInnerItem)($innerItem, $item);
+ return $this->pool->{$method}($innerItem);
+ }
+ private function generateItems(iterable $items): \Generator
+ {
+ $f = self::$createCacheItem;
+ foreach ($items as $key => $item) {
+ if ($this->namespaceLen) {
+ $key = substr($key, $this->namespaceLen);
+ }
+ yield $key => $f($key, $item, $this->poolHash);
+ }
+ }
+ private function getId($key): string
+ {
+ \assert('' !== CacheItem::validateKey($key));
+ return $this->namespace . $key;
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Adapter/Psr16Adapter.php b/src/modules/common/third-party/vendor/symfony/cache/Adapter/Psr16Adapter.php
new file mode 100644
index 0000000000..e2b98d2aaa
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Adapter/Psr16Adapter.php
@@ -0,0 +1,75 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Adapter;
+
+use Wordlift\Modules\Common\Psr\SimpleCache\CacheInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\PruneableInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\ResettableInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Traits\ProxyTrait;
+/**
+ * Turns a PSR-16 cache into a PSR-6 one.
+ *
+ * @author Nicolas Grekas
+ */
+class Psr16Adapter extends AbstractAdapter implements PruneableInterface, ResettableInterface
+{
+ use ProxyTrait;
+ /**
+ * @internal
+ */
+ protected const NS_SEPARATOR = '_';
+ private $miss;
+ public function __construct(CacheInterface $pool, string $namespace = '', int $defaultLifetime = 0)
+ {
+ parent::__construct($namespace, $defaultLifetime);
+ $this->pool = $pool;
+ $this->miss = new \stdClass();
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doFetch(array $ids)
+ {
+ foreach ($this->pool->getMultiple($ids, $this->miss) as $key => $value) {
+ if ($this->miss !== $value) {
+ yield $key => $value;
+ }
+ }
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doHave(string $id)
+ {
+ return $this->pool->has($id);
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doClear(string $namespace)
+ {
+ return $this->pool->clear();
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doDelete(array $ids)
+ {
+ return $this->pool->deleteMultiple($ids);
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doSave(array $values, int $lifetime)
+ {
+ return $this->pool->setMultiple($values, (0 === $lifetime) ? null : $lifetime);
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Adapter/RedisAdapter.php b/src/modules/common/third-party/vendor/symfony/cache/Adapter/RedisAdapter.php
new file mode 100644
index 0000000000..0b36be329b
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Adapter/RedisAdapter.php
@@ -0,0 +1,29 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Adapter;
+
+use Wordlift\Modules\Common\Symfony\Component\Cache\Marshaller\MarshallerInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Traits\RedisClusterProxy;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Traits\RedisProxy;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Traits\RedisTrait;
+class RedisAdapter extends AbstractAdapter
+{
+ use RedisTrait;
+ /**
+ * @param \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|RedisProxy|RedisClusterProxy $redis The redis client
+ * @param string $namespace The default namespace
+ * @param int $defaultLifetime The default lifetime
+ */
+ public function __construct($redis, string $namespace = '', int $defaultLifetime = 0, ?MarshallerInterface $marshaller = null)
+ {
+ $this->init($redis, $namespace, $defaultLifetime, $marshaller);
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Adapter/RedisTagAwareAdapter.php b/src/modules/common/third-party/vendor/symfony/cache/Adapter/RedisTagAwareAdapter.php
new file mode 100644
index 0000000000..5b71fc409a
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Adapter/RedisTagAwareAdapter.php
@@ -0,0 +1,278 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Adapter;
+
+use Wordlift\Modules\Common\Predis\Connection\Aggregate\ClusterInterface;
+use Wordlift\Modules\Common\Predis\Connection\Aggregate\PredisCluster;
+use Wordlift\Modules\Common\Predis\Connection\Aggregate\ReplicationInterface;
+use Wordlift\Modules\Common\Predis\Response\ErrorInterface;
+use Wordlift\Modules\Common\Predis\Response\Status;
+use Wordlift\Modules\Common\Symfony\Component\Cache\CacheItem;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Exception\InvalidArgumentException;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Exception\LogicException;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Marshaller\DeflateMarshaller;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Marshaller\MarshallerInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Marshaller\TagAwareMarshaller;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Traits\RedisClusterProxy;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Traits\RedisProxy;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Traits\RedisTrait;
+/**
+ * Stores tag id <> cache id relationship as a Redis Set.
+ *
+ * Set (tag relation info) is stored without expiry (non-volatile), while cache always gets an expiry (volatile) even
+ * if not set by caller. Thus if you configure redis with the right eviction policy you can be safe this tag <> cache
+ * relationship survives eviction (cache cleanup when Redis runs out of memory).
+ *
+ * Redis server 2.8+ with any `volatile-*` eviction policy, OR `noeviction` if you're sure memory will NEVER fill up
+ *
+ * Design limitations:
+ * - Max 4 billion cache keys per cache tag as limited by Redis Set datatype.
+ * E.g. If you use a "all" items tag for expiry instead of clear(), that limits you to 4 billion cache items also.
+ *
+ * @see https://redis.io/topics/lru-cache#eviction-policies Documentation for Redis eviction policies.
+ * @see https://redis.io/topics/data-types#sets Documentation for Redis Set datatype.
+ *
+ * @author Nicolas Grekas
+ * @author André Rømcke
+ */
+class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterface, PruneableInterface, ResettableInterface, LoggerAwareInterface
+{
+ use ContractsTrait;
+ use LoggerAwareTrait;
+ use ProxyTrait;
+ public const TAGS_PREFIX = "\x00tags\x00";
+ private $deferred = [];
+ private $tags;
+ private $knownTagVersions = [];
+ private $knownTagVersionsTtl;
+ private static $createCacheItem;
+ private static $setCacheItemTags;
+ private static $getTagsByKey;
+ private static $saveTags;
+ public function __construct(AdapterInterface $itemsPool, ?AdapterInterface $tagsPool = null, float $knownTagVersionsTtl = 0.15)
+ {
+ $this->pool = $itemsPool;
+ $this->tags = $tagsPool ?: $itemsPool;
+ $this->knownTagVersionsTtl = $knownTagVersionsTtl;
+ self::$createCacheItem ?? self::$createCacheItem = \Closure::bind(static function ($key, $value, CacheItem $protoItem) {
+ $item = new CacheItem();
+ $item->key = $key;
+ $item->value = $value;
+ $item->expiry = $protoItem->expiry;
+ $item->poolHash = $protoItem->poolHash;
+ return $item;
+ }, null, CacheItem::class);
+ self::$setCacheItemTags ?? self::$setCacheItemTags = \Closure::bind(static function (CacheItem $item, $key, array &$itemTags) {
+ $item->isTaggable = \true;
+ if (!$item->isHit) {
+ return $item;
+ }
+ if (isset($itemTags[$key])) {
+ foreach ($itemTags[$key] as $tag => $version) {
+ $item->metadata[CacheItem::METADATA_TAGS][$tag] = $tag;
+ }
+ unset($itemTags[$key]);
+ } else {
+ $item->value = null;
+ $item->isHit = \false;
+ }
+ return $item;
+ }, null, CacheItem::class);
+ self::$getTagsByKey ?? self::$getTagsByKey = \Closure::bind(static function ($deferred) {
+ $tagsByKey = [];
+ foreach ($deferred as $key => $item) {
+ $tagsByKey[$key] = $item->newMetadata[CacheItem::METADATA_TAGS] ?? [];
+ $item->metadata = $item->newMetadata;
+ }
+ return $tagsByKey;
+ }, null, CacheItem::class);
+ self::$saveTags ?? self::$saveTags = \Closure::bind(static function (AdapterInterface $tagsAdapter, array $tags) {
+ ksort($tags);
+ foreach ($tags as $v) {
+ $v->expiry = 0;
+ $tagsAdapter->saveDeferred($v);
+ }
+ return $tagsAdapter->commit();
+ }, null, CacheItem::class);
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function invalidateTags(array $tags)
+ {
+ $ids = [];
+ foreach ($tags as $tag) {
+ \assert('' !== CacheItem::validateKey($tag));
+ unset($this->knownTagVersions[$tag]);
+ $ids[] = $tag . static::TAGS_PREFIX;
+ }
+ return !$tags || $this->tags->deleteItems($ids);
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function hasItem($key)
+ {
+ if (\is_string($key) && isset($this->deferred[$key])) {
+ $this->commit();
+ }
+ if (!$this->pool->hasItem($key)) {
+ return \false;
+ }
+ $itemTags = $this->pool->getItem(static::TAGS_PREFIX . $key);
+ if (!$itemTags->isHit()) {
+ return \false;
+ }
+ if (!$itemTags = $itemTags->get()) {
+ return \true;
+ }
+ foreach ($this->getTagVersions([$itemTags]) as $tag => $version) {
+ if ($itemTags[$tag] !== $version) {
+ return \false;
+ }
+ }
+ return \true;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function getItem($key)
+ {
+ foreach ($this->getItems([$key]) as $item) {
+ return $item;
+ }
+ return null;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function getItems(array $keys = [])
+ {
+ $tagKeys = [];
+ $commit = \false;
+ foreach ($keys as $key) {
+ if ('' !== $key && \is_string($key)) {
+ $commit = $commit || isset($this->deferred[$key]);
+ $key = static::TAGS_PREFIX . $key;
+ $tagKeys[$key] = $key;
+ }
+ }
+ if ($commit) {
+ $this->commit();
+ }
+ try {
+ $items = $this->pool->getItems($tagKeys + $keys);
+ } catch (InvalidArgumentException $e) {
+ $this->pool->getItems($keys);
+ // Should throw an exception
+ throw $e;
+ }
+ return $this->generateItems($items, $tagKeys);
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function clear(string $prefix = '')
+ {
+ if ('' !== $prefix) {
+ foreach ($this->deferred as $key => $item) {
+ if (str_starts_with($key, $prefix)) {
+ unset($this->deferred[$key]);
+ }
+ }
+ } else {
+ $this->deferred = [];
+ }
+ if ($this->pool instanceof AdapterInterface) {
+ return $this->pool->clear($prefix);
+ }
+ return $this->pool->clear();
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function deleteItem($key)
+ {
+ return $this->deleteItems([$key]);
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function deleteItems(array $keys)
+ {
+ foreach ($keys as $key) {
+ if ('' !== $key && \is_string($key)) {
+ $keys[] = static::TAGS_PREFIX . $key;
+ }
+ }
+ return $this->pool->deleteItems($keys);
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function save(CacheItemInterface $item)
+ {
+ if (!$item instanceof CacheItem) {
+ return \false;
+ }
+ $this->deferred[$item->getKey()] = $item;
+ return $this->commit();
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function saveDeferred(CacheItemInterface $item)
+ {
+ if (!$item instanceof CacheItem) {
+ return \false;
+ }
+ $this->deferred[$item->getKey()] = $item;
+ return \true;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function commit()
+ {
+ if (!$this->deferred) {
+ return \true;
+ }
+ $ok = \true;
+ foreach ($this->deferred as $key => $item) {
+ if (!$this->pool->saveDeferred($item)) {
+ unset($this->deferred[$key]);
+ $ok = \false;
+ }
+ }
+ $items = $this->deferred;
+ $tagsByKey = (self::$getTagsByKey)($items);
+ $this->deferred = [];
+ $tagVersions = $this->getTagVersions($tagsByKey);
+ $f = self::$createCacheItem;
+ foreach ($tagsByKey as $key => $tags) {
+ $this->pool->saveDeferred($f(static::TAGS_PREFIX . $key, array_intersect_key($tagVersions, $tags), $items[$key]));
+ }
+ return $this->pool->commit() && $ok;
+ }
+ /**
+ * @return array
+ */
+ public function __sleep()
+ {
+ throw new \BadMethodCallException('Cannot serialize ' . __CLASS__);
+ }
+ public function __wakeup()
+ {
+ throw new \BadMethodCallException('Cannot unserialize ' . __CLASS__);
+ }
+ public function __destruct()
+ {
+ $this->commit();
+ }
+ private function generateItems(iterable $items, array $tagKeys): \Generator
+ {
+ $bufferedItems = $itemTags = [];
+ $f = self::$setCacheItemTags;
+ foreach ($items as $key => $item) {
+ if (!$tagKeys) {
+ yield $key => $f($item, static::TAGS_PREFIX . $key, $itemTags);
+ continue;
+ }
+ if (!isset($tagKeys[$key])) {
+ $bufferedItems[$key] = $item;
+ continue;
+ }
+ unset($tagKeys[$key]);
+ if ($item->isHit()) {
+ $itemTags[$key] = $item->get() ?: [];
+ }
+ if (!$tagKeys) {
+ $tagVersions = $this->getTagVersions($itemTags);
+ foreach ($itemTags as $key => $tags) {
+ foreach ($tags as $tag => $version) {
+ if ($tagVersions[$tag] !== $version) {
+ unset($itemTags[$key]);
+ continue 2;
+ }
+ }
+ }
+ $tagVersions = $tagKeys = null;
+ foreach ($bufferedItems as $key => $item) {
+ yield $key => $f($item, static::TAGS_PREFIX . $key, $itemTags);
+ }
+ $bufferedItems = null;
+ }
+ }
+ }
+ private function getTagVersions(array $tagsByKey)
+ {
+ $tagVersions = [];
+ $fetchTagVersions = \false;
+ foreach ($tagsByKey as $tags) {
+ $tagVersions += $tags;
+ foreach ($tags as $tag => $version) {
+ if ($tagVersions[$tag] !== $version) {
+ unset($this->knownTagVersions[$tag]);
+ }
+ }
+ }
+ if (!$tagVersions) {
+ return [];
+ }
+ $now = microtime(\true);
+ $tags = [];
+ foreach ($tagVersions as $tag => $version) {
+ $tags[$tag . static::TAGS_PREFIX] = $tag;
+ if ($fetchTagVersions || ($this->knownTagVersions[$tag][1] ?? null) !== $version || $now - $this->knownTagVersions[$tag][0] >= $this->knownTagVersionsTtl) {
+ // reuse previously fetched tag versions up to the ttl
+ $fetchTagVersions = \true;
+ }
+ }
+ if (!$fetchTagVersions) {
+ return $tagVersions;
+ }
+ $newTags = [];
+ $newVersion = null;
+ foreach ($this->tags->getItems(array_keys($tags)) as $tag => $version) {
+ if (!$version->isHit()) {
+ $newTags[$tag] = $version->set($newVersion ?? $newVersion = random_int(\PHP_INT_MIN, \PHP_INT_MAX));
+ }
+ $tagVersions[$tag = $tags[$tag]] = $version->get();
+ $this->knownTagVersions[$tag] = [$now, $tagVersions[$tag]];
+ }
+ if ($newTags) {
+ (self::$saveTags)($this->tags, $newTags);
+ }
+ return $tagVersions;
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Adapter/TagAwareAdapterInterface.php b/src/modules/common/third-party/vendor/symfony/cache/Adapter/TagAwareAdapterInterface.php
new file mode 100644
index 0000000000..fb66ae621c
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Adapter/TagAwareAdapterInterface.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Adapter;
+
+use Wordlift\Modules\Common\Psr\Cache\InvalidArgumentException;
+/**
+ * Interface for invalidating cached items using tags.
+ *
+ * @author Nicolas Grekas
+ */
+interface TagAwareAdapterInterface extends AdapterInterface
+{
+ /**
+ * Invalidates cached items using tags.
+ *
+ * @param string[] $tags An array of tags to invalidate
+ *
+ * @return bool
+ *
+ * @throws InvalidArgumentException When $tags is not valid
+ */
+ public function invalidateTags(array $tags);
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Adapter/TraceableAdapter.php b/src/modules/common/third-party/vendor/symfony/cache/Adapter/TraceableAdapter.php
new file mode 100644
index 0000000000..8d741885e4
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Adapter/TraceableAdapter.php
@@ -0,0 +1,266 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Adapter;
+
+use Wordlift\Modules\Common\Psr\Cache\CacheItemInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\CacheItem;
+use Wordlift\Modules\Common\Symfony\Component\Cache\PruneableInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\ResettableInterface;
+use Wordlift\Modules\Common\Symfony\Contracts\Cache\CacheInterface;
+use Wordlift\Modules\Common\Symfony\Contracts\Service\ResetInterface;
+/**
+ * An adapter that collects data about all cache calls.
+ *
+ * @author Aaron Scherer
+ */
+class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface
+{
+ protected $pool;
+ private $calls = [];
+ public function __construct(AdapterInterface $pool)
+ {
+ $this->pool = $pool;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null)
+ {
+ if (!$this->pool instanceof CacheInterface) {
+ throw new \BadMethodCallException(sprintf('Cannot call "%s::get()": this class doesn\'t implement "%s".', get_debug_type($this->pool), CacheInterface::class));
+ }
+ $isHit = \true;
+ $callback = function (CacheItem $item, bool &$save) use ($callback, &$isHit) {
+ $isHit = $item->isHit();
+ return $callback($item, $save);
+ };
+ $event = $this->start(__FUNCTION__);
+ try {
+ $value = $this->pool->get($key, $callback, $beta, $metadata);
+ $event->result[$key] = get_debug_type($value);
+ } finally {
+ $event->end = microtime(\true);
+ }
+ if ($isHit) {
+ ++$event->hits;
+ } else {
+ ++$event->misses;
+ }
+ return $value;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function getItem($key)
+ {
+ $event = $this->start(__FUNCTION__);
+ try {
+ $item = $this->pool->getItem($key);
+ } finally {
+ $event->end = microtime(\true);
+ }
+ if ($event->result[$key] = $item->isHit()) {
+ ++$event->hits;
+ } else {
+ ++$event->misses;
+ }
+ return $item;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function hasItem($key)
+ {
+ $event = $this->start(__FUNCTION__);
+ try {
+ return $event->result[$key] = $this->pool->hasItem($key);
+ } finally {
+ $event->end = microtime(\true);
+ }
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function deleteItem($key)
+ {
+ $event = $this->start(__FUNCTION__);
+ try {
+ return $event->result[$key] = $this->pool->deleteItem($key);
+ } finally {
+ $event->end = microtime(\true);
+ }
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function save(CacheItemInterface $item)
+ {
+ $event = $this->start(__FUNCTION__);
+ try {
+ return $event->result[$item->getKey()] = $this->pool->save($item);
+ } finally {
+ $event->end = microtime(\true);
+ }
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function saveDeferred(CacheItemInterface $item)
+ {
+ $event = $this->start(__FUNCTION__);
+ try {
+ return $event->result[$item->getKey()] = $this->pool->saveDeferred($item);
+ } finally {
+ $event->end = microtime(\true);
+ }
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function getItems(array $keys = [])
+ {
+ $event = $this->start(__FUNCTION__);
+ try {
+ $result = $this->pool->getItems($keys);
+ } finally {
+ $event->end = microtime(\true);
+ }
+ $f = function () use ($result, $event) {
+ $event->result = [];
+ foreach ($result as $key => $item) {
+ if ($event->result[$key] = $item->isHit()) {
+ ++$event->hits;
+ } else {
+ ++$event->misses;
+ }
+ yield $key => $item;
+ }
+ };
+ return $f();
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function clear(string $prefix = '')
+ {
+ $event = $this->start(__FUNCTION__);
+ try {
+ if ($this->pool instanceof AdapterInterface) {
+ return $event->result = $this->pool->clear($prefix);
+ }
+ return $event->result = $this->pool->clear();
+ } finally {
+ $event->end = microtime(\true);
+ }
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function deleteItems(array $keys)
+ {
+ $event = $this->start(__FUNCTION__);
+ $event->result['keys'] = $keys;
+ try {
+ return $event->result['result'] = $this->pool->deleteItems($keys);
+ } finally {
+ $event->end = microtime(\true);
+ }
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function commit()
+ {
+ $event = $this->start(__FUNCTION__);
+ try {
+ return $event->result = $this->pool->commit();
+ } finally {
+ $event->end = microtime(\true);
+ }
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function prune()
+ {
+ if (!$this->pool instanceof PruneableInterface) {
+ return \false;
+ }
+ $event = $this->start(__FUNCTION__);
+ try {
+ return $event->result = $this->pool->prune();
+ } finally {
+ $event->end = microtime(\true);
+ }
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function reset()
+ {
+ if ($this->pool instanceof ResetInterface) {
+ $this->pool->reset();
+ }
+ $this->clearCalls();
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function delete(string $key): bool
+ {
+ $event = $this->start(__FUNCTION__);
+ try {
+ return $event->result[$key] = $this->pool->deleteItem($key);
+ } finally {
+ $event->end = microtime(\true);
+ }
+ }
+ public function getCalls()
+ {
+ return $this->calls;
+ }
+ public function clearCalls()
+ {
+ $this->calls = [];
+ }
+ protected function start(string $name)
+ {
+ $this->calls[] = $event = new TraceableAdapterEvent();
+ $event->name = $name;
+ $event->start = microtime(\true);
+ return $event;
+ }
+}
+class TraceableAdapterEvent
+{
+ public $name;
+ public $start;
+ public $end;
+ public $result;
+ public $hits = 0;
+ public $misses = 0;
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Adapter/TraceableTagAwareAdapter.php b/src/modules/common/third-party/vendor/symfony/cache/Adapter/TraceableTagAwareAdapter.php
new file mode 100644
index 0000000000..fff64d6e15
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Adapter/TraceableTagAwareAdapter.php
@@ -0,0 +1,35 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Adapter;
+
+use Wordlift\Modules\Common\Symfony\Contracts\Cache\TagAwareCacheInterface;
+/**
+ * @author Robin Chalas
+ */
+final class CacheItem implements ItemInterface
+{
+ private const METADATA_EXPIRY_OFFSET = 1527506807;
+ protected $key;
+ protected $value;
+ protected $isHit = \false;
+ protected $expiry;
+ protected $metadata = [];
+ protected $newMetadata = [];
+ protected $innerItem;
+ protected $poolHash;
+ protected $isTaggable = \false;
+ /**
+ * {@inheritdoc}
+ */
+ public function getKey(): string
+ {
+ return $this->key;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return mixed
+ */
+ public function get()
+ {
+ return $this->value;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function isHit(): bool
+ {
+ return $this->isHit;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return $this
+ */
+ public function set($value): self
+ {
+ $this->value = $value;
+ return $this;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return $this
+ */
+ public function expiresAt($expiration): self
+ {
+ if (null === $expiration) {
+ $this->expiry = null;
+ } elseif ($expiration instanceof \DateTimeInterface) {
+ $this->expiry = (float) $expiration->format('U.u');
+ } else {
+ throw new InvalidArgumentException(sprintf('Expiration date must implement DateTimeInterface or be null, "%s" given.', get_debug_type($expiration)));
+ }
+ return $this;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return $this
+ */
+ public function expiresAfter($time): self
+ {
+ if (null === $time) {
+ $this->expiry = null;
+ } elseif ($time instanceof \DateInterval) {
+ $this->expiry = microtime(\true) + \DateTime::createFromFormat('U', 0)->add($time)->format('U.u');
+ } elseif (\is_int($time)) {
+ $this->expiry = $time + microtime(\true);
+ } else {
+ throw new InvalidArgumentException(sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given.', get_debug_type($time)));
+ }
+ return $this;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function tag($tags): ItemInterface
+ {
+ if (!$this->isTaggable) {
+ throw new LogicException(sprintf('Cache item "%s" comes from a non tag-aware pool: you cannot tag it.', $this->key));
+ }
+ if (!is_iterable($tags)) {
+ $tags = [$tags];
+ }
+ foreach ($tags as $tag) {
+ if (!\is_string($tag) && !(\is_object($tag) && method_exists($tag, '__toString'))) {
+ throw new InvalidArgumentException(sprintf('Cache tag must be string or object that implements __toString(), "%s" given.', \is_object($tag) ? \get_class($tag) : \gettype($tag)));
+ }
+ $tag = (string) $tag;
+ if (isset($this->newMetadata[self::METADATA_TAGS][$tag])) {
+ continue;
+ }
+ if ('' === $tag) {
+ throw new InvalidArgumentException('Cache tag length must be greater than zero.');
+ }
+ if (\false !== strpbrk($tag, self::RESERVED_CHARACTERS)) {
+ throw new InvalidArgumentException(sprintf('Cache tag "%s" contains reserved characters "%s".', $tag, self::RESERVED_CHARACTERS));
+ }
+ $this->newMetadata[self::METADATA_TAGS][$tag] = $tag;
+ }
+ return $this;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function getMetadata(): array
+ {
+ return $this->metadata;
+ }
+ /**
+ * Validates a cache key according to PSR-6.
+ *
+ * @param mixed $key The key to validate
+ *
+ * @throws InvalidArgumentException When $key is not valid
+ */
+ public static function validateKey($key): string
+ {
+ if (!\is_string($key)) {
+ throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
+ }
+ if ('' === $key) {
+ throw new InvalidArgumentException('Cache key length must be greater than zero.');
+ }
+ if (\false !== strpbrk($key, self::RESERVED_CHARACTERS)) {
+ throw new InvalidArgumentException(sprintf('Cache key "%s" contains reserved characters "%s".', $key, self::RESERVED_CHARACTERS));
+ }
+ return $key;
+ }
+ /**
+ * Internal logging helper.
+ *
+ * @internal
+ */
+ public static function log(?LoggerInterface $logger, string $message, array $context = [])
+ {
+ if ($logger) {
+ $logger->warning($message, $context);
+ } else {
+ $replace = [];
+ foreach ($context as $k => $v) {
+ if (\is_scalar($v)) {
+ $replace['{' . $k . '}'] = $v;
+ }
+ }
+ @trigger_error(strtr($message, $replace), \E_USER_WARNING);
+ }
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/DataCollector/CacheDataCollector.php b/src/modules/common/third-party/vendor/symfony/cache/DataCollector/CacheDataCollector.php
new file mode 100644
index 0000000000..d0a32de8c2
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/DataCollector/CacheDataCollector.php
@@ -0,0 +1,152 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\DataCollector;
+
+use Wordlift\Modules\Common\Symfony\Component\Cache\Adapter\TraceableAdapter;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Adapter\TraceableAdapterEvent;
+use Wordlift\Modules\Common\Symfony\Component\HttpFoundation\Request;
+use Wordlift\Modules\Common\Symfony\Component\HttpFoundation\Response;
+use Wordlift\Modules\Common\Symfony\Component\HttpKernel\DataCollector\DataCollector;
+use Wordlift\Modules\Common\Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
+/**
+ * @author Aaron Scherer
+ */
+class CachePoolClearerPass implements CompilerPassInterface
+{
+ private $cachePoolClearerTag;
+ public function __construct(string $cachePoolClearerTag = 'cache.pool.clearer')
+ {
+ if (0 < \func_num_args()) {
+ trigger_deprecation('symfony/cache', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
+ }
+ $this->cachePoolClearerTag = $cachePoolClearerTag;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function process(ContainerBuilder $container)
+ {
+ $container->getParameterBag()->remove('cache.prefix.seed');
+ foreach ($container->findTaggedServiceIds($this->cachePoolClearerTag) as $id => $attr) {
+ $clearer = $container->getDefinition($id);
+ $pools = [];
+ foreach ($clearer->getArgument(0) as $name => $ref) {
+ if ($container->hasDefinition($ref)) {
+ $pools[$name] = new Reference($ref);
+ }
+ }
+ $clearer->replaceArgument(0, $pools);
+ }
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/DependencyInjection/CachePoolPass.php b/src/modules/common/third-party/vendor/symfony/cache/DependencyInjection/CachePoolPass.php
new file mode 100644
index 0000000000..27f99952b1
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/DependencyInjection/CachePoolPass.php
@@ -0,0 +1,223 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\DependencyInjection;
+
+use Wordlift\Modules\Common\Symfony\Component\Cache\Adapter\AbstractAdapter;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Adapter\ArrayAdapter;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Adapter\ChainAdapter;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Adapter\NullAdapter;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Adapter\ParameterNormalizer;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Messenger\EarlyExpirationDispatcher;
+use Wordlift\Modules\Common\Symfony\Component\DependencyInjection\ChildDefinition;
+use Wordlift\Modules\Common\Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Wordlift\Modules\Common\Symfony\Component\DependencyInjection\ContainerBuilder;
+use Wordlift\Modules\Common\Symfony\Component\DependencyInjection\Definition;
+use Wordlift\Modules\Common\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
+use Wordlift\Modules\Common\Symfony\Component\DependencyInjection\Reference;
+/**
+ * @author Nicolas Grekas
+ */
+class CachePoolPass implements CompilerPassInterface
+{
+ private $cachePoolTag;
+ private $kernelResetTag;
+ private $cacheClearerId;
+ private $cachePoolClearerTag;
+ private $cacheSystemClearerId;
+ private $cacheSystemClearerTag;
+ private $reverseContainerId;
+ private $reversibleTag;
+ private $messageHandlerId;
+ public function __construct(string $cachePoolTag = 'cache.pool', string $kernelResetTag = 'kernel.reset', string $cacheClearerId = 'cache.global_clearer', string $cachePoolClearerTag = 'cache.pool.clearer', string $cacheSystemClearerId = 'cache.system_clearer', string $cacheSystemClearerTag = 'kernel.cache_clearer', string $reverseContainerId = 'reverse_container', string $reversibleTag = 'container.reversible', string $messageHandlerId = 'cache.early_expiration_handler')
+ {
+ if (0 < \func_num_args()) {
+ trigger_deprecation('symfony/cache', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
+ }
+ $this->cachePoolTag = $cachePoolTag;
+ $this->kernelResetTag = $kernelResetTag;
+ $this->cacheClearerId = $cacheClearerId;
+ $this->cachePoolClearerTag = $cachePoolClearerTag;
+ $this->cacheSystemClearerId = $cacheSystemClearerId;
+ $this->cacheSystemClearerTag = $cacheSystemClearerTag;
+ $this->reverseContainerId = $reverseContainerId;
+ $this->reversibleTag = $reversibleTag;
+ $this->messageHandlerId = $messageHandlerId;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function process(ContainerBuilder $container)
+ {
+ if ($container->hasParameter('cache.prefix.seed')) {
+ $seed = $container->getParameterBag()->resolveValue($container->getParameter('cache.prefix.seed'));
+ } else {
+ $seed = '_' . $container->getParameter('kernel.project_dir');
+ $seed .= '.' . $container->getParameter('kernel.container_class');
+ }
+ $needsMessageHandler = \false;
+ $allPools = [];
+ $clearers = [];
+ $attributes = ['provider', 'name', 'namespace', 'default_lifetime', 'early_expiration_message_bus', 'reset'];
+ foreach ($container->findTaggedServiceIds($this->cachePoolTag) as $id => $tags) {
+ $adapter = $pool = $container->getDefinition($id);
+ if ($pool->isAbstract()) {
+ continue;
+ }
+ $class = $adapter->getClass();
+ while ($adapter instanceof ChildDefinition) {
+ $adapter = $container->findDefinition($adapter->getParent());
+ $class = $class ?: $adapter->getClass();
+ if ($t = $adapter->getTag($this->cachePoolTag)) {
+ $tags[0] += $t[0];
+ }
+ }
+ $name = $tags[0]['name'] ?? $id;
+ if (!isset($tags[0]['namespace'])) {
+ $namespaceSeed = $seed;
+ if (null !== $class) {
+ $namespaceSeed .= '.' . $class;
+ }
+ $tags[0]['namespace'] = $this->getNamespace($namespaceSeed, $name);
+ }
+ if (isset($tags[0]['clearer'])) {
+ $clearer = $tags[0]['clearer'];
+ while ($container->hasAlias($clearer)) {
+ $clearer = (string) $container->getAlias($clearer);
+ }
+ } else {
+ $clearer = null;
+ }
+ unset($tags[0]['clearer'], $tags[0]['name']);
+ if (isset($tags[0]['provider'])) {
+ $tags[0]['provider'] = new Reference(static::getServiceProvider($container, $tags[0]['provider']));
+ }
+ if (ChainAdapter::class === $class) {
+ $adapters = [];
+ foreach ($adapter->getArgument(0) as $provider => $adapter) {
+ if ($adapter instanceof ChildDefinition) {
+ $chainedPool = $adapter;
+ } else {
+ $chainedPool = $adapter = new ChildDefinition($adapter);
+ }
+ $chainedTags = [\is_int($provider) ? [] : ['provider' => $provider]];
+ $chainedClass = '';
+ while ($adapter instanceof ChildDefinition) {
+ $adapter = $container->findDefinition($adapter->getParent());
+ $chainedClass = $chainedClass ?: $adapter->getClass();
+ if ($t = $adapter->getTag($this->cachePoolTag)) {
+ $chainedTags[0] += $t[0];
+ }
+ }
+ if (ChainAdapter::class === $chainedClass) {
+ throw new InvalidArgumentException(sprintf('Invalid service "%s": chain of adapters cannot reference another chain, found "%s".', $id, $chainedPool->getParent()));
+ }
+ $i = 0;
+ if (isset($chainedTags[0]['provider'])) {
+ $chainedPool->replaceArgument($i++, new Reference(static::getServiceProvider($container, $chainedTags[0]['provider'])));
+ }
+ if (isset($tags[0]['namespace']) && !\in_array($adapter->getClass(), [ArrayAdapter::class, NullAdapter::class], \true)) {
+ $chainedPool->replaceArgument($i++, $tags[0]['namespace']);
+ }
+ if (isset($tags[0]['default_lifetime'])) {
+ $chainedPool->replaceArgument($i++, $tags[0]['default_lifetime']);
+ }
+ $adapters[] = $chainedPool;
+ }
+ $pool->replaceArgument(0, $adapters);
+ unset($tags[0]['provider'], $tags[0]['namespace']);
+ $i = 1;
+ } else {
+ $i = 0;
+ }
+ foreach ($attributes as $attr) {
+ if (!isset($tags[0][$attr])) {
+ // no-op
+ } elseif ('reset' === $attr) {
+ if ($tags[0][$attr]) {
+ $pool->addTag($this->kernelResetTag, ['method' => $tags[0][$attr]]);
+ }
+ } elseif ('early_expiration_message_bus' === $attr) {
+ $needsMessageHandler = \true;
+ $pool->addMethodCall('setCallbackWrapper', [(new Definition(EarlyExpirationDispatcher::class))->addArgument(new Reference($tags[0]['early_expiration_message_bus']))->addArgument(new Reference($this->reverseContainerId))->addArgument((new Definition('callable'))->setFactory([new Reference($id), 'setCallbackWrapper'])->addArgument(null))]);
+ $pool->addTag($this->reversibleTag);
+ } elseif ('namespace' !== $attr || !\in_array($class, [ArrayAdapter::class, NullAdapter::class], \true)) {
+ $argument = $tags[0][$attr];
+ if ('default_lifetime' === $attr && !is_numeric($argument)) {
+ $argument = (new Definition('int', [$argument]))->setFactory([ParameterNormalizer::class, 'normalizeDuration']);
+ }
+ $pool->replaceArgument($i++, $argument);
+ }
+ unset($tags[0][$attr]);
+ }
+ if (!empty($tags[0])) {
+ throw new InvalidArgumentException(sprintf('Invalid "%s" tag for service "%s": accepted attributes are "clearer", "provider", "name", "namespace", "default_lifetime", "early_expiration_message_bus" and "reset", found "%s".', $this->cachePoolTag, $id, implode('", "', array_keys($tags[0]))));
+ }
+ if (null !== $clearer) {
+ $clearers[$clearer][$name] = new Reference($id, $container::IGNORE_ON_UNINITIALIZED_REFERENCE);
+ }
+ $allPools[$name] = new Reference($id, $container::IGNORE_ON_UNINITIALIZED_REFERENCE);
+ }
+ if (!$needsMessageHandler) {
+ $container->removeDefinition($this->messageHandlerId);
+ }
+ $notAliasedCacheClearerId = $this->cacheClearerId;
+ while ($container->hasAlias($notAliasedCacheClearerId)) {
+ $notAliasedCacheClearerId = (string) $container->getAlias($notAliasedCacheClearerId);
+ }
+ if ($container->hasDefinition($notAliasedCacheClearerId)) {
+ $clearers[$notAliasedCacheClearerId] = $allPools;
+ }
+ foreach ($clearers as $id => $pools) {
+ $clearer = $container->getDefinition($id);
+ if ($clearer instanceof ChildDefinition) {
+ $clearer->replaceArgument(0, $pools);
+ } else {
+ $clearer->setArgument(0, $pools);
+ }
+ $clearer->addTag($this->cachePoolClearerTag);
+ if ($this->cacheSystemClearerId === $id) {
+ $clearer->addTag($this->cacheSystemClearerTag);
+ }
+ }
+ $allPoolsKeys = array_keys($allPools);
+ if ($container->hasDefinition('console.command.cache_pool_list')) {
+ $container->getDefinition('console.command.cache_pool_list')->replaceArgument(0, $allPoolsKeys);
+ }
+ if ($container->hasDefinition('console.command.cache_pool_clear')) {
+ $container->getDefinition('console.command.cache_pool_clear')->addArgument($allPoolsKeys);
+ }
+ if ($container->hasDefinition('console.command.cache_pool_delete')) {
+ $container->getDefinition('console.command.cache_pool_delete')->addArgument($allPoolsKeys);
+ }
+ }
+ private function getNamespace(string $seed, string $id)
+ {
+ return substr(str_replace('/', '-', base64_encode(hash('sha256', $id . $seed, \true))), 0, 10);
+ }
+ /**
+ * @internal
+ */
+ public static function getServiceProvider(ContainerBuilder $container, string $name)
+ {
+ $container->resolveEnvPlaceholders($name, null, $usedEnvs);
+ if ($usedEnvs || preg_match('#^[a-z]++:#', $name)) {
+ $dsn = $name;
+ if (!$container->hasDefinition($name = '.cache_connection.' . ContainerBuilder::hash($dsn))) {
+ $definition = new Definition(AbstractAdapter::class);
+ $definition->setPublic(\false);
+ $definition->setFactory([AbstractAdapter::class, 'createConnection']);
+ $definition->setArguments([$dsn, ['lazy' => \true]]);
+ $container->setDefinition($name, $definition);
+ }
+ }
+ return $name;
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/DependencyInjection/CachePoolPrunerPass.php b/src/modules/common/third-party/vendor/symfony/cache/DependencyInjection/CachePoolPrunerPass.php
new file mode 100644
index 0000000000..964d200e50
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/DependencyInjection/CachePoolPrunerPass.php
@@ -0,0 +1,54 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\DependencyInjection;
+
+use Wordlift\Modules\Common\Symfony\Component\Cache\PruneableInterface;
+use Wordlift\Modules\Common\Symfony\Component\DependencyInjection\Argument\IteratorArgument;
+use Wordlift\Modules\Common\Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Wordlift\Modules\Common\Symfony\Component\DependencyInjection\ContainerBuilder;
+use Wordlift\Modules\Common\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
+use Wordlift\Modules\Common\Symfony\Component\DependencyInjection\Reference;
+/**
+ * @author Rob Frawley 2nd
+ *
+ * @deprecated Use Doctrine\Common\Cache\Psr6\DoctrineProvider instead
+ */
+class DoctrineProvider extends CacheProvider implements PruneableInterface, ResettableInterface
+{
+ private $pool;
+ public function __construct(CacheItemPoolInterface $pool)
+ {
+ trigger_deprecation('symfony/cache', '5.4', '"%s" is deprecated, use "Doctrine\Common\Cache\Psr6\DoctrineProvider" instead.', __CLASS__);
+ $this->pool = $pool;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function prune()
+ {
+ return $this->pool instanceof PruneableInterface && $this->pool->prune();
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function reset()
+ {
+ if ($this->pool instanceof ResetInterface) {
+ $this->pool->reset();
+ }
+ $this->setNamespace($this->getNamespace());
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return mixed
+ */
+ protected function doFetch($id)
+ {
+ $item = $this->pool->getItem(rawurlencode($id));
+ return $item->isHit() ? $item->get() : \false;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ protected function doContains($id)
+ {
+ return $this->pool->hasItem(rawurlencode($id));
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ protected function doSave($id, $data, $lifeTime = 0)
+ {
+ $item = $this->pool->getItem(rawurlencode($id));
+ if (0 < $lifeTime) {
+ $item->expiresAfter($lifeTime);
+ }
+ return $this->pool->save($item->set($data));
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ protected function doDelete($id)
+ {
+ return $this->pool->deleteItem(rawurlencode($id));
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ protected function doFlush()
+ {
+ return $this->pool->clear();
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return array|null
+ */
+ protected function doGetStats()
+ {
+ return null;
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Exception/CacheException.php b/src/modules/common/third-party/vendor/symfony/cache/Exception/CacheException.php
new file mode 100644
index 0000000000..6f8fc8084b
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Exception/CacheException.php
@@ -0,0 +1,23 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Exception;
+
+use Wordlift\Modules\Common\Psr\Cache\CacheException as Psr6CacheInterface;
+use Wordlift\Modules\Common\Psr\SimpleCache\CacheException as SimpleCacheInterface;
+if (interface_exists(SimpleCacheInterface::class)) {
+ class CacheException extends \Exception implements Psr6CacheInterface, SimpleCacheInterface
+ {
+ }
+} else {
+ class CacheException extends \Exception implements Psr6CacheInterface
+ {
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Exception/InvalidArgumentException.php b/src/modules/common/third-party/vendor/symfony/cache/Exception/InvalidArgumentException.php
new file mode 100644
index 0000000000..c89501e6cd
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Exception/InvalidArgumentException.php
@@ -0,0 +1,23 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Exception;
+
+use Wordlift\Modules\Common\Psr\Cache\InvalidArgumentException as Psr6CacheInterface;
+use Wordlift\Modules\Common\Psr\SimpleCache\InvalidArgumentException as SimpleCacheInterface;
+if (interface_exists(SimpleCacheInterface::class)) {
+ class InvalidArgumentException extends \InvalidArgumentException implements Psr6CacheInterface, SimpleCacheInterface
+ {
+ }
+} else {
+ class InvalidArgumentException extends \InvalidArgumentException implements Psr6CacheInterface
+ {
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Exception/LogicException.php b/src/modules/common/third-party/vendor/symfony/cache/Exception/LogicException.php
new file mode 100644
index 0000000000..193043b2ea
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Exception/LogicException.php
@@ -0,0 +1,23 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Exception;
+
+use Wordlift\Modules\Common\Psr\Cache\CacheException as Psr6CacheInterface;
+use Wordlift\Modules\Common\Psr\SimpleCache\CacheException as SimpleCacheInterface;
+if (interface_exists(SimpleCacheInterface::class)) {
+ class LogicException extends \LogicException implements Psr6CacheInterface, SimpleCacheInterface
+ {
+ }
+} else {
+ class LogicException extends \LogicException implements Psr6CacheInterface
+ {
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/LockRegistry.php b/src/modules/common/third-party/vendor/symfony/cache/LockRegistry.php
new file mode 100644
index 0000000000..b3f248a17e
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/LockRegistry.php
@@ -0,0 +1,120 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache;
+
+use Wordlift\Modules\Common\Psr\Log\LoggerInterface;
+use Wordlift\Modules\Common\Symfony\Contracts\Cache\CacheInterface;
+use Wordlift\Modules\Common\Symfony\Contracts\Cache\ItemInterface;
+/**
+ * LockRegistry is used internally by existing adapters to protect against cache stampede.
+ *
+ * It does so by wrapping the computation of items in a pool of locks.
+ * Foreach each apps, there can be at most 20 concurrent processes that
+ * compute items at the same time and only one per cache-key.
+ *
+ * @author Nicolas Grekas
+ */
+final class LockRegistry
+{
+ private static $openedFiles = [];
+ private static $lockedFiles;
+ private static $signalingException;
+ private static $signalingCallback;
+ /**
+ * The number of items in this list controls the max number of concurrent processes.
+ */
+ private static $files = [__DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'AbstractAdapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'AbstractTagAwareAdapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'AdapterInterface.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'ApcuAdapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'ArrayAdapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'ChainAdapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'CouchbaseBucketAdapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'CouchbaseCollectionAdapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'DoctrineAdapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'DoctrineDbalAdapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'FilesystemAdapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'FilesystemTagAwareAdapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'MemcachedAdapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'NullAdapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'ParameterNormalizer.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'PdoAdapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'PhpArrayAdapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'PhpFilesAdapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'ProxyAdapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'Psr16Adapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'RedisAdapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'RedisTagAwareAdapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'TagAwareAdapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'TagAwareAdapterInterface.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'TraceableAdapter.php', __DIR__ . \DIRECTORY_SEPARATOR . 'Adapter' . \DIRECTORY_SEPARATOR . 'TraceableTagAwareAdapter.php'];
+ /**
+ * Defines a set of existing files that will be used as keys to acquire locks.
+ *
+ * @return array The previously defined set of files
+ */
+ public static function setFiles(array $files): array
+ {
+ $previousFiles = self::$files;
+ self::$files = $files;
+ foreach (self::$openedFiles as $file) {
+ if ($file) {
+ flock($file, \LOCK_UN);
+ fclose($file);
+ }
+ }
+ self::$openedFiles = self::$lockedFiles = [];
+ return $previousFiles;
+ }
+ public static function compute(callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, ?\Closure $setMetadata = null, ?LoggerInterface $logger = null)
+ {
+ if ('\\' === \DIRECTORY_SEPARATOR && null === self::$lockedFiles) {
+ // disable locking on Windows by default
+ self::$files = self::$lockedFiles = [];
+ }
+ $key = self::$files ? abs(crc32($item->getKey())) % \count(self::$files) : -1;
+ if ($key < 0 || self::$lockedFiles || !$lock = self::open($key)) {
+ return $callback($item, $save);
+ }
+ self::$signalingException ?? self::$signalingException = unserialize("O:9:\"Exception\":1:{s:16:\"\x00Exception\x00trace\";a:0:{}}");
+ self::$signalingCallback ?? self::$signalingCallback = function () {
+ throw self::$signalingException;
+ };
+ while (\true) {
+ try {
+ $locked = \false;
+ // race to get the lock in non-blocking mode
+ $locked = flock($lock, \LOCK_EX | \LOCK_NB, $wouldBlock);
+ if ($locked || !$wouldBlock) {
+ $logger && $logger->info(sprintf('Lock %s, now computing item "{key}"', $locked ? 'acquired' : 'not supported'), ['key' => $item->getKey()]);
+ self::$lockedFiles[$key] = \true;
+ $value = $callback($item, $save);
+ if ($save) {
+ if ($setMetadata) {
+ $setMetadata($item);
+ }
+ $pool->save($item->set($value));
+ $save = \false;
+ }
+ return $value;
+ }
+ // if we failed the race, retry locking in blocking mode to wait for the winner
+ $logger && $logger->info('Item "{key}" is locked, waiting for it to be released', ['key' => $item->getKey()]);
+ flock($lock, \LOCK_SH);
+ } finally {
+ flock($lock, \LOCK_UN);
+ unset(self::$lockedFiles[$key]);
+ }
+ try {
+ $value = $pool->get($item->getKey(), self::$signalingCallback, 0);
+ $logger && $logger->info('Item "{key}" retrieved after lock was released', ['key' => $item->getKey()]);
+ $save = \false;
+ return $value;
+ } catch (\Exception $e) {
+ if (self::$signalingException !== $e) {
+ throw $e;
+ }
+ $logger && $logger->info('Item "{key}" not found while lock was released, now retrying', ['key' => $item->getKey()]);
+ }
+ }
+ return null;
+ }
+ private static function open(int $key)
+ {
+ if (null !== $h = self::$openedFiles[$key] ?? null) {
+ return $h;
+ }
+ set_error_handler(function () {
+ });
+ try {
+ $h = fopen(self::$files[$key], 'r+');
+ } finally {
+ restore_error_handler();
+ }
+ return self::$openedFiles[$key] = $h ?: @fopen(self::$files[$key], 'r');
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Marshaller/DefaultMarshaller.php b/src/modules/common/third-party/vendor/symfony/cache/Marshaller/DefaultMarshaller.php
new file mode 100644
index 0000000000..38040a1387
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Marshaller/DefaultMarshaller.php
@@ -0,0 +1,95 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Marshaller;
+
+use Wordlift\Modules\Common\Symfony\Component\Cache\Exception\CacheException;
+/**
+ * Serializes/unserializes values using igbinary_serialize() if available, serialize() otherwise.
+ *
+ * @author Nicolas Grekas
+ */
+class DefaultMarshaller implements MarshallerInterface
+{
+ private $useIgbinarySerialize = \true;
+ private $throwOnSerializationFailure;
+ public function __construct(?bool $useIgbinarySerialize = null, bool $throwOnSerializationFailure = \false)
+ {
+ if (null === $useIgbinarySerialize) {
+ $useIgbinarySerialize = \extension_loaded('igbinary') && (\PHP_VERSION_ID < 70400 || version_compare('3.1.6', phpversion('igbinary'), '<='));
+ } elseif ($useIgbinarySerialize && (!\extension_loaded('igbinary') || \PHP_VERSION_ID >= 70400 && version_compare('3.1.6', phpversion('igbinary'), '>'))) {
+ throw new CacheException((\extension_loaded('igbinary') && \PHP_VERSION_ID >= 70400) ? 'Please upgrade the "igbinary" PHP extension to v3.1.6 or higher.' : 'The "igbinary" PHP extension is not loaded.');
+ }
+ $this->useIgbinarySerialize = $useIgbinarySerialize;
+ $this->throwOnSerializationFailure = $throwOnSerializationFailure;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function marshall(array $values, ?array &$failed): array
+ {
+ $serialized = $failed = [];
+ foreach ($values as $id => $value) {
+ try {
+ if ($this->useIgbinarySerialize) {
+ $serialized[$id] = igbinary_serialize($value);
+ } else {
+ $serialized[$id] = serialize($value);
+ }
+ } catch (\Exception $e) {
+ if ($this->throwOnSerializationFailure) {
+ throw new \ValueError($e->getMessage(), 0, $e);
+ }
+ $failed[] = $id;
+ }
+ }
+ return $serialized;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function unmarshall(string $value)
+ {
+ if ('b:0;' === $value) {
+ return \false;
+ }
+ if ('N;' === $value) {
+ return null;
+ }
+ static $igbinaryNull;
+ if ($value === ($igbinaryNull ?? $igbinaryNull = \extension_loaded('igbinary') ? igbinary_serialize(null) : \false)) {
+ return null;
+ }
+ $unserializeCallbackHandler = ini_set('unserialize_callback_func', __CLASS__ . '::handleUnserializeCallback');
+ try {
+ if (':' === ($value[1] ?? ':')) {
+ if (\false !== $value = unserialize($value)) {
+ return $value;
+ }
+ } elseif (\false === $igbinaryNull) {
+ throw new \RuntimeException('Failed to unserialize values, did you forget to install the "igbinary" extension?');
+ } elseif (null !== $value = igbinary_unserialize($value)) {
+ return $value;
+ }
+ throw new \DomainException(error_get_last() ? error_get_last()['message'] : 'Failed to unserialize values.');
+ } catch (\Error $e) {
+ throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine());
+ } finally {
+ ini_set('unserialize_callback_func', $unserializeCallbackHandler);
+ }
+ }
+ /**
+ * @internal
+ */
+ public static function handleUnserializeCallback(string $class)
+ {
+ throw new \DomainException('Class not found: ' . $class);
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Marshaller/DeflateMarshaller.php b/src/modules/common/third-party/vendor/symfony/cache/Marshaller/DeflateMarshaller.php
new file mode 100644
index 0000000000..41a298ed27
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Marshaller/DeflateMarshaller.php
@@ -0,0 +1,46 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Marshaller;
+
+use Wordlift\Modules\Common\Symfony\Component\Cache\Exception\CacheException;
+/**
+ * Compresses values using gzdeflate().
+ *
+ * @author Nicolas Grekas
+ */
+class DeflateMarshaller implements MarshallerInterface
+{
+ private $marshaller;
+ public function __construct(MarshallerInterface $marshaller)
+ {
+ if (!\function_exists('gzdeflate') && !\function_exists('Wordlift\Modules\Common\gzdeflate')) {
+ throw new CacheException('The "zlib" PHP extension is not loaded.');
+ }
+ $this->marshaller = $marshaller;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function marshall(array $values, ?array &$failed): array
+ {
+ return array_map('gzdeflate', $this->marshaller->marshall($values, $failed));
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function unmarshall(string $value)
+ {
+ if (\false !== $inflatedValue = @gzinflate($value)) {
+ $value = $inflatedValue;
+ }
+ return $this->marshaller->unmarshall($value);
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Marshaller/MarshallerInterface.php b/src/modules/common/third-party/vendor/symfony/cache/Marshaller/MarshallerInterface.php
new file mode 100644
index 0000000000..96634205d7
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Marshaller/MarshallerInterface.php
@@ -0,0 +1,38 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Marshaller;
+
+/**
+ * Serializes/unserializes PHP values.
+ *
+ * Implementations of this interface MUST deal with errors carefully. They MUST
+ * also deal with forward and backward compatibility at the storage format level.
+ *
+ * @author Nicolas Grekas
+ */
+interface MarshallerInterface
+{
+ /**
+ * Serializes a list of values.
+ *
+ * When serialization fails for a specific value, no exception should be
+ * thrown. Instead, its key should be listed in $failed.
+ */
+ public function marshall(array $values, ?array &$failed): array;
+ /**
+ * Unserializes a single value and throws an exception if anything goes wrong.
+ *
+ * @return mixed
+ *
+ * @throws \Exception Whenever unserialization fails
+ */
+ public function unmarshall(string $value);
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Marshaller/SodiumMarshaller.php b/src/modules/common/third-party/vendor/symfony/cache/Marshaller/SodiumMarshaller.php
new file mode 100644
index 0000000000..779e3f53da
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Marshaller/SodiumMarshaller.php
@@ -0,0 +1,69 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Marshaller;
+
+use Wordlift\Modules\Common\Symfony\Component\Cache\Exception\CacheException;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Exception\InvalidArgumentException;
+/**
+ * Encrypt/decrypt values using Libsodium.
+ *
+ * @author Ahmed TAILOULOUTE
+ */
+class TagAwareMarshaller implements MarshallerInterface
+{
+ private $marshaller;
+ public function __construct(?MarshallerInterface $marshaller = null)
+ {
+ $this->marshaller = $marshaller ?? new DefaultMarshaller();
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function marshall(array $values, ?array &$failed): array
+ {
+ $failed = $notSerialized = $serialized = [];
+ foreach ($values as $id => $value) {
+ if (\is_array($value) && \is_array($value['tags'] ?? null) && \array_key_exists('value', $value) && \count($value) === 2 + (\is_string($value['meta'] ?? null) && 8 === \strlen($value['meta']))) {
+ // if the value is an array with keys "tags", "value" and "meta", use a compact serialization format
+ // magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F allow detecting this format quickly in unmarshall()
+ $v = $this->marshaller->marshall($value, $f);
+ if ($f) {
+ $f = [];
+ $failed[] = $id;
+ } else {
+ if ([] === $value['tags']) {
+ $v['tags'] = '';
+ }
+ $serialized[$id] = "\x9d" . ($value['meta'] ?? "\x00\x00\x00\x00\x00\x00\x00\x00") . pack('N', \strlen($v['tags'])) . $v['tags'] . $v['value'];
+ $serialized[$id][9] = "_";
+ }
+ } else {
+ // other arbitrary values are serialized using the decorated marshaller below
+ $notSerialized[$id] = $value;
+ }
+ }
+ if ($notSerialized) {
+ $serialized += $this->marshaller->marshall($notSerialized, $f);
+ $failed = array_merge($failed, $f);
+ }
+ return $serialized;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function unmarshall(string $value)
+ {
+ // detect the compact format used in marshall() using magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F
+ if (13 >= \strlen($value) || "\x9d" !== $value[0] || "\x00" !== $value[5] || "_" !== $value[9]) {
+ return $this->marshaller->unmarshall($value);
+ }
+ // data consists of value, tags and metadata which we need to unpack
+ $meta = substr($value, 1, 12);
+ $meta[8] = "\x00";
+ $tagLen = unpack('Nlen', $meta, 8)['len'];
+ $meta = substr($meta, 0, 8);
+ return ['value' => $this->marshaller->unmarshall(substr($value, 13 + $tagLen)), 'tags' => $tagLen ? $this->marshaller->unmarshall(substr($value, 13, $tagLen)) : [], 'meta' => ("\x00\x00\x00\x00\x00\x00\x00\x00" === $meta) ? null : $meta];
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Messenger/EarlyExpirationDispatcher.php b/src/modules/common/third-party/vendor/symfony/cache/Messenger/EarlyExpirationDispatcher.php
new file mode 100644
index 0000000000..2f841d5fcf
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Messenger/EarlyExpirationDispatcher.php
@@ -0,0 +1,52 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Messenger;
+
+use Wordlift\Modules\Common\Psr\Log\LoggerInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Adapter\AdapterInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\CacheItem;
+use Wordlift\Modules\Common\Symfony\Component\DependencyInjection\ReverseContainer;
+use Wordlift\Modules\Common\Symfony\Component\Messenger\MessageBusInterface;
+use Wordlift\Modules\Common\Symfony\Component\Messenger\Stamp\HandledStamp;
+/**
+ * Sends the computation of cached values to a message bus.
+ */
+class EarlyExpirationDispatcher
+{
+ private $bus;
+ private $reverseContainer;
+ private $callbackWrapper;
+ public function __construct(MessageBusInterface $bus, ReverseContainer $reverseContainer, ?callable $callbackWrapper = null)
+ {
+ $this->bus = $bus;
+ $this->reverseContainer = $reverseContainer;
+ $this->callbackWrapper = $callbackWrapper;
+ }
+ public function __invoke(callable $callback, CacheItem $item, bool &$save, AdapterInterface $pool, \Closure $setMetadata, ?LoggerInterface $logger = null)
+ {
+ if (!$item->isHit() || null === $message = EarlyExpirationMessage::create($this->reverseContainer, $callback, $item, $pool)) {
+ // The item is stale or the callback cannot be reversed: we must compute the value now
+ $logger && $logger->info('Computing item "{key}" online: ' . ($item->isHit() ? 'callback cannot be reversed' : 'item is stale'), ['key' => $item->getKey()]);
+ return (null !== $this->callbackWrapper) ? ($this->callbackWrapper)($callback, $item, $save, $pool, $setMetadata, $logger) : $callback($item, $save);
+ }
+ $envelope = $this->bus->dispatch($message);
+ if ($logger) {
+ if ($envelope->last(HandledStamp::class)) {
+ $logger->info('Item "{key}" was computed online', ['key' => $item->getKey()]);
+ } else {
+ $logger->info('Item "{key}" sent for recomputation', ['key' => $item->getKey()]);
+ }
+ }
+ // The item's value is not stale, no need to write it to the backend
+ $save = \false;
+ return $message->getItem()->get() ?? $item->get();
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Messenger/EarlyExpirationHandler.php b/src/modules/common/third-party/vendor/symfony/cache/Messenger/EarlyExpirationHandler.php
new file mode 100644
index 0000000000..d147c40532
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Messenger/EarlyExpirationHandler.php
@@ -0,0 +1,64 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Messenger;
+
+use Wordlift\Modules\Common\Symfony\Component\Cache\CacheItem;
+use Wordlift\Modules\Common\Symfony\Component\DependencyInjection\ReverseContainer;
+use Wordlift\Modules\Common\Symfony\Component\Messenger\Handler\MessageHandlerInterface;
+/**
+ * Computes cached values sent to a message bus.
+ */
+class EarlyExpirationHandler implements MessageHandlerInterface
+{
+ private $reverseContainer;
+ private $processedNonces = [];
+ public function __construct(ReverseContainer $reverseContainer)
+ {
+ $this->reverseContainer = $reverseContainer;
+ }
+ public function __invoke(EarlyExpirationMessage $message)
+ {
+ $item = $message->getItem();
+ $metadata = $item->getMetadata();
+ $expiry = $metadata[CacheItem::METADATA_EXPIRY] ?? 0;
+ $ctime = $metadata[CacheItem::METADATA_CTIME] ?? 0;
+ if ($expiry && $ctime) {
+ // skip duplicate or expired messages
+ $processingNonce = [$expiry, $ctime];
+ $pool = $message->getPool();
+ $key = $item->getKey();
+ if (($this->processedNonces[$pool][$key] ?? null) === $processingNonce) {
+ return;
+ }
+ if (microtime(\true) >= $expiry) {
+ return;
+ }
+ $this->processedNonces[$pool] = [$key => $processingNonce] + ($this->processedNonces[$pool] ?? []);
+ if (\count($this->processedNonces[$pool]) > 100) {
+ array_pop($this->processedNonces[$pool]);
+ }
+ }
+ static $setMetadata;
+ $setMetadata ?? $setMetadata = \Closure::bind(function (CacheItem $item, float $startTime) {
+ if ($item->expiry > $endTime = microtime(\true)) {
+ $item->newMetadata[CacheItem::METADATA_EXPIRY] = $item->expiry;
+ $item->newMetadata[CacheItem::METADATA_CTIME] = (int) ceil(1000 * ($endTime - $startTime));
+ }
+ }, null, CacheItem::class);
+ $startTime = microtime(\true);
+ $pool = $message->findPool($this->reverseContainer);
+ $callback = $message->findCallback($this->reverseContainer);
+ $save = \true;
+ $value = $callback($item, $save);
+ $setMetadata($item, $startTime);
+ $pool->save($item->set($value));
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Messenger/EarlyExpirationMessage.php b/src/modules/common/third-party/vendor/symfony/cache/Messenger/EarlyExpirationMessage.php
new file mode 100644
index 0000000000..6d80042601
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Messenger/EarlyExpirationMessage.php
@@ -0,0 +1,82 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Messenger;
+
+use Wordlift\Modules\Common\Symfony\Component\Cache\Adapter\AdapterInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\CacheItem;
+use Wordlift\Modules\Common\Symfony\Component\DependencyInjection\ReverseContainer;
+/**
+ * Conveys a cached value that needs to be computed.
+ */
+final class EarlyExpirationMessage
+{
+ private $item;
+ private $pool;
+ private $callback;
+ public static function create(ReverseContainer $reverseContainer, callable $callback, CacheItem $item, AdapterInterface $pool): ?self
+ {
+ try {
+ $item = clone $item;
+ $item->set(null);
+ } catch (\Exception $e) {
+ return null;
+ }
+ $pool = $reverseContainer->getId($pool);
+ if (\is_object($callback)) {
+ if (null === $id = $reverseContainer->getId($callback)) {
+ return null;
+ }
+ $callback = '@' . $id;
+ } elseif (!\is_array($callback)) {
+ $callback = (string) $callback;
+ } elseif (!\is_object($callback[0])) {
+ $callback = [(string) $callback[0], (string) $callback[1]];
+ } else {
+ if (null === $id = $reverseContainer->getId($callback[0])) {
+ return null;
+ }
+ $callback = ['@' . $id, (string) $callback[1]];
+ }
+ return new self($item, $pool, $callback);
+ }
+ public function getItem(): CacheItem
+ {
+ return $this->item;
+ }
+ public function getPool(): string
+ {
+ return $this->pool;
+ }
+ public function getCallback()
+ {
+ return $this->callback;
+ }
+ public function findPool(ReverseContainer $reverseContainer): AdapterInterface
+ {
+ return $reverseContainer->getService($this->pool);
+ }
+ public function findCallback(ReverseContainer $reverseContainer): callable
+ {
+ if (\is_string($callback = $this->callback)) {
+ return ('@' === $callback[0]) ? $reverseContainer->getService(substr($callback, 1)) : $callback;
+ }
+ if ('@' === $callback[0][0]) {
+ $callback[0] = $reverseContainer->getService(substr($callback[0], 1));
+ }
+ return $callback;
+ }
+ private function __construct(CacheItem $item, string $pool, $callback)
+ {
+ $this->item = $item;
+ $this->pool = $pool;
+ $this->callback = $callback;
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/PruneableInterface.php b/src/modules/common/third-party/vendor/symfony/cache/PruneableInterface.php
new file mode 100644
index 0000000000..84e48b56c1
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/PruneableInterface.php
@@ -0,0 +1,22 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache;
+
+/**
+ * Interface extends psr-6 and psr-16 caches to allow for pruning (deletion) of all expired cache items.
+ */
+interface PruneableInterface
+{
+ /**
+ * @return bool
+ */
+ public function prune();
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Psr16Cache.php b/src/modules/common/third-party/vendor/symfony/cache/Psr16Cache.php
new file mode 100644
index 0000000000..174e8ae397
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Psr16Cache.php
@@ -0,0 +1,255 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache;
+
+use Wordlift\Modules\Common\Psr\Cache\CacheException as Psr6CacheException;
+use Wordlift\Modules\Common\Psr\Cache\CacheItemPoolInterface;
+use Wordlift\Modules\Common\Psr\SimpleCache\CacheException as SimpleCacheException;
+use Wordlift\Modules\Common\Psr\SimpleCache\CacheInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Adapter\AdapterInterface;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Exception\InvalidArgumentException;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Traits\ProxyTrait;
+if (null !== (new \ReflectionMethod(CacheInterface::class, 'get'))->getReturnType()) {
+ throw new \LogicException('psr/simple-cache 3.0+ is not compatible with this version of symfony/cache. Please upgrade symfony/cache to 6.0+ or downgrade psr/simple-cache to 1.x or 2.x.');
+}
+/**
+ * Turns a PSR-6 cache into a PSR-16 one.
+ *
+ * @author Nicolas Grekas
+ */
+class Psr16Cache implements CacheInterface, PruneableInterface, ResettableInterface
+{
+ use ProxyTrait;
+ private const METADATA_EXPIRY_OFFSET = 1527506807;
+ private $createCacheItem;
+ private $cacheItemPrototype;
+ public function __construct(CacheItemPoolInterface $pool)
+ {
+ $this->pool = $pool;
+ if (!$pool instanceof AdapterInterface) {
+ return;
+ }
+ $cacheItemPrototype =& $this->cacheItemPrototype;
+ $createCacheItem = \Closure::bind(static function ($key, $value, $allowInt = \false) use (&$cacheItemPrototype) {
+ $item = clone $cacheItemPrototype;
+ $item->poolHash = $item->innerItem = null;
+ if ($allowInt && \is_int($key)) {
+ $item->key = (string) $key;
+ } else {
+ \assert('' !== CacheItem::validateKey($key));
+ $item->key = $key;
+ }
+ $item->value = $value;
+ $item->isHit = \false;
+ return $item;
+ }, null, CacheItem::class);
+ $this->createCacheItem = function ($key, $value, $allowInt = \false) use ($createCacheItem) {
+ if (null === $this->cacheItemPrototype) {
+ $this->get(($allowInt && \is_int($key)) ? (string) $key : $key);
+ }
+ $this->createCacheItem = $createCacheItem;
+ return $createCacheItem($key, null, $allowInt)->set($value);
+ };
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return mixed
+ */
+ public function get($key, $default = null)
+ {
+ try {
+ $item = $this->pool->getItem($key);
+ } catch (SimpleCacheException $e) {
+ throw $e;
+ } catch (Psr6CacheException $e) {
+ throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
+ }
+ if (null === $this->cacheItemPrototype) {
+ $this->cacheItemPrototype = clone $item;
+ $this->cacheItemPrototype->set(null);
+ }
+ return $item->isHit() ? $item->get() : $default;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function set($key, $value, $ttl = null)
+ {
+ try {
+ if (null !== $f = $this->createCacheItem) {
+ $item = $f($key, $value);
+ } else {
+ $item = $this->pool->getItem($key)->set($value);
+ }
+ } catch (SimpleCacheException $e) {
+ throw $e;
+ } catch (Psr6CacheException $e) {
+ throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
+ }
+ if (null !== $ttl) {
+ $item->expiresAfter($ttl);
+ }
+ return $this->pool->save($item);
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function delete($key)
+ {
+ try {
+ return $this->pool->deleteItem($key);
+ } catch (SimpleCacheException $e) {
+ throw $e;
+ } catch (Psr6CacheException $e) {
+ throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function clear()
+ {
+ return $this->pool->clear();
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return iterable
+ */
+ public function getMultiple($keys, $default = null)
+ {
+ if ($keys instanceof \Traversable) {
+ $keys = iterator_to_array($keys, \false);
+ } elseif (!\is_array($keys)) {
+ throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', get_debug_type($keys)));
+ }
+ try {
+ $items = $this->pool->getItems($keys);
+ } catch (SimpleCacheException $e) {
+ throw $e;
+ } catch (Psr6CacheException $e) {
+ throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
+ }
+ $values = [];
+ if (!$this->pool instanceof AdapterInterface) {
+ foreach ($items as $key => $item) {
+ $values[$key] = $item->isHit() ? $item->get() : $default;
+ }
+ return $values;
+ }
+ foreach ($items as $key => $item) {
+ if (!$item->isHit()) {
+ $values[$key] = $default;
+ continue;
+ }
+ $values[$key] = $item->get();
+ if (!$metadata = $item->getMetadata()) {
+ continue;
+ }
+ unset($metadata[CacheItem::METADATA_TAGS]);
+ if ($metadata) {
+ $values[$key] = ["\x9d" . pack('VN', (int) (0.1 + $metadata[CacheItem::METADATA_EXPIRY] - self::METADATA_EXPIRY_OFFSET), $metadata[CacheItem::METADATA_CTIME]) . "_" => $values[$key]];
+ }
+ }
+ return $values;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function setMultiple($values, $ttl = null)
+ {
+ $valuesIsArray = \is_array($values);
+ if (!$valuesIsArray && !$values instanceof \Traversable) {
+ throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given.', get_debug_type($values)));
+ }
+ $items = [];
+ try {
+ if (null !== $f = $this->createCacheItem) {
+ $valuesIsArray = \false;
+ foreach ($values as $key => $value) {
+ $items[$key] = $f($key, $value, \true);
+ }
+ } elseif ($valuesIsArray) {
+ $items = [];
+ foreach ($values as $key => $value) {
+ $items[] = (string) $key;
+ }
+ $items = $this->pool->getItems($items);
+ } else {
+ foreach ($values as $key => $value) {
+ if (\is_int($key)) {
+ $key = (string) $key;
+ }
+ $items[$key] = $this->pool->getItem($key)->set($value);
+ }
+ }
+ } catch (SimpleCacheException $e) {
+ throw $e;
+ } catch (Psr6CacheException $e) {
+ throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
+ }
+ $ok = \true;
+ foreach ($items as $key => $item) {
+ if ($valuesIsArray) {
+ $item->set($values[$key]);
+ }
+ if (null !== $ttl) {
+ $item->expiresAfter($ttl);
+ }
+ $ok = $this->pool->saveDeferred($item) && $ok;
+ }
+ return $this->pool->commit() && $ok;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function deleteMultiple($keys)
+ {
+ if ($keys instanceof \Traversable) {
+ $keys = iterator_to_array($keys, \false);
+ } elseif (!\is_array($keys)) {
+ throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', get_debug_type($keys)));
+ }
+ try {
+ return $this->pool->deleteItems($keys);
+ } catch (SimpleCacheException $e) {
+ throw $e;
+ } catch (Psr6CacheException $e) {
+ throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function has($key)
+ {
+ try {
+ return $this->pool->hasItem($key);
+ } catch (SimpleCacheException $e) {
+ throw $e;
+ } catch (Psr6CacheException $e) {
+ throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/ResettableInterface.php b/src/modules/common/third-party/vendor/symfony/cache/ResettableInterface.php
new file mode 100644
index 0000000000..f7103f51cf
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/ResettableInterface.php
@@ -0,0 +1,19 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache;
+
+use Wordlift\Modules\Common\Symfony\Contracts\Service\ResetInterface;
+/**
+ * Resets a pool's local state.
+ */
+interface ResettableInterface extends ResetInterface
+{
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Traits/AbstractAdapterTrait.php b/src/modules/common/third-party/vendor/symfony/cache/Traits/AbstractAdapterTrait.php
new file mode 100644
index 0000000000..633a23e837
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Traits/AbstractAdapterTrait.php
@@ -0,0 +1,372 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Traits;
+
+use Wordlift\Modules\Common\Psr\Cache\CacheItemInterface;
+use Wordlift\Modules\Common\Psr\Log\LoggerAwareTrait;
+use Wordlift\Modules\Common\Symfony\Component\Cache\CacheItem;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Exception\InvalidArgumentException;
+/**
+ * @author Nicolas Grekas
+ *
+ * @internal
+ */
+trait AbstractAdapterTrait
+{
+ use LoggerAwareTrait;
+ /**
+ * @var \Closure needs to be set by class, signature is function(string
+ *
+ * @internal
+ */
+trait ContractsTrait
+{
+ use CacheTrait {
+ doGet as private contractsGet;
+ }
+ private $callbackWrapper;
+ private $computing = [];
+ /**
+ * Wraps the callback passed to ->get() in a callable.
+ *
+ * @return callable the previous callback wrapper
+ */
+ public function setCallbackWrapper(?callable $callbackWrapper): callable
+ {
+ if (!isset($this->callbackWrapper)) {
+ $this->callbackWrapper = \Closure::fromCallable([LockRegistry::class, 'compute']);
+ if (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], \true)) {
+ $this->setCallbackWrapper(null);
+ }
+ }
+ $previousWrapper = $this->callbackWrapper;
+ $this->callbackWrapper = $callbackWrapper ?? static function (callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata, ?LoggerInterface $logger) {
+ return $callback($item, $save);
+ };
+ return $previousWrapper;
+ }
+ private function doGet(AdapterInterface $pool, string $key, callable $callback, ?float $beta, ?array &$metadata = null)
+ {
+ if (0 > $beta = $beta ?? 1.0) {
+ throw new InvalidArgumentException(sprintf('Argument "$beta" provided to "%s::get()" must be a positive number, %f given.', static::class, $beta));
+ }
+ static $setMetadata;
+ $setMetadata ?? $setMetadata = \Closure::bind(static function (CacheItem $item, float $startTime, ?array &$metadata) {
+ if ($item->expiry > $endTime = microtime(\true)) {
+ $item->newMetadata[CacheItem::METADATA_EXPIRY] = $metadata[CacheItem::METADATA_EXPIRY] = $item->expiry;
+ $item->newMetadata[CacheItem::METADATA_CTIME] = $metadata[CacheItem::METADATA_CTIME] = (int) ceil(1000 * ($endTime - $startTime));
+ } else {
+ unset($metadata[CacheItem::METADATA_EXPIRY], $metadata[CacheItem::METADATA_CTIME]);
+ }
+ }, null, CacheItem::class);
+ return $this->contractsGet($pool, $key, function (CacheItem $item, bool &$save) use ($pool, $callback, $setMetadata, &$metadata, $key) {
+ // don't wrap nor save recursive calls
+ if (isset($this->computing[$key])) {
+ $value = $callback($item, $save);
+ $save = \false;
+ return $value;
+ }
+ $this->computing[$key] = $key;
+ $startTime = microtime(\true);
+ if (!isset($this->callbackWrapper)) {
+ $this->setCallbackWrapper($this->setCallbackWrapper(null));
+ }
+ try {
+ $value = ($this->callbackWrapper)($callback, $item, $save, $pool, function (CacheItem $item) use ($setMetadata, $startTime, &$metadata) {
+ $setMetadata($item, $startTime, $metadata);
+ }, $this->logger ?? null);
+ $setMetadata($item, $startTime, $metadata);
+ return $value;
+ } finally {
+ unset($this->computing[$key]);
+ }
+ }, $beta, $metadata, $this->logger ?? null);
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Traits/FilesystemCommonTrait.php b/src/modules/common/third-party/vendor/symfony/cache/Traits/FilesystemCommonTrait.php
new file mode 100644
index 0000000000..d5ab61cd25
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Traits/FilesystemCommonTrait.php
@@ -0,0 +1,180 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Traits;
+
+use Wordlift\Modules\Common\Symfony\Component\Cache\Exception\InvalidArgumentException;
+/**
+ * @author Nicolas Grekas
+ *
+ * @internal
+ */
+trait FilesystemCommonTrait
+{
+ private $directory;
+ private $tmp;
+ private function init(string $namespace, ?string $directory)
+ {
+ if (!isset($directory[0])) {
+ $directory = sys_get_temp_dir() . \DIRECTORY_SEPARATOR . 'symfony-cache';
+ } else {
+ $directory = realpath($directory) ?: $directory;
+ }
+ if (isset($namespace[0])) {
+ if (preg_match('#[^-+_.A-Za-z0-9]#', $namespace, $match)) {
+ throw new InvalidArgumentException(sprintf('Namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0]));
+ }
+ $directory .= \DIRECTORY_SEPARATOR . $namespace;
+ } else {
+ $directory .= \DIRECTORY_SEPARATOR . '@';
+ }
+ if (!is_dir($directory)) {
+ @mkdir($directory, 0777, \true);
+ }
+ $directory .= \DIRECTORY_SEPARATOR;
+ // On Windows the whole path is limited to 258 chars
+ if ('\\' === \DIRECTORY_SEPARATOR && \strlen($directory) > 234) {
+ throw new InvalidArgumentException(sprintf('Cache directory too long (%s).', $directory));
+ }
+ $this->directory = $directory;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doClear(string $namespace)
+ {
+ $ok = \true;
+ foreach ($this->scanHashDir($this->directory) as $file) {
+ if ('' !== $namespace && !str_starts_with($this->getFileKey($file), $namespace)) {
+ continue;
+ }
+ $ok = ($this->doUnlink($file) || !file_exists($file)) && $ok;
+ }
+ return $ok;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function doDelete(array $ids)
+ {
+ $ok = \true;
+ foreach ($ids as $id) {
+ $file = $this->getFile($id);
+ $ok = (!is_file($file) || $this->doUnlink($file) || !file_exists($file)) && $ok;
+ }
+ return $ok;
+ }
+ protected function doUnlink(string $file)
+ {
+ return @unlink($file);
+ }
+ private function write(string $file, string $data, ?int $expiresAt = null)
+ {
+ $unlink = \false;
+ set_error_handler(__CLASS__ . '::throwError');
+ try {
+ if (null === $this->tmp) {
+ $this->tmp = $this->directory . bin2hex(random_bytes(6));
+ }
+ try {
+ $h = fopen($this->tmp, 'x');
+ } catch (\ErrorException $e) {
+ if (!str_contains($e->getMessage(), 'File exists')) {
+ throw $e;
+ }
+ $this->tmp = $this->directory . bin2hex(random_bytes(6));
+ $h = fopen($this->tmp, 'x');
+ }
+ fwrite($h, $data);
+ fclose($h);
+ $unlink = \true;
+ if (null !== $expiresAt) {
+ touch($this->tmp, $expiresAt ?: (time() + 31556952));
+ // 1 year in seconds
+ }
+ if ('\\' === \DIRECTORY_SEPARATOR) {
+ $success = copy($this->tmp, $file);
+ $unlink = \true;
+ } else {
+ $success = rename($this->tmp, $file);
+ $unlink = !$success;
+ }
+ return $success;
+ } finally {
+ restore_error_handler();
+ if ($unlink) {
+ @unlink($this->tmp);
+ }
+ }
+ }
+ private function getFile(string $id, bool $mkdir = \false, ?string $directory = null)
+ {
+ // Use MD5 to favor speed over security, which is not an issue here
+ $hash = str_replace('/', '-', base64_encode(hash('md5', static::class . $id, \true)));
+ $dir = ($directory ?? $this->directory) . strtoupper($hash[0] . \DIRECTORY_SEPARATOR . $hash[1] . \DIRECTORY_SEPARATOR);
+ if ($mkdir && !is_dir($dir)) {
+ @mkdir($dir, 0777, \true);
+ }
+ return $dir . substr($hash, 2, 20);
+ }
+ private function getFileKey(string $file): string
+ {
+ return '';
+ }
+ private function scanHashDir(string $directory): \Generator
+ {
+ if (!is_dir($directory)) {
+ return;
+ }
+ $chars = '+-ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ for ($i = 0; $i < 38; ++$i) {
+ if (!is_dir($directory . $chars[$i])) {
+ continue;
+ }
+ for ($j = 0; $j < 38; ++$j) {
+ if (!is_dir($dir = $directory . $chars[$i] . \DIRECTORY_SEPARATOR . $chars[$j])) {
+ continue;
+ }
+ foreach ((@scandir($dir, \SCANDIR_SORT_NONE)) ?: [] as $file) {
+ if ('.' !== $file && '..' !== $file) {
+ yield $dir . \DIRECTORY_SEPARATOR . $file;
+ }
+ }
+ }
+ }
+ }
+ /**
+ * @internal
+ */
+ public static function throwError(int $type, string $message, string $file, int $line)
+ {
+ throw new \ErrorException($message, 0, $type, $file, $line);
+ }
+ /**
+ * @return array
+ */
+ public function __sleep()
+ {
+ throw new \BadMethodCallException('Cannot serialize ' . __CLASS__);
+ }
+ public function __wakeup()
+ {
+ throw new \BadMethodCallException('Cannot unserialize ' . __CLASS__);
+ }
+ public function __destruct()
+ {
+ if (method_exists(parent::class, '__destruct')) {
+ parent::__destruct();
+ }
+ if (null !== $this->tmp && is_file($this->tmp)) {
+ unlink($this->tmp);
+ }
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Traits/FilesystemTrait.php b/src/modules/common/third-party/vendor/symfony/cache/Traits/FilesystemTrait.php
new file mode 100644
index 0000000000..1add54dabc
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Traits/FilesystemTrait.php
@@ -0,0 +1,106 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Traits;
+
+use Wordlift\Modules\Common\Symfony\Component\Cache\Exception\CacheException;
+/**
+ * @author Nicolas Grekas
+ * @author Rob Frawley 2nd
+ *
+ * @internal
+ */
+trait ProxyTrait
+{
+ private $pool;
+ /**
+ * {@inheritdoc}
+ */
+ public function prune()
+ {
+ return $this->pool instanceof PruneableInterface && $this->pool->prune();
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function reset()
+ {
+ if ($this->pool instanceof ResetInterface) {
+ $this->pool->reset();
+ }
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Traits/RedisClusterNodeProxy.php b/src/modules/common/third-party/vendor/symfony/cache/Traits/RedisClusterNodeProxy.php
new file mode 100644
index 0000000000..f0f15b108a
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Traits/RedisClusterNodeProxy.php
@@ -0,0 +1,48 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Traits;
+
+/**
+ * This file acts as a wrapper to the \RedisCluster implementation so it can accept the same type of calls as
+ * individual \Redis objects.
+ *
+ * Calls are made to individual nodes via: RedisCluster->{method}($host, ...args)'
+ * according to https://github.com/phpredis/phpredis/blob/develop/cluster.markdown#directed-node-commands
+ *
+ * @author Jack Thomas
+ *
+ * @internal
+ */
+class RedisProxy
+{
+ private $redis;
+ private $initializer;
+ private $ready = \false;
+ public function __construct(\Redis $redis, \Closure $initializer)
+ {
+ $this->redis = $redis;
+ $this->initializer = $initializer;
+ }
+ public function __call(string $method, array $args)
+ {
+ $this->ready ?: $this->ready = $this->initializer->__invoke($this->redis);
+ return $this->redis->{$method}(...$args);
+ }
+ public function hscan($strKey, &$iIterator, $strPattern = null, $iCount = null)
+ {
+ $this->ready ?: $this->ready = $this->initializer->__invoke($this->redis);
+ return $this->redis->hscan($strKey, $iIterator, $strPattern, $iCount);
+ }
+ public function scan(&$iIterator, $strPattern = null, $iCount = null)
+ {
+ $this->ready ?: $this->ready = $this->initializer->__invoke($this->redis);
+ return $this->redis->scan($iIterator, $strPattern, $iCount);
+ }
+ public function sscan($strKey, &$iIterator, $strPattern = null, $iCount = null)
+ {
+ $this->ready ?: $this->ready = $this->initializer->__invoke($this->redis);
+ return $this->redis->sscan($strKey, $iIterator, $strPattern, $iCount);
+ }
+ public function zscan($strKey, &$iIterator, $strPattern = null, $iCount = null)
+ {
+ $this->ready ?: $this->ready = $this->initializer->__invoke($this->redis);
+ return $this->redis->zscan($strKey, $iIterator, $strPattern, $iCount);
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/Traits/RedisTrait.php b/src/modules/common/third-party/vendor/symfony/cache/Traits/RedisTrait.php
new file mode 100644
index 0000000000..7c6a96e454
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/Traits/RedisTrait.php
@@ -0,0 +1,553 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Cache\Traits;
+
+use Wordlift\Modules\Common\Predis\Command\Redis\UNLINK;
+use Wordlift\Modules\Common\Predis\Connection\Aggregate\ClusterInterface;
+use Wordlift\Modules\Common\Predis\Connection\Aggregate\RedisCluster;
+use Wordlift\Modules\Common\Predis\Connection\Aggregate\ReplicationInterface;
+use Wordlift\Modules\Common\Predis\Connection\Cluster\ClusterInterface as Predis2ClusterInterface;
+use Wordlift\Modules\Common\Predis\Connection\Cluster\RedisCluster as Predis2RedisCluster;
+use Wordlift\Modules\Common\Predis\Response\ErrorInterface;
+use Wordlift\Modules\Common\Predis\Response\Status;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Exception\CacheException;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Exception\InvalidArgumentException;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Marshaller\DefaultMarshaller;
+use Wordlift\Modules\Common\Symfony\Component\Cache\Marshaller\MarshallerInterface;
+/**
+ * @author Aurimas Niekis
+ *
+ * @internal
+ */
+trait RedisTrait
+{
+ private static $defaultConnectionOptions = ['class' => null, 'persistent' => 0, 'persistent_id' => null, 'timeout' => 30, 'read_timeout' => 0, 'retry_interval' => 0, 'tcp_keepalive' => 0, 'lazy' => null, 'redis_cluster' => \false, 'redis_sentinel' => null, 'dbindex' => 0, 'failover' => 'none', 'ssl' => null];
+ private $redis;
+ private $marshaller;
+ /**
+ * @param \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|RedisProxy|RedisClusterProxy $redis
+ */
+ private function init($redis, string $namespace, int $defaultLifetime, ?MarshallerInterface $marshaller)
+ {
+ parent::__construct($namespace, $defaultLifetime);
+ if (preg_match('#[^-+_.A-Za-z0-9]#', $namespace, $match)) {
+ throw new InvalidArgumentException(sprintf('RedisAdapter namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0]));
+ }
+ if (!$redis instanceof \Redis && !$redis instanceof \RedisArray && !$redis instanceof \RedisCluster && !$redis instanceof \Wordlift\Modules\Common\Predis\ClientInterface && !$redis instanceof RedisProxy && !$redis instanceof RedisClusterProxy) {
+ throw new InvalidArgumentException(sprintf('"%s()" expects parameter 1 to be Redis, RedisArray, RedisCluster or Predis\ClientInterface, "%s" given.', __METHOD__, get_debug_type($redis)));
+ }
+ if ($redis instanceof \Wordlift\Modules\Common\Predis\ClientInterface && $redis->getOptions()->exceptions) {
+ $options = clone $redis->getOptions();
+ \Closure::bind(function () {
+ $this->options['exceptions'] = \false;
+ }, $options, $options)();
+ $redis = new $redis($redis->getConnection(), $options);
+ }
+ $this->redis = $redis;
+ $this->marshaller = $marshaller ?? new DefaultMarshaller();
+ }
+ /**
+ * Creates a Redis connection using a DSN configuration.
+ *
+ * Example DSN:
+ * - redis://localhost
+ * - redis://example.com:1234
+ * - redis://secret@example.com/13
+ * - redis:///var/run/redis.sock
+ * - redis://secret@/var/run/redis.sock/13
+ *
+ * @param array $options See self::$defaultConnectionOptions
+ *
+ * @return \Redis|\RedisArray|\RedisCluster|RedisClusterProxy|RedisProxy|\Predis\ClientInterface According to the "class" option
+ *
+ * @throws InvalidArgumentException when the DSN is invalid
+ */
+ public static function createConnection(string $dsn, array $options = [])
+ {
+ if (str_starts_with($dsn, 'redis:')) {
+ $scheme = 'redis';
+ } elseif (str_starts_with($dsn, 'rediss:')) {
+ $scheme = 'rediss';
+ } else {
+ throw new InvalidArgumentException('Invalid Redis DSN: it does not start with "redis[s]:".');
+ }
+ if (!\extension_loaded('redis') && !class_exists(\Wordlift\Modules\Common\Predis\Client::class)) {
+ throw new CacheException('Cannot find the "redis" extension nor the "predis/predis" package.');
+ }
+ $params = preg_replace_callback('#^' . $scheme . ':(//)?(?:(?:[^:@]*+:)?([^@]*+)@)?#', function ($m) use (&$auth) {
+ if (isset($m[2])) {
+ $auth = rawurldecode($m[2]);
+ if ('' === $auth) {
+ $auth = null;
+ }
+ }
+ return 'file:' . ($m[1] ?? '');
+ }, $dsn);
+ if (\false === $params = parse_url($params)) {
+ throw new InvalidArgumentException('Invalid Redis DSN.');
+ }
+ $query = $hosts = [];
+ $tls = 'rediss' === $scheme;
+ $tcpScheme = $tls ? 'tls' : 'tcp';
+ if (isset($params['query'])) {
+ parse_str($params['query'], $query);
+ if (isset($query['host'])) {
+ if (!\is_array($hosts = $query['host'])) {
+ throw new InvalidArgumentException('Invalid Redis DSN: query parameter "host" must be an array.');
+ }
+ foreach ($hosts as $host => $parameters) {
+ if (\is_string($parameters)) {
+ parse_str($parameters, $parameters);
+ }
+ if (\false === $i = strrpos($host, ':')) {
+ $hosts[$host] = ['scheme' => $tcpScheme, 'host' => $host, 'port' => 6379] + $parameters;
+ } elseif ($port = (int) substr($host, 1 + $i)) {
+ $hosts[$host] = ['scheme' => $tcpScheme, 'host' => substr($host, 0, $i), 'port' => $port] + $parameters;
+ } else {
+ $hosts[$host] = ['scheme' => 'unix', 'path' => substr($host, 0, $i)] + $parameters;
+ }
+ }
+ $hosts = array_values($hosts);
+ }
+ }
+ if (isset($params['host']) || isset($params['path'])) {
+ if (!isset($params['dbindex']) && isset($params['path'])) {
+ if (preg_match('#/(\d+)?$#', $params['path'], $m)) {
+ $params['dbindex'] = $m[1] ?? $query['dbindex'] ?? '0';
+ $params['path'] = substr($params['path'], 0, -\strlen($m[0]));
+ } elseif (isset($params['host'])) {
+ throw new InvalidArgumentException('Invalid Redis DSN: parameter "dbindex" must be a number.');
+ }
+ }
+ if (isset($params['host'])) {
+ array_unshift($hosts, ['scheme' => $tcpScheme, 'host' => $params['host'], 'port' => $params['port'] ?? 6379]);
+ } else {
+ array_unshift($hosts, ['scheme' => 'unix', 'path' => $params['path']]);
+ }
+ }
+ if (!$hosts) {
+ throw new InvalidArgumentException('Invalid Redis DSN: missing host.');
+ }
+ if (isset($params['dbindex'], $query['dbindex']) && $params['dbindex'] !== $query['dbindex']) {
+ throw new InvalidArgumentException('Invalid Redis DSN: path and query "dbindex" parameters mismatch.');
+ }
+ $params += $query + $options + self::$defaultConnectionOptions;
+ if (isset($params['redis_sentinel']) && !class_exists(\Wordlift\Modules\Common\Predis\Client::class) && !class_exists(\RedisSentinel::class)) {
+ throw new CacheException('Redis Sentinel support requires the "predis/predis" package or the "redis" extension v5.2 or higher.');
+ }
+ if (isset($params['lazy'])) {
+ $params['lazy'] = filter_var($params['lazy'], \FILTER_VALIDATE_BOOLEAN);
+ }
+ $params['redis_cluster'] = filter_var($params['redis_cluster'], \FILTER_VALIDATE_BOOLEAN);
+ if ($params['redis_cluster'] && isset($params['redis_sentinel'])) {
+ throw new InvalidArgumentException('Cannot use both "redis_cluster" and "redis_sentinel" at the same time.');
+ }
+ if (null === $params['class'] && \extension_loaded('redis')) {
+ $class = $params['redis_cluster'] ? \RedisCluster::class : ((1 < \count($hosts) && !isset($params['redis_sentinel'])) ? \RedisArray::class : \Redis::class);
+ } else {
+ $class = $params['class'] ?? \Wordlift\Modules\Common\Predis\Client::class;
+ if (isset($params['redis_sentinel']) && !is_a($class, \Wordlift\Modules\Common\Predis\Client::class, \true) && !class_exists(\RedisSentinel::class)) {
+ throw new CacheException(sprintf('Cannot use Redis Sentinel: class "%s" does not extend "Predis\Client" and ext-redis >= 5.2 not found.', $class));
+ }
+ }
+ if (is_a($class, \Redis::class, \true)) {
+ $connect = ($params['persistent'] || $params['persistent_id']) ? 'pconnect' : 'connect';
+ $redis = new $class();
+ $initializer = static function ($redis) use ($connect, $params, $auth, $hosts, $tls) {
+ $hostIndex = 0;
+ do {
+ $host = $hosts[$hostIndex]['host'] ?? $hosts[$hostIndex]['path'];
+ $port = $hosts[$hostIndex]['port'] ?? 0;
+ $passAuth = \defined('Redis::OPT_NULL_MULTIBULK_AS_NULL') && isset($params['auth']);
+ $address = \false;
+ if (isset($hosts[$hostIndex]['host']) && $tls) {
+ $host = 'tls://' . $host;
+ }
+ if (!isset($params['redis_sentinel'])) {
+ break;
+ }
+ if (version_compare(phpversion('redis'), '6.0.0', '>=')) {
+ $options = ['host' => $host, 'port' => $port, 'connectTimeout' => (float) $params['timeout'], 'persistent' => $params['persistent_id'], 'retryInterval' => (int) $params['retry_interval'], 'readTimeout' => (float) $params['read_timeout']];
+ if ($passAuth) {
+ $options['auth'] = $params['auth'];
+ }
+ $sentinel = new \RedisSentinel($options);
+ } else {
+ $extra = $passAuth ? [$params['auth']] : [];
+ $sentinel = new \RedisSentinel($host, $port, $params['timeout'], (string) $params['persistent_id'], $params['retry_interval'], $params['read_timeout'], ...$extra);
+ }
+ try {
+ if ($address = $sentinel->getMasterAddrByName($params['redis_sentinel'])) {
+ [$host, $port] = $address;
+ }
+ } catch (\RedisException $e) {
+ }
+ } while (++$hostIndex < \count($hosts) && !$address);
+ if (isset($params['redis_sentinel']) && !$address) {
+ throw new InvalidArgumentException(sprintf('Failed to retrieve master information from sentinel "%s".', $params['redis_sentinel']));
+ }
+ try {
+ $extra = ['stream' => $params['ssl'] ?? null];
+ $booleanStreamOptions = ['allow_self_signed', 'capture_peer_cert', 'capture_peer_cert_chain', 'disable_compression', 'SNI_enabled', 'verify_peer', 'verify_peer_name'];
+ foreach ($extra['stream'] ?? [] as $streamOption => $value) {
+ if (\in_array($streamOption, $booleanStreamOptions, \true) && \is_string($value)) {
+ $extra['stream'][$streamOption] = filter_var($value, \FILTER_VALIDATE_BOOL);
+ }
+ }
+ if (isset($params['auth'])) {
+ $extra['auth'] = $params['auth'];
+ }
+ @$redis->{$connect}($host, $port, $params['timeout'], (string) $params['persistent_id'], $params['retry_interval'], $params['read_timeout'], ...\defined('Redis::SCAN_PREFIX') ? [$extra] : []);
+ set_error_handler(function ($type, $msg) use (&$error) {
+ $error = $msg;
+ });
+ try {
+ $isConnected = $redis->isConnected();
+ } finally {
+ restore_error_handler();
+ }
+ if (!$isConnected) {
+ $error = preg_match('/^Redis::p?connect\(\): (.*)/', $error ?? $redis->getLastError() ?? '', $error) ? sprintf(' (%s)', $error[1]) : '';
+ throw new InvalidArgumentException('Redis connection failed: ' . $error . '.');
+ }
+ if (null !== $auth && !$redis->auth($auth) || ($params['dbindex'] || 'pconnect' === $connect && '0' !== \ini_get('redis.pconnect.pooling_enabled')) && !$redis->select($params['dbindex'])) {
+ $e = preg_replace('/^ERR /', '', $redis->getLastError());
+ throw new InvalidArgumentException('Redis connection failed: ' . $e . '.');
+ }
+ if (0 < $params['tcp_keepalive'] && \defined('Redis::OPT_TCP_KEEPALIVE')) {
+ $redis->setOption(\Redis::OPT_TCP_KEEPALIVE, $params['tcp_keepalive']);
+ }
+ } catch (\RedisException $e) {
+ throw new InvalidArgumentException('Redis connection failed: ' . $e->getMessage());
+ }
+ return \true;
+ };
+ if ($params['lazy']) {
+ $redis = new RedisProxy($redis, $initializer);
+ } else {
+ $initializer($redis);
+ }
+ } elseif (is_a($class, \RedisArray::class, \true)) {
+ foreach ($hosts as $i => $host) {
+ switch ($host['scheme']) {
+ case 'tcp':
+ $hosts[$i] = $host['host'] . ':' . $host['port'];
+ break;
+ case 'tls':
+ $hosts[$i] = 'tls://' . $host['host'] . ':' . $host['port'];
+ break;
+ default:
+ $hosts[$i] = $host['path'];
+ }
+ }
+ $params['lazy_connect'] = $params['lazy'] ?? \true;
+ $params['connect_timeout'] = $params['timeout'];
+ try {
+ $redis = new $class($hosts, $params);
+ } catch (\RedisClusterException $e) {
+ throw new InvalidArgumentException('Redis connection failed: ' . $e->getMessage());
+ }
+ if (0 < $params['tcp_keepalive'] && \defined('Redis::OPT_TCP_KEEPALIVE')) {
+ $redis->setOption(\Redis::OPT_TCP_KEEPALIVE, $params['tcp_keepalive']);
+ }
+ } elseif (is_a($class, \RedisCluster::class, \true)) {
+ $initializer = static function () use ($class, $params, $hosts) {
+ foreach ($hosts as $i => $host) {
+ switch ($host['scheme']) {
+ case 'tcp':
+ $hosts[$i] = $host['host'] . ':' . $host['port'];
+ break;
+ case 'tls':
+ $hosts[$i] = 'tls://' . $host['host'] . ':' . $host['port'];
+ break;
+ default:
+ $hosts[$i] = $host['path'];
+ }
+ }
+ try {
+ $redis = new $class(null, $hosts, $params['timeout'], $params['read_timeout'], (bool) $params['persistent'], $params['auth'] ?? '', ...\defined('Redis::SCAN_PREFIX') ? [$params['ssl'] ?? null] : []);
+ } catch (\RedisClusterException $e) {
+ throw new InvalidArgumentException('Redis connection failed: ' . $e->getMessage());
+ }
+ if (0 < $params['tcp_keepalive'] && \defined('Redis::OPT_TCP_KEEPALIVE')) {
+ $redis->setOption(\Redis::OPT_TCP_KEEPALIVE, $params['tcp_keepalive']);
+ }
+ switch ($params['failover']) {
+ case 'error':
+ $redis->setOption(\RedisCluster::OPT_SLAVE_FAILOVER, \RedisCluster::FAILOVER_ERROR);
+ break;
+ case 'distribute':
+ $redis->setOption(\RedisCluster::OPT_SLAVE_FAILOVER, \RedisCluster::FAILOVER_DISTRIBUTE);
+ break;
+ case 'slaves':
+ $redis->setOption(\RedisCluster::OPT_SLAVE_FAILOVER, \RedisCluster::FAILOVER_DISTRIBUTE_SLAVES);
+ break;
+ }
+ return $redis;
+ };
+ $redis = $params['lazy'] ? new RedisClusterProxy($initializer) : $initializer();
+ } elseif (is_a($class, \Wordlift\Modules\Common\Predis\ClientInterface::class, \true)) {
+ if ($params['redis_cluster']) {
+ $params['cluster'] = 'redis';
+ } elseif (isset($params['redis_sentinel'])) {
+ $params['replication'] = 'sentinel';
+ $params['service'] = $params['redis_sentinel'];
+ }
+ $params += ['parameters' => []];
+ $params['parameters'] += ['persistent' => $params['persistent'], 'timeout' => $params['timeout'], 'read_write_timeout' => $params['read_timeout'], 'tcp_nodelay' => \true];
+ if ($params['dbindex']) {
+ $params['parameters']['database'] = $params['dbindex'];
+ }
+ if (null !== $auth) {
+ $params['parameters']['password'] = $auth;
+ }
+ if (isset($params['ssl'])) {
+ foreach ($hosts as $i => $host) {
+ if (!isset($host['ssl'])) {
+ $hosts[$i]['ssl'] = $params['ssl'];
+ }
+ }
+ }
+ if (1 === \count($hosts) && !($params['redis_cluster'] || $params['redis_sentinel'])) {
+ $hosts = $hosts[0];
+ } elseif (\in_array($params['failover'], ['slaves', 'distribute'], \true) && !isset($params['replication'])) {
+ $params['replication'] = \true;
+ $hosts[0] += ['alias' => 'master'];
+ }
+ $params['exceptions'] = \false;
+ $redis = new $class($hosts, array_diff_key($params, self::$defaultConnectionOptions));
+ if (isset($params['redis_sentinel'])) {
+ $redis->getConnection()->setSentinelTimeout($params['timeout']);
+ }
+ } elseif (class_exists($class, \false)) {
+ throw new InvalidArgumentException(sprintf('"%s" is not a subclass of "Redis", "RedisArray", "RedisCluster" nor "Predis\ClientInterface".', $class));
+ } else {
+ throw new InvalidArgumentException(sprintf('Class "%s" does not exist.', $class));
+ }
+ return $redis;
+ }
+ protected function doFetch(array $ids)
+ {
+ if (!$ids) {
+ return [];
+ }
+ $result = [];
+ if ($this->redis instanceof \Wordlift\Modules\Common\Predis\ClientInterface && ($this->redis->getConnection() instanceof ClusterInterface || $this->redis->getConnection() instanceof Predis2ClusterInterface)) {
+ $values = $this->pipeline(function () use ($ids) {
+ foreach ($ids as $id) {
+ yield 'get' => [$id];
+ }
+ });
+ } else {
+ $values = $this->redis->mget($ids);
+ if (!\is_array($values) || \count($values) !== \count($ids)) {
+ return [];
+ }
+ $values = array_combine($ids, $values);
+ }
+ foreach ($values as $id => $v) {
+ if ($v) {
+ $result[$id] = $this->marshaller->unmarshall($v);
+ }
+ }
+ return $result;
+ }
+ protected function doHave(string $id)
+ {
+ return (bool) $this->redis->exists($id);
+ }
+ protected function doClear(string $namespace)
+ {
+ if ($this->redis instanceof \Wordlift\Modules\Common\Predis\ClientInterface) {
+ $prefix = $this->redis->getOptions()->prefix ? $this->redis->getOptions()->prefix->getPrefix() : '';
+ $prefixLen = \strlen($prefix ?? '');
+ }
+ $cleared = \true;
+ $hosts = $this->getHosts();
+ $host = reset($hosts);
+ if ($host instanceof \Wordlift\Modules\Common\Predis\Client && $host->getConnection() instanceof ReplicationInterface) {
+ // Predis supports info command only on the master in replication environments
+ $hosts = [$host->getClientFor('master')];
+ }
+ foreach ($hosts as $host) {
+ if (!isset($namespace[0])) {
+ $cleared = $host->flushDb() && $cleared;
+ continue;
+ }
+ $info = $host->info('Server');
+ $info = (!$info instanceof ErrorInterface) ? $info['Server'] ?? $info : ['redis_version' => '2.0'];
+ if (!$host instanceof \Wordlift\Modules\Common\Predis\ClientInterface) {
+ $prefix = (\defined('Redis::SCAN_PREFIX') && \Redis::SCAN_PREFIX & $host->getOption(\Redis::OPT_SCAN)) ? '' : $host->getOption(\Redis::OPT_PREFIX);
+ $prefixLen = \strlen($host->getOption(\Redis::OPT_PREFIX) ?? '');
+ }
+ $pattern = $prefix . $namespace . '*';
+ if (!version_compare($info['redis_version'], '2.8', '>=')) {
+ // As documented in Redis documentation (http://redis.io/commands/keys) using KEYS
+ // can hang your server when it is executed against large databases (millions of items).
+ // Whenever you hit this scale, you should really consider upgrading to Redis 2.8 or above.
+ $unlink = version_compare($info['redis_version'], '4.0', '>=') ? 'UNLINK' : 'DEL';
+ $args = ($this->redis instanceof \Wordlift\Modules\Common\Predis\ClientInterface) ? [0, $pattern] : [[$pattern], 0];
+ $cleared = $host->eval("local keys=redis.call('KEYS',ARGV[1]) for i=1,#keys,5000 do redis.call('{$unlink}',unpack(keys,i,math.min(i+4999,#keys))) end return 1", $args[0], $args[1]) && $cleared;
+ continue;
+ }
+ $cursor = null;
+ do {
+ $keys = ($host instanceof \Wordlift\Modules\Common\Predis\ClientInterface) ? $host->scan($cursor, 'MATCH', $pattern, 'COUNT', 1000) : $host->scan($cursor, $pattern, 1000);
+ if (isset($keys[1]) && \is_array($keys[1])) {
+ $cursor = $keys[0];
+ $keys = $keys[1];
+ }
+ if ($keys) {
+ if ($prefixLen) {
+ foreach ($keys as $i => $key) {
+ $keys[$i] = substr($key, $prefixLen);
+ }
+ }
+ $this->doDelete($keys);
+ }
+ } while ($cursor);
+ }
+ return $cleared;
+ }
+ protected function doDelete(array $ids)
+ {
+ if (!$ids) {
+ return \true;
+ }
+ if ($this->redis instanceof \Wordlift\Modules\Common\Predis\ClientInterface && ($this->redis->getConnection() instanceof ClusterInterface || $this->redis->getConnection() instanceof Predis2ClusterInterface)) {
+ static $del;
+ $del = $del ?? (class_exists(UNLINK::class) ? 'unlink' : 'del');
+ $this->pipeline(function () use ($ids, $del) {
+ foreach ($ids as $id) {
+ yield $del => [$id];
+ }
+ })->rewind();
+ } else {
+ static $unlink = \true;
+ if ($unlink) {
+ try {
+ $unlink = \false !== $this->redis->unlink($ids);
+ } catch (\Throwable $e) {
+ $unlink = \false;
+ }
+ }
+ if (!$unlink) {
+ $this->redis->del($ids);
+ }
+ }
+ return \true;
+ }
+ protected function doSave(array $values, int $lifetime)
+ {
+ if (!$values = $this->marshaller->marshall($values, $failed)) {
+ return $failed;
+ }
+ $results = $this->pipeline(function () use ($values, $lifetime) {
+ foreach ($values as $id => $value) {
+ if (0 >= $lifetime) {
+ yield 'set' => [$id, $value];
+ } else {
+ yield 'setEx' => [$id, $lifetime, $value];
+ }
+ }
+ });
+ foreach ($results as $id => $result) {
+ if (\true !== $result && (!$result instanceof Status || Status::get('OK') !== $result)) {
+ $failed[] = $id;
+ }
+ }
+ return $failed;
+ }
+ private function pipeline(\Closure $generator, ?object $redis = null): \Generator
+ {
+ $ids = [];
+ $redis = $redis ?? $this->redis;
+ if ($redis instanceof RedisClusterProxy || $redis instanceof \RedisCluster || $redis instanceof \Wordlift\Modules\Common\Predis\ClientInterface && ($redis->getConnection() instanceof RedisCluster || $redis->getConnection() instanceof Predis2RedisCluster)) {
+ // phpredis & predis don't support pipelining with RedisCluster
+ // see https://github.com/phpredis/phpredis/blob/develop/cluster.markdown#pipelining
+ // see https://github.com/nrk/predis/issues/267#issuecomment-123781423
+ $results = [];
+ foreach ($generator() as $command => $args) {
+ $results[] = $redis->{$command}(...$args);
+ $ids[] = ('eval' === $command) ? ($redis instanceof \Wordlift\Modules\Common\Predis\ClientInterface) ? $args[2] : $args[1][0] : $args[0];
+ }
+ } elseif ($redis instanceof \Wordlift\Modules\Common\Predis\ClientInterface) {
+ $results = $redis->pipeline(static function ($redis) use ($generator, &$ids) {
+ foreach ($generator() as $command => $args) {
+ $redis->{$command}(...$args);
+ $ids[] = ('eval' === $command) ? $args[2] : $args[0];
+ }
+ });
+ } elseif ($redis instanceof \RedisArray) {
+ $connections = $results = $ids = [];
+ foreach ($generator() as $command => $args) {
+ $id = ('eval' === $command) ? $args[1][0] : $args[0];
+ if (!isset($connections[$h = $redis->_target($id)])) {
+ $connections[$h] = [$redis->_instance($h), -1];
+ $connections[$h][0]->multi(\Redis::PIPELINE);
+ }
+ $connections[$h][0]->{$command}(...$args);
+ $results[] = [$h, ++$connections[$h][1]];
+ $ids[] = $id;
+ }
+ foreach ($connections as $h => $c) {
+ $connections[$h] = $c[0]->exec();
+ }
+ foreach ($results as $k => [$h, $c]) {
+ $results[$k] = $connections[$h][$c];
+ }
+ } else {
+ $redis->multi(\Redis::PIPELINE);
+ foreach ($generator() as $command => $args) {
+ $redis->{$command}(...$args);
+ $ids[] = ('eval' === $command) ? $args[1][0] : $args[0];
+ }
+ $results = $redis->exec();
+ }
+ if (!$redis instanceof \Wordlift\Modules\Common\Predis\ClientInterface && 'eval' === $command && $redis->getLastError()) {
+ $e = new \RedisException($redis->getLastError());
+ $results = array_map(function ($v) use ($e) {
+ return (\false === $v) ? $e : $v;
+ }, (array) $results);
+ }
+ if (\is_bool($results)) {
+ return;
+ }
+ foreach ($ids as $k => $id) {
+ yield $id => $results[$k];
+ }
+ }
+ private function getHosts(): array
+ {
+ $hosts = [$this->redis];
+ if ($this->redis instanceof \Wordlift\Modules\Common\Predis\ClientInterface) {
+ $connection = $this->redis->getConnection();
+ if (($connection instanceof ClusterInterface || $connection instanceof Predis2ClusterInterface) && $connection instanceof \Traversable) {
+ $hosts = [];
+ foreach ($connection as $c) {
+ $hosts[] = new \Wordlift\Modules\Common\Predis\Client($c);
+ }
+ }
+ } elseif ($this->redis instanceof \RedisArray) {
+ $hosts = [];
+ foreach ($this->redis->_hosts() as $host) {
+ $hosts[] = $this->redis->_instance($host);
+ }
+ } elseif ($this->redis instanceof RedisClusterProxy || $this->redis instanceof \RedisCluster) {
+ $hosts = [];
+ foreach ($this->redis->_masters() as $host) {
+ $hosts[] = new RedisClusterNodeProxy($host, $this->redis);
+ }
+ }
+ return $hosts;
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/cache/composer.json b/src/modules/common/third-party/vendor/symfony/cache/composer.json
new file mode 100644
index 0000000000..5676d942f0
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/cache/composer.json
@@ -0,0 +1,65 @@
+{
+ "name": "symfony\/cache",
+ "type": "library",
+ "description": "Provides extended PSR-6, PSR-16 (and tags) implementations",
+ "keywords": [
+ "caching",
+ "psr6"
+ ],
+ "homepage": "https:\/\/symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https:\/\/symfony.com\/contributors"
+ }
+ ],
+ "provide": {
+ "psr\/cache-implementation": "1.0|2.0",
+ "psr\/simple-cache-implementation": "1.0|2.0",
+ "symfony\/cache-implementation": "1.0|2.0"
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "psr\/cache": "^1.0|^2.0",
+ "psr\/log": "^1.1|^2|^3",
+ "symfony\/cache-contracts": "^1.1.7|^2",
+ "symfony\/deprecation-contracts": "^2.1|^3",
+ "symfony\/polyfill-php73": "^1.9",
+ "symfony\/polyfill-php80": "^1.16",
+ "symfony\/service-contracts": "^1.1|^2|^3",
+ "symfony\/var-exporter": "^4.4|^5.0|^6.0"
+ },
+ "require-dev": {
+ "cache\/integration-tests": "dev-master",
+ "doctrine\/cache": "^1.6|^2.0",
+ "doctrine\/dbal": "^2.13.1|^3|^4",
+ "predis\/predis": "^1.1|^2.0",
+ "psr\/simple-cache": "^1.0|^2.0",
+ "symfony\/config": "^4.4|^5.0|^6.0",
+ "symfony\/dependency-injection": "^4.4|^5.0|^6.0",
+ "symfony\/filesystem": "^4.4|^5.0|^6.0",
+ "symfony\/http-kernel": "^4.4|^5.0|^6.0",
+ "symfony\/messenger": "^4.4|^5.0|^6.0",
+ "symfony\/var-dumper": "^4.4|^5.0|^6.0"
+ },
+ "conflict": {
+ "doctrine\/dbal": "<2.13.1",
+ "symfony\/dependency-injection": "<4.4",
+ "symfony\/http-kernel": "<4.4",
+ "symfony\/var-dumper": "<4.4"
+ },
+ "autoload": {
+ "psr-4": {
+ "Wordlift\\Modules\\Common\\Symfony\\Component\\Cache\\": ""
+ },
+ "exclude-from-classmap": [
+ "\/Tests\/"
+ ]
+ },
+ "minimum-stability": "dev"
+}
\ No newline at end of file
diff --git a/src/modules/common/third-party/vendor/symfony/config/Builder/ClassBuilder.php b/src/modules/common/third-party/vendor/symfony/config/Builder/ClassBuilder.php
new file mode 100644
index 0000000000..b6be8b5853
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/config/Builder/ClassBuilder.php
@@ -0,0 +1,149 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\Config\Builder;
+
+/**
+ * Build PHP classes to generate config.
+ *
+ * @internal
+ *
+ * @author Tobias Nyholm
+ */
+class ContainerBag extends FrozenParameterBag implements ContainerBagInterface
+{
+ private $container;
+ public function __construct(Container $container)
+ {
+ $this->container = $container;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function all()
+ {
+ return $this->container->getParameterBag()->all();
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return array|bool|string|int|float|\UnitEnum|null
+ */
+ public function get(string $name)
+ {
+ return $this->container->getParameter($name);
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function has(string $name)
+ {
+ return $this->container->hasParameter($name);
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/dependency-injection/ParameterBag/ContainerBagInterface.php b/src/modules/common/third-party/vendor/symfony/dependency-injection/ParameterBag/ContainerBagInterface.php
new file mode 100644
index 0000000000..6ce9066b52
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/dependency-injection/ParameterBag/ContainerBagInterface.php
@@ -0,0 +1,52 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\DependencyInjection\ParameterBag;
+
+use Wordlift\Modules\Common\Psr\Container\ContainerInterface;
+use Wordlift\Modules\Common\Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
+/**
+ * ContainerBagInterface is the interface implemented by objects that manage service container parameters.
+ *
+ * @author Nicolas Grekas
+ */
+interface ContainerBagInterface extends ContainerInterface
+{
+ /**
+ * Gets the service container parameters.
+ *
+ * @return array
+ */
+ public function all();
+ /**
+ * Replaces parameter placeholders (%name%) by their values.
+ *
+ * @param mixed $value A value
+ *
+ * @throws ParameterNotFoundException if a placeholder references a parameter that does not exist
+ */
+ public function resolveValue($value);
+ /**
+ * Escape parameter placeholders %.
+ *
+ * @param mixed $value
+ *
+ * @return mixed
+ */
+ public function escapeValue($value);
+ /**
+ * Unescape parameter placeholders %.
+ *
+ * @param mixed $value
+ *
+ * @return mixed
+ */
+ public function unescapeValue($value);
+}
diff --git a/src/modules/common/third-party/vendor/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php b/src/modules/common/third-party/vendor/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php
index daa978ab61..334676cf87 100644
--- a/src/modules/common/third-party/vendor/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php
+++ b/src/modules/common/third-party/vendor/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php
@@ -17,37 +17,57 @@
*/
class EnvPlaceholderParameterBag extends ParameterBag
{
+ private $envPlaceholderUniquePrefix;
private $envPlaceholders = [];
+ private $unusedEnvPlaceholders = [];
private $providedTypes = [];
+ private static $counter = 0;
/**
* {@inheritdoc}
*/
- public function get($name)
+ public function get(string $name)
{
- if (0 === \strpos($name, 'env(') && ')' === \substr($name, -1) && 'env()' !== $name) {
- $env = \substr($name, 4, -1);
+ if (str_starts_with($name, 'env(') && str_ends_with($name, ')') && 'env()' !== $name) {
+ $env = substr($name, 4, -1);
if (isset($this->envPlaceholders[$env])) {
foreach ($this->envPlaceholders[$env] as $placeholder) {
return $placeholder;
// return first result
}
}
- if (!\preg_match('/^(?:\\w++:)*+\\w++$/', $env)) {
- throw new InvalidArgumentException(\sprintf('Invalid "%s" name: only "word" characters are allowed.', $name));
- }
- if ($this->has($name)) {
- $defaultValue = parent::get($name);
- if (null !== $defaultValue && !\is_scalar($defaultValue)) {
- throw new RuntimeException(\sprintf('The default value of an env() parameter must be scalar or null, but "%s" given to "%s".', \gettype($defaultValue), $name));
+ if (isset($this->unusedEnvPlaceholders[$env])) {
+ foreach ($this->unusedEnvPlaceholders[$env] as $placeholder) {
+ return $placeholder;
+ // return first result
}
}
- $uniqueName = \md5($name . \uniqid(\mt_rand(), \true));
- $placeholder = \sprintf('env_%s_%s', \str_replace(':', '_', $env), $uniqueName);
+ if (!preg_match('/^(?:[-.\w]*+:)*+\w++$/', $env)) {
+ throw new InvalidArgumentException(sprintf('Invalid %s name: only "word" characters are allowed.', $name));
+ }
+ if ($this->has($name) && null !== ($defaultValue = parent::get($name)) && !\is_string($defaultValue)) {
+ throw new RuntimeException(sprintf('The default value of an env() parameter must be a string or null, but "%s" given to "%s".', get_debug_type($defaultValue), $name));
+ }
+ $uniqueName = md5($name . '_' . self::$counter++);
+ $placeholder = sprintf('%s_%s_%s', $this->getEnvPlaceholderUniquePrefix(), strtr($env, ':-.', '___'), $uniqueName);
$this->envPlaceholders[$env][$placeholder] = $placeholder;
return $placeholder;
}
return parent::get($name);
}
+ /**
+ * Gets the common env placeholder prefix for env vars created by this bag.
+ */
+ public function getEnvPlaceholderUniquePrefix(): string
+ {
+ if (null === $this->envPlaceholderUniquePrefix) {
+ $reproducibleEntropy = unserialize(serialize($this->parameters));
+ array_walk_recursive($reproducibleEntropy, function (&$v) {
+ $v = null;
+ });
+ $this->envPlaceholderUniquePrefix = 'env_' . substr(md5(serialize($reproducibleEntropy)), -16);
+ }
+ return $this->envPlaceholderUniquePrefix;
+ }
/**
* Returns the map of env vars used in the resolved parameter values to their placeholders.
*
@@ -57,6 +77,14 @@ public function getEnvPlaceholders()
{
return $this->envPlaceholders;
}
+ public function getUnusedEnvPlaceholders(): array
+ {
+ return $this->unusedEnvPlaceholders;
+ }
+ public function clearUnusedEnvPlaceholders()
+ {
+ $this->unusedEnvPlaceholders = [];
+ }
/**
* Merges the env placeholders of another EnvPlaceholderParameterBag.
*/
@@ -68,6 +96,12 @@ public function mergeEnvPlaceholders(self $bag)
$this->envPlaceholders[$env] += $placeholders;
}
}
+ if ($newUnusedPlaceholders = $bag->getUnusedEnvPlaceholders()) {
+ $this->unusedEnvPlaceholders += $newUnusedPlaceholders;
+ foreach ($newUnusedPlaceholders as $env => $placeholders) {
+ $this->unusedEnvPlaceholders[$env] += $placeholders;
+ }
+ }
}
/**
* Maps env prefixes to their corresponding PHP types.
@@ -95,13 +129,8 @@ public function resolve()
}
parent::resolve();
foreach ($this->envPlaceholders as $env => $placeholders) {
- if (!$this->has($name = "env({$env})")) {
- continue;
- }
- if (\is_numeric($default = $this->parameters[$name])) {
- $this->parameters[$name] = (string) $default;
- } elseif (null !== $default && !\is_scalar($default)) {
- throw new RuntimeException(\sprintf('The default value of env parameter "%s" must be scalar or null, "%s" given.', $env, \gettype($default)));
+ if ($this->has($name = "env({$env})") && null !== ($default = $this->parameters[$name]) && !\is_string($default)) {
+ throw new RuntimeException(sprintf('The default value of env parameter "%s" must be a string or null, "%s" given.', $env, get_debug_type($default)));
}
}
}
diff --git a/src/modules/common/third-party/vendor/symfony/dependency-injection/ParameterBag/FrozenParameterBag.php b/src/modules/common/third-party/vendor/symfony/dependency-injection/ParameterBag/FrozenParameterBag.php
index 50a38ea026..aebfe99679 100644
--- a/src/modules/common/third-party/vendor/symfony/dependency-injection/ParameterBag/FrozenParameterBag.php
+++ b/src/modules/common/third-party/vendor/symfony/dependency-injection/ParameterBag/FrozenParameterBag.php
@@ -48,14 +48,14 @@ public function add(array $parameters)
/**
* {@inheritdoc}
*/
- public function set($name, $value)
+ public function set(string $name, $value)
{
throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
}
/**
* {@inheritdoc}
*/
- public function remove($name)
+ public function remove(string $name)
{
throw new LogicException('Impossible to call remove() on a frozen ParameterBag.');
}
diff --git a/src/modules/common/third-party/vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php b/src/modules/common/third-party/vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php
index beae00ed16..2bcc722a10 100644
--- a/src/modules/common/third-party/vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php
+++ b/src/modules/common/third-party/vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php
@@ -22,25 +22,19 @@ class ParameterBag implements ParameterBagInterface
{
protected $parameters = [];
protected $resolved = \false;
- private $normalizedNames = [];
- /**
- * @param array $parameters An array of parameters
- */
public function __construct(array $parameters = [])
{
$this->add($parameters);
}
/**
- * Clears all parameters.
+ * {@inheritdoc}
*/
public function clear()
{
$this->parameters = [];
}
/**
- * Adds parameters to the service container parameters.
- *
- * @param array $parameters An array of parameters
+ * {@inheritdoc}
*/
public function add(array $parameters)
{
@@ -58,24 +52,23 @@ public function all()
/**
* {@inheritdoc}
*/
- public function get($name)
+ public function get(string $name)
{
- $name = $this->normalizeName($name);
if (!\array_key_exists($name, $this->parameters)) {
if (!$name) {
throw new ParameterNotFoundException($name);
}
$alternatives = [];
foreach ($this->parameters as $key => $parameterValue) {
- $lev = \levenshtein($name, $key);
- if ($lev <= \strlen($name) / 3 || \false !== \strpos($key, $name)) {
+ $lev = levenshtein($name, $key);
+ if ($lev <= \strlen($name) / 3 || str_contains($key, $name)) {
$alternatives[] = $key;
}
}
$nonNestedAlternative = null;
- if (!\count($alternatives) && \false !== \strpos($name, '.')) {
- $namePartsLength = \array_map('strlen', \explode('.', $name));
- $key = \substr($name, 0, -1 * (1 + \array_pop($namePartsLength)));
+ if (!\count($alternatives) && str_contains($name, '.')) {
+ $namePartsLength = array_map('strlen', explode('.', $name));
+ $key = substr($name, 0, -1 * (1 + array_pop($namePartsLength)));
while (\count($namePartsLength)) {
if ($this->has($key)) {
if (\is_array($this->get($key))) {
@@ -83,7 +76,7 @@ public function get($name)
}
break;
}
- $key = \substr($key, 0, -1 * (1 + \array_pop($namePartsLength)));
+ $key = substr($key, 0, -1 * (1 + array_pop($namePartsLength)));
}
}
throw new ParameterNotFoundException($name, null, null, null, $alternatives, $nonNestedAlternative);
@@ -91,30 +84,25 @@ public function get($name)
return $this->parameters[$name];
}
/**
- * Sets a service container parameter.
- *
- * @param string $name The parameter name
- * @param mixed $value The parameter value
+ * {@inheritdoc}
*/
- public function set($name, $value)
+ public function set(string $name, $value)
{
- $this->parameters[$this->normalizeName($name)] = $value;
+ $this->parameters[$name] = $value;
}
/**
* {@inheritdoc}
*/
- public function has($name)
+ public function has(string $name)
{
- return \array_key_exists($this->normalizeName($name), $this->parameters);
+ return \array_key_exists($name, $this->parameters);
}
/**
- * Removes a parameter.
- *
- * @param string $name The parameter name
+ * {@inheritdoc}
*/
- public function remove($name)
+ public function remove(string $name)
{
- unset($this->parameters[$this->normalizeName($name)]);
+ unset($this->parameters[$name]);
}
/**
* {@inheritdoc}
@@ -143,7 +131,7 @@ public function resolve()
* @param mixed $value A value
* @param array $resolving An array of keys that are being resolved (used internally to detect circular references)
*
- * @return mixed The resolved value
+ * @return mixed
*
* @throws ParameterNotFoundException if a placeholder references a parameter that does not exist
* @throws ParameterCircularReferenceException if a circular reference if detected
@@ -166,47 +154,42 @@ public function resolveValue($value, array $resolving = [])
/**
* Resolves parameters inside a string.
*
- * @param string $value The string to resolve
- * @param array $resolving An array of keys that are being resolved (used internally to detect circular references)
+ * @param array $resolving An array of keys that are being resolved (used internally to detect circular references)
*
- * @return mixed The resolved string
+ * @return mixed
*
* @throws ParameterNotFoundException if a placeholder references a parameter that does not exist
* @throws ParameterCircularReferenceException if a circular reference if detected
* @throws RuntimeException when a given parameter has a type problem
*/
- public function resolveString($value, array $resolving = [])
+ public function resolveString(string $value, array $resolving = [])
{
// we do this to deal with non string values (Boolean, integer, ...)
// as the preg_replace_callback throw an exception when trying
// a non-string in a parameter value
- if (\preg_match('/^%([^%\\s]+)%$/', $value, $match)) {
+ if (preg_match('/^%([^%\s]+)%$/', $value, $match)) {
$key = $match[1];
- $lcKey = \strtolower($key);
- // strtolower() to be removed in 4.0
- if (isset($resolving[$lcKey])) {
- throw new ParameterCircularReferenceException(\array_keys($resolving));
+ if (isset($resolving[$key])) {
+ throw new ParameterCircularReferenceException(array_keys($resolving));
}
- $resolving[$lcKey] = \true;
+ $resolving[$key] = \true;
return $this->resolved ? $this->get($key) : $this->resolveValue($this->get($key), $resolving);
}
- return \preg_replace_callback('/%%|%([^%\\s]+)%/', function ($match) use($resolving, $value) {
+ return preg_replace_callback('/%%|%([^%\s]+)%/', function ($match) use ($resolving, $value) {
// skip %%
if (!isset($match[1])) {
return '%%';
}
$key = $match[1];
- $lcKey = \strtolower($key);
- // strtolower() to be removed in 4.0
- if (isset($resolving[$lcKey])) {
- throw new ParameterCircularReferenceException(\array_keys($resolving));
+ if (isset($resolving[$key])) {
+ throw new ParameterCircularReferenceException(array_keys($resolving));
}
$resolved = $this->get($key);
- if (!\is_string($resolved) && !\is_numeric($resolved)) {
- throw new RuntimeException(\sprintf('A string value must be composed of strings and/or numbers, but found parameter "%s" of type "%s" inside string value "%s".', $key, \gettype($resolved), $value));
+ if (!\is_string($resolved) && !is_numeric($resolved)) {
+ throw new RuntimeException(sprintf('A string value must be composed of strings and/or numbers, but found parameter "%s" of type "%s" inside string value "%s".', $key, get_debug_type($resolved), $value));
}
$resolved = (string) $resolved;
- $resolving[$lcKey] = \true;
+ $resolving[$key] = \true;
return $this->isResolved() ? $resolved : $this->resolveString($resolved, $resolving);
}, $value);
}
@@ -220,7 +203,7 @@ public function isResolved()
public function escapeValue($value)
{
if (\is_string($value)) {
- return \str_replace('%', '%%', $value);
+ return str_replace('%', '%%', $value);
}
if (\is_array($value)) {
$result = [];
@@ -237,7 +220,7 @@ public function escapeValue($value)
public function unescapeValue($value)
{
if (\is_string($value)) {
- return \str_replace('%%', '%', $value);
+ return str_replace('%%', '%', $value);
}
if (\is_array($value)) {
$result = [];
@@ -248,16 +231,4 @@ public function unescapeValue($value)
}
return $value;
}
- private function normalizeName($name)
- {
- if (isset($this->normalizedNames[$normalizedName = \strtolower($name)])) {
- $normalizedName = $this->normalizedNames[$normalizedName];
- if ((string) $name !== $normalizedName) {
- @\trigger_error(\sprintf('Parameter names will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.4.', $name, $normalizedName), \E_USER_DEPRECATED);
- }
- } else {
- $normalizedName = $this->normalizedNames[$normalizedName] = (string) $name;
- }
- return $normalizedName;
- }
}
diff --git a/src/modules/common/third-party/vendor/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php b/src/modules/common/third-party/vendor/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php
index 5ea9e7d2ef..2708e55256 100644
--- a/src/modules/common/third-party/vendor/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php
+++ b/src/modules/common/third-party/vendor/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php
@@ -13,7 +13,7 @@
use Wordlift\Modules\Common\Symfony\Component\DependencyInjection\Exception\LogicException;
use Wordlift\Modules\Common\Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
/**
- * ParameterBagInterface.
+ * ParameterBagInterface is the interface implemented by objects that manage service container parameters.
*
* @author Fabien Potencier
+ */
+final class ReverseContainer
+{
+ private $serviceContainer;
+ private $reversibleLocator;
+ private $tagName;
+ private $getServiceId;
+ public function __construct(Container $serviceContainer, ContainerInterface $reversibleLocator, string $tagName = 'container.reversible')
+ {
+ $this->serviceContainer = $serviceContainer;
+ $this->reversibleLocator = $reversibleLocator;
+ $this->tagName = $tagName;
+ $this->getServiceId = \Closure::bind(function (object $service): ?string {
+ return (array_search($service, $this->services, \true) ?: array_search($service, $this->privates, \true)) ?: null;
+ }, $serviceContainer, Container::class);
+ }
+ /**
+ * Returns the id of the passed object when it exists as a service.
+ *
+ * To be reversible, services need to be either public or be tagged with "container.reversible".
+ */
+ public function getId(object $service): ?string
+ {
+ if ($this->serviceContainer === $service) {
+ return 'service_container';
+ }
+ if (null === $id = ($this->getServiceId)($service)) {
+ return null;
+ }
+ if ($this->serviceContainer->has($id) || $this->reversibleLocator->has($id)) {
+ return $id;
+ }
+ return null;
+ }
+ /**
+ * @throws ServiceNotFoundException When the service is not reversible
+ */
+ public function getService(string $id): object
+ {
+ if ($this->reversibleLocator->has($id)) {
+ return $this->reversibleLocator->get($id);
+ }
+ if (isset($this->serviceContainer->getRemovedIds()[$id])) {
+ throw new ServiceNotFoundException($id, null, null, [], sprintf('The "%s" service is private and cannot be accessed by reference. You should either make it public, or tag it as "%s".', $id, $this->tagName));
+ }
+ return $this->serviceContainer->get($id);
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/dependency-injection/ServiceLocator.php b/src/modules/common/third-party/vendor/symfony/dependency-injection/ServiceLocator.php
index 440311747a..550356bf7c 100644
--- a/src/modules/common/third-party/vendor/symfony/dependency-injection/ServiceLocator.php
+++ b/src/modules/common/third-party/vendor/symfony/dependency-injection/ServiceLocator.php
@@ -10,78 +10,76 @@
*/
namespace Wordlift\Modules\Common\Symfony\Component\DependencyInjection;
-use Wordlift\Modules\Common\Psr\Container\ContainerInterface as PsrContainerInterface;
+use Wordlift\Modules\Common\Psr\Container\ContainerExceptionInterface;
+use Wordlift\Modules\Common\Psr\Container\NotFoundExceptionInterface;
+use Wordlift\Modules\Common\Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Wordlift\Modules\Common\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use Wordlift\Modules\Common\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
+use Wordlift\Modules\Common\Symfony\Contracts\Service\ServiceLocatorTrait;
+use Wordlift\Modules\Common\Symfony\Contracts\Service\ServiceProviderInterface;
+use Wordlift\Modules\Common\Symfony\Contracts\Service\ServiceSubscriberInterface;
/**
* @author Robin Chalas
*/
-class ServiceLocator implements PsrContainerInterface
+class ServiceLocator implements ServiceProviderInterface
{
- private $factories;
- private $loading = [];
+ use ServiceLocatorTrait {
+ get as private doGet;
+ }
private $externalId;
private $container;
- /**
- * @param callable[] $factories
- */
- public function __construct(array $factories)
- {
- $this->factories = $factories;
- }
- /**
- * {@inheritdoc}
- */
- public function has($id)
- {
- return isset($this->factories[$id]);
- }
/**
* {@inheritdoc}
+ *
+ * @return mixed
*/
- public function get($id)
+ public function get(string $id)
{
- if (!isset($this->factories[$id])) {
- throw new ServiceNotFoundException($id, \end($this->loading) ?: null, null, [], $this->createServiceNotFoundMessage($id));
- }
- if (isset($this->loading[$id])) {
- $ids = \array_values($this->loading);
- $ids = \array_slice($this->loading, \array_search($id, $ids));
- $ids[] = $id;
- throw new ServiceCircularReferenceException($id, $ids);
+ if (!$this->externalId) {
+ return $this->doGet($id);
}
- $this->loading[$id] = $id;
try {
- return $this->factories[$id]();
- } finally {
- unset($this->loading[$id]);
+ return $this->doGet($id);
+ } catch (RuntimeException $e) {
+ $what = sprintf('service "%s" required by "%s"', $id, $this->externalId);
+ $message = preg_replace('/service "\.service_locator\.[^"]++"/', $what, $e->getMessage());
+ if ($e->getMessage() === $message) {
+ $message = sprintf('Cannot resolve %s: %s', $what, $message);
+ }
+ $r = new \ReflectionProperty($e, 'message');
+ $r->setAccessible(\true);
+ $r->setValue($e, $message);
+ throw $e;
}
}
- public function __invoke($id)
+ public function __invoke(string $id)
{
return isset($this->factories[$id]) ? $this->get($id) : null;
}
/**
* @internal
+ *
+ * @return static
*/
- public function withContext($externalId, Container $container)
+ public function withContext(string $externalId, Container $container): self
{
$locator = clone $this;
$locator->externalId = $externalId;
$locator->container = $container;
return $locator;
}
- private function createServiceNotFoundMessage($id)
+ private function createNotFoundException(string $id): NotFoundExceptionInterface
{
if ($this->loading) {
- return \sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', \end($this->loading), $id, $this->formatAlternatives());
+ $msg = sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', end($this->loading), $id, $this->formatAlternatives());
+ return new ServiceNotFoundException($id, end($this->loading) ?: null, null, [], $msg);
}
- $class = \debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT | \DEBUG_BACKTRACE_IGNORE_ARGS, 3);
- $class = isset($class[2]['object']) ? \get_class($class[2]['object']) : null;
+ $class = debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT | \DEBUG_BACKTRACE_IGNORE_ARGS, 4);
+ $class = isset($class[3]['object']) ? \get_class($class[3]['object']) : null;
$externalId = $this->externalId ?: $class;
$msg = [];
- $msg[] = \sprintf('Service "%s" not found:', $id);
+ $msg[] = sprintf('Service "%s" not found:', $id);
if (!$this->container) {
$class = null;
} elseif ($this->container->has($id) || isset($this->container->getRemovedIds()[$id])) {
@@ -92,36 +90,40 @@ private function createServiceNotFoundMessage($id)
$class = null;
} catch (ServiceNotFoundException $e) {
if ($e->getAlternatives()) {
- $msg[] = \sprintf('did you mean %s? Anyway,', $this->formatAlternatives($e->getAlternatives(), 'or'));
+ $msg[] = sprintf('did you mean %s? Anyway,', $this->formatAlternatives($e->getAlternatives(), 'or'));
} else {
$class = null;
}
}
}
if ($externalId) {
- $msg[] = \sprintf('the container inside "%s" is a smaller service locator that %s', $externalId, $this->formatAlternatives());
+ $msg[] = sprintf('the container inside "%s" is a smaller service locator that %s', $externalId, $this->formatAlternatives());
} else {
- $msg[] = \sprintf('the current service locator %s', $this->formatAlternatives());
+ $msg[] = sprintf('the current service locator %s', $this->formatAlternatives());
}
if (!$class) {
// no-op
- } elseif (\is_subclass_of($class, ServiceSubscriberInterface::class)) {
- $msg[] = \sprintf('Unless you need extra laziness, try using dependency injection instead. Otherwise, you need to declare it using "%s::getSubscribedServices()".', \preg_replace('/([^\\\\]++\\\\)++/', '', $class));
+ } elseif (is_subclass_of($class, ServiceSubscriberInterface::class)) {
+ $msg[] = sprintf('Unless you need extra laziness, try using dependency injection instead. Otherwise, you need to declare it using "%s::getSubscribedServices()".', preg_replace('/([^\\\\]++\\\\)++/', '', $class));
} else {
$msg[] = 'Try using dependency injection instead.';
}
- return \implode(' ', $msg);
+ return new ServiceNotFoundException($id, end($this->loading) ?: null, null, [], implode(' ', $msg));
+ }
+ private function createCircularReferenceException(string $id, array $path): ContainerExceptionInterface
+ {
+ return new ServiceCircularReferenceException($id, $path);
}
- private function formatAlternatives(array $alternatives = null, $separator = 'and')
+ private function formatAlternatives(?array $alternatives = null, string $separator = 'and'): string
{
$format = '"%s"%s';
if (null === $alternatives) {
- if (!($alternatives = \array_keys($this->factories))) {
+ if (!$alternatives = array_keys($this->factories)) {
return 'is empty...';
}
- $format = \sprintf('only knows about the %s service%s.', $format, 1 < \count($alternatives) ? 's' : '');
+ $format = sprintf('only knows about the %s service%s.', $format, (1 < \count($alternatives)) ? 's' : '');
}
- $last = \array_pop($alternatives);
- return \sprintf($format, $alternatives ? \implode('", "', $alternatives) : $last, $alternatives ? \sprintf(' %s "%s"', $separator, $last) : '');
+ $last = array_pop($alternatives);
+ return sprintf($format, $alternatives ? implode('", "', $alternatives) : $last, $alternatives ? sprintf(' %s "%s"', $separator, $last) : '');
}
}
diff --git a/src/modules/common/third-party/vendor/symfony/dependency-injection/TaggedContainerInterface.php b/src/modules/common/third-party/vendor/symfony/dependency-injection/TaggedContainerInterface.php
index f962fc0004..26d9ed0a18 100644
--- a/src/modules/common/third-party/vendor/symfony/dependency-injection/TaggedContainerInterface.php
+++ b/src/modules/common/third-party/vendor/symfony/dependency-injection/TaggedContainerInterface.php
@@ -22,7 +22,7 @@ interface TaggedContainerInterface extends ContainerInterface
*
* @param string $name The tag name
*
- * @return array An array of tags
+ * @return array
*/
- public function findTaggedServiceIds($name);
+ public function findTaggedServiceIds(string $name);
}
diff --git a/src/modules/common/third-party/vendor/symfony/dependency-injection/TypedReference.php b/src/modules/common/third-party/vendor/symfony/dependency-injection/TypedReference.php
index a624acf3b7..7ca1641531 100644
--- a/src/modules/common/third-party/vendor/symfony/dependency-injection/TypedReference.php
+++ b/src/modules/common/third-party/vendor/symfony/dependency-injection/TypedReference.php
@@ -18,29 +18,25 @@
class TypedReference extends Reference
{
private $type;
- private $requiringClass;
+ private $name;
/**
- * @param string $id The service identifier
- * @param string $type The PHP type of the identified service
- * @param string $requiringClass The class of the service that requires the referenced type
- * @param int $invalidBehavior The behavior when the service does not exist
+ * @param string $id The service identifier
+ * @param string $type The PHP type of the identified service
+ * @param int $invalidBehavior The behavior when the service does not exist
+ * @param string|null $name The name of the argument targeting the service
*/
- public function __construct($id, $type, $requiringClass = '', $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE)
+ public function __construct(string $id, string $type, int $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, ?string $name = null)
{
+ $this->name = ($type === $id) ? $name : null;
parent::__construct($id, $invalidBehavior);
$this->type = $type;
- $this->requiringClass = $requiringClass;
}
public function getType()
{
return $this->type;
}
- public function getRequiringClass()
+ public function getName(): ?string
{
- return $this->requiringClass;
- }
- public function canBeAutoregistered()
- {
- return $this->requiringClass && \false !== ($i = \strpos($this->type, '\\')) && 0 === \strncasecmp($this->type, $this->requiringClass, 1 + $i);
+ return $this->name;
}
}
diff --git a/src/modules/common/third-party/vendor/symfony/dependency-injection/Variable.php b/src/modules/common/third-party/vendor/symfony/dependency-injection/Variable.php
index 8ff822b288..1e71b78ed3 100644
--- a/src/modules/common/third-party/vendor/symfony/dependency-injection/Variable.php
+++ b/src/modules/common/third-party/vendor/symfony/dependency-injection/Variable.php
@@ -26,13 +26,13 @@
class Variable
{
private $name;
- /**
- * @param string $name
- */
- public function __construct($name)
+ public function __construct(string $name)
{
$this->name = $name;
}
+ /**
+ * @return string
+ */
public function __toString()
{
return $this->name;
diff --git a/src/modules/common/third-party/vendor/symfony/dependency-injection/composer.json b/src/modules/common/third-party/vendor/symfony/dependency-injection/composer.json
new file mode 100644
index 0000000000..a5f9701f5b
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/dependency-injection/composer.json
@@ -0,0 +1,58 @@
+{
+ "name": "symfony\/dependency-injection",
+ "type": "library",
+ "description": "Allows you to standardize and centralize the way objects are constructed in your application",
+ "keywords": [],
+ "homepage": "https:\/\/symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https:\/\/symfony.com\/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=7.2.5",
+ "psr\/container": "^1.1.1",
+ "symfony\/deprecation-contracts": "^2.1|^3",
+ "symfony\/polyfill-php80": "^1.16",
+ "symfony\/polyfill-php81": "^1.22",
+ "symfony\/service-contracts": "^1.1.6|^2"
+ },
+ "require-dev": {
+ "symfony\/yaml": "^4.4.26|^5.0|^6.0",
+ "symfony\/config": "^5.3|^6.0",
+ "symfony\/expression-language": "^4.4|^5.0|^6.0"
+ },
+ "suggest": {
+ "symfony\/yaml": "",
+ "symfony\/config": "",
+ "symfony\/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required",
+ "symfony\/expression-language": "For using expressions in service container configuration",
+ "symfony\/proxy-manager-bridge": "Generate service proxies to lazy load them"
+ },
+ "conflict": {
+ "ext-psr": "<1.1|>=2",
+ "symfony\/config": "<5.3",
+ "symfony\/finder": "<4.4",
+ "symfony\/proxy-manager-bridge": "<4.4",
+ "symfony\/yaml": "<4.4.26"
+ },
+ "provide": {
+ "psr\/container-implementation": "1.0",
+ "symfony\/service-implementation": "1.0|2.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Wordlift\\Modules\\Common\\Symfony\\Component\\DependencyInjection\\": ""
+ },
+ "exclude-from-classmap": [
+ "\/Tests\/"
+ ]
+ },
+ "minimum-stability": "dev"
+}
\ No newline at end of file
diff --git a/src/modules/common/third-party/vendor/symfony/deprecation-contracts/composer.json b/src/modules/common/third-party/vendor/symfony/deprecation-contracts/composer.json
new file mode 100644
index 0000000000..ab39026cd6
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/deprecation-contracts/composer.json
@@ -0,0 +1,35 @@
+{
+ "name": "symfony\/deprecation-contracts",
+ "type": "library",
+ "description": "A generic function and convention to trigger deprecation notices",
+ "homepage": "https:\/\/symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https:\/\/symfony.com\/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=7.1"
+ },
+ "autoload": {
+ "files": [
+ "function.php"
+ ]
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "2.5-dev"
+ },
+ "thanks": {
+ "name": "symfony\/contracts",
+ "url": "https:\/\/github.com\/symfony\/contracts"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/modules/common/third-party/vendor/symfony/deprecation-contracts/function.php b/src/modules/common/third-party/vendor/symfony/deprecation-contracts/function.php
new file mode 100644
index 0000000000..f8aed24e10
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/deprecation-contracts/function.php
@@ -0,0 +1,28 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+if (!\function_exists('Wordlift\Modules\Common\trigger_deprecation')) {
+ /**
+ * Triggers a silenced deprecation notice.
+ *
+ * @param string $package The name of the Composer package that is triggering the deprecation
+ * @param string $version The version of the package that introduced the deprecation
+ * @param string $message The message of the deprecation
+ * @param mixed ...$args Values to insert in the message using printf() formatting
+ *
+ * @author Nicolas Grekas
+ */
+ function trigger_deprecation(string $package, string $version, string $message, ...$args): void
+ {
+ @\trigger_error((($package || $version) ? "Since {$package} {$version}: " : '') . ($args ? \vsprintf($message, $args) : $message), \E_USER_DEPRECATED);
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/expression-language/Compiler.php b/src/modules/common/third-party/vendor/symfony/expression-language/Compiler.php
new file mode 100644
index 0000000000..eb7543092c
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/expression-language/Compiler.php
@@ -0,0 +1,126 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\ExpressionLanguage;
+
+use Wordlift\Modules\Common\Symfony\Contracts\Service\ResetInterface;
+/**
+ * Compiles a node to PHP code.
+ *
+ * @author Fabien Potencier
+ *
+ * @internal
+ */
+final class Php81
+{
+ public static function array_is_list(array $array): bool
+ {
+ if ([] === $array || $array === array_values($array)) {
+ return \true;
+ }
+ $nextKey = -1;
+ foreach ($array as $k => $v) {
+ if ($k !== ++$nextKey) {
+ return \false;
+ }
+ }
+ return \true;
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php b/src/modules/common/third-party/vendor/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php
new file mode 100644
index 0000000000..ab675f37c6
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php
@@ -0,0 +1,49 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+if (\PHP_VERSION_ID >= 70400 && \extension_loaded('curl')) {
+ /**
+ * @property string $data
+ */
+ class CURLStringFile extends \CURLFile
+ {
+ private $data;
+ public function __construct(string $data, string $postname, string $mime = 'application/octet-stream')
+ {
+ $this->data = $data;
+ parent::__construct('data://application/octet-stream;base64,' . \base64_encode($data), $mime, $postname);
+ }
+ public function __set(string $name, $value): void
+ {
+ if ('data' !== $name) {
+ $this->{$name} = $value;
+ return;
+ }
+ if (\is_object($value) ? !\method_exists($value, '__toString') : !\is_scalar($value)) {
+ throw new \TypeError('Cannot assign ' . \gettype($value) . ' to property CURLStringFile::$data of type string');
+ }
+ $this->name = 'data://application/octet-stream;base64,' . \base64_encode($value);
+ }
+ public function __isset(string $name): bool
+ {
+ return isset($this->{$name});
+ }
+ public function &__get(string $name)
+ {
+ return $this->{$name};
+ }
+ }
+ /**
+ * @property string $data
+ */
+ \class_alias('Wordlift\Modules\Common\CURLStringFile', 'CURLStringFile', \false);
+}
diff --git a/src/modules/common/third-party/vendor/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php b/src/modules/common/third-party/vendor/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php
new file mode 100644
index 0000000000..6decc0a114
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php
@@ -0,0 +1,22 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+if (\PHP_VERSION_ID < 80100) {
+ #[\Attribute(\Attribute::TARGET_METHOD)]
+ final class ReturnTypeWillChange
+ {
+ public function __construct()
+ {
+ }
+ }
+ \class_alias('Wordlift\Modules\Common\ReturnTypeWillChange', 'ReturnTypeWillChange', \false);
+}
diff --git a/src/modules/common/third-party/vendor/symfony/polyfill-php81/bootstrap.php b/src/modules/common/third-party/vendor/symfony/polyfill-php81/bootstrap.php
new file mode 100644
index 0000000000..04fd6dda62
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/polyfill-php81/bootstrap.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+use Wordlift\Modules\Common\Symfony\Polyfill\Php81 as p;
+if (\PHP_VERSION_ID >= 80100) {
+ return;
+}
+if (\defined('MYSQLI_REFRESH_SLAVE') && !\defined('MYSQLI_REFRESH_REPLICA')) {
+ \define('MYSQLI_REFRESH_REPLICA', 64);
+}
+if (!\function_exists('array_is_list') && !\function_exists('Wordlift\Modules\Common\array_is_list')) {
+ function array_is_list(array $array): bool
+ {
+ return p\Php81::array_is_list($array);
+ }
+}
+if (!\function_exists('enum_exists') && !\function_exists('Wordlift\Modules\Common\enum_exists')) {
+ function enum_exists(string $enum, bool $autoload = \true): bool
+ {
+ return $autoload && \class_exists($enum) && \false;
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/polyfill-php81/composer.json b/src/modules/common/third-party/vendor/symfony/polyfill-php81/composer.json
new file mode 100644
index 0000000000..60527bc1b2
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/polyfill-php81/composer.json
@@ -0,0 +1,44 @@
+{
+ "name": "symfony\/polyfill-php81",
+ "type": "library",
+ "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
+ "keywords": [
+ "polyfill",
+ "shim",
+ "compatibility",
+ "portable"
+ ],
+ "homepage": "https:\/\/symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https:\/\/symfony.com\/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=7.2"
+ },
+ "autoload": {
+ "psr-4": {
+ "Wordlift\\Modules\\Common\\Symfony\\Polyfill\\Php81\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ],
+ "classmap": [
+ "Resources\/stubs"
+ ]
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "thanks": {
+ "name": "symfony\/polyfill",
+ "url": "https:\/\/github.com\/symfony\/polyfill"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/modules/common/third-party/vendor/symfony/service-contracts/Attribute/Required.php b/src/modules/common/third-party/vendor/symfony/service-contracts/Attribute/Required.php
new file mode 100644
index 0000000000..dd2106fbbe
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/service-contracts/Attribute/Required.php
@@ -0,0 +1,24 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Contracts\Service\Attribute;
+
+/**
+ * A required dependency.
+ *
+ * This attribute indicates that a property holds a required dependency. The annotated property or method should be
+ * considered during the instantiation process of the containing class.
+ *
+ * @author Alexander M. Turek
+ */
+trait ServiceLocatorTrait
+{
+ private $factories;
+ private $loading = [];
+ private $providedTypes;
+ /**
+ * @param callable[] $factories
+ */
+ public function __construct(array $factories)
+ {
+ $this->factories = $factories;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ public function has(string $id)
+ {
+ return isset($this->factories[$id]);
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return mixed
+ */
+ public function get(string $id)
+ {
+ if (!isset($this->factories[$id])) {
+ throw $this->createNotFoundException($id);
+ }
+ if (isset($this->loading[$id])) {
+ $ids = array_values($this->loading);
+ $ids = \array_slice($this->loading, array_search($id, $ids));
+ $ids[] = $id;
+ throw $this->createCircularReferenceException($id, $ids);
+ }
+ $this->loading[$id] = $id;
+ try {
+ return $this->factories[$id]($this);
+ } finally {
+ unset($this->loading[$id]);
+ }
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function getProvidedServices(): array
+ {
+ if (null === $this->providedTypes) {
+ $this->providedTypes = [];
+ foreach ($this->factories as $name => $factory) {
+ if (!\is_callable($factory)) {
+ $this->providedTypes[$name] = '?';
+ } else {
+ $type = (new \ReflectionFunction($factory))->getReturnType();
+ $this->providedTypes[$name] = $type ? ($type->allowsNull() ? '?' : '') . (($type instanceof \ReflectionNamedType) ? $type->getName() : $type) : '?';
+ }
+ }
+ }
+ return $this->providedTypes;
+ }
+ private function createNotFoundException(string $id): NotFoundExceptionInterface
+ {
+ if (!$alternatives = array_keys($this->factories)) {
+ $message = 'is empty...';
+ } else {
+ $last = array_pop($alternatives);
+ if ($alternatives) {
+ $message = sprintf('only knows about the "%s" and "%s" services.', implode('", "', $alternatives), $last);
+ } else {
+ $message = sprintf('only knows about the "%s" service.', $last);
+ }
+ }
+ if ($this->loading) {
+ $message = sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', end($this->loading), $id, $message);
+ } else {
+ $message = sprintf('Service "%s" not found: the current service locator %s', $id, $message);
+ }
+ return new class($message) extends \InvalidArgumentException implements NotFoundExceptionInterface
+ {
+ };
+ }
+ private function createCircularReferenceException(string $id, array $path): ContainerExceptionInterface
+ {
+ return new class(sprintf('Circular reference detected for service "%s", path: "%s".', $id, implode(' -> ', $path))) extends \RuntimeException implements ContainerExceptionInterface
+ {
+ };
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/service-contracts/ServiceProviderInterface.php b/src/modules/common/third-party/vendor/symfony/service-contracts/ServiceProviderInterface.php
new file mode 100644
index 0000000000..c85b765df3
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/service-contracts/ServiceProviderInterface.php
@@ -0,0 +1,34 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Contracts\Service;
+
+use Wordlift\Modules\Common\Psr\Container\ContainerInterface;
+/**
+ * A ServiceProviderInterface exposes the identifiers and the types of services provided by a container.
+ *
+ * @author Nicolas Grekas
+ * @author Mateusz Sip
+ */
+final class Instantiator
+{
+ /**
+ * Creates an object and sets its properties without calling its constructor nor any other methods.
+ *
+ * For example:
+ *
+ * // creates an empty instance of Foo
+ * Instantiator::instantiate(Foo::class);
+ *
+ * // creates a Foo instance and sets one of its properties
+ * Instantiator::instantiate(Foo::class, ['propertyName' => $propertyValue]);
+ *
+ * // creates a Foo instance and sets a private property defined on its parent Bar class
+ * Instantiator::instantiate(Foo::class, [], [
+ * Bar::class => ['privateBarProperty' => $propertyValue],
+ * ]);
+ *
+ * Instances of ArrayObject, ArrayIterator and SplObjectStorage can be created
+ * by using the special "\0" property name to define their internal value:
+ *
+ * // creates an SplObjectStorage where $info1 is attached to $obj1, etc.
+ * Instantiator::instantiate(SplObjectStorage::class, ["\0" => [$obj1, $info1, $obj2, $info2...]]);
+ *
+ * // creates an ArrayObject populated with $inputArray
+ * Instantiator::instantiate(ArrayObject::class, ["\0" => [$inputArray]]);
+ *
+ * @param string $class The class of the instance to create
+ * @param array $properties The properties to set on the instance
+ * @param array $privateProperties The private properties to set on the instance,
+ * keyed by their declaring class
+ *
+ * @throws ExceptionInterface When the instance cannot be created
+ */
+ public static function instantiate(string $class, array $properties = [], array $privateProperties = []): object
+ {
+ $reflector = Registry::$reflectors[$class] ?? Registry::getClassReflector($class);
+ if (Registry::$cloneable[$class]) {
+ $wrappedInstance = [clone Registry::$prototypes[$class]];
+ } elseif (Registry::$instantiableWithoutConstructor[$class]) {
+ $wrappedInstance = [$reflector->newInstanceWithoutConstructor()];
+ } elseif (null === Registry::$prototypes[$class]) {
+ throw new NotInstantiableTypeException($class);
+ } elseif ($reflector->implementsInterface('Serializable') && (\PHP_VERSION_ID < 70400 || !method_exists($class, '__unserialize'))) {
+ $wrappedInstance = [unserialize('C:' . \strlen($class) . ':"' . $class . '":0:{}')];
+ } else {
+ $wrappedInstance = [unserialize('O:' . \strlen($class) . ':"' . $class . '":0:{}')];
+ }
+ if ($properties) {
+ $privateProperties[$class] = isset($privateProperties[$class]) ? $properties + $privateProperties[$class] : $properties;
+ }
+ foreach ($privateProperties as $class => $properties) {
+ if (!$properties) {
+ continue;
+ }
+ foreach ($properties as $name => $value) {
+ // because they're also used for "unserialization", hydrators
+ // deal with array of instances, so we need to wrap values
+ $properties[$name] = [$value];
+ }
+ (Hydrator::$hydrators[$class] ?? Hydrator::getHydrator($class))($properties, $wrappedInstance);
+ }
+ return $wrappedInstance[0];
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/var-exporter/Internal/Exporter.php b/src/modules/common/third-party/vendor/symfony/var-exporter/Internal/Exporter.php
new file mode 100644
index 0000000000..5f479cbdae
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/var-exporter/Internal/Exporter.php
@@ -0,0 +1,358 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\VarExporter\Internal;
+
+use Wordlift\Modules\Common\Symfony\Component\VarExporter\Exception\NotInstantiableTypeException;
+/**
+ * @author Nicolas Grekas
+ *
+ * @internal
+ */
+class Exporter
+{
+ /**
+ * Prepares an array of values for VarExporter.
+ *
+ * For performance this method is public and has no type-hints.
+ *
+ * @param array &$values
+ * @param \SplObjectStorage $objectsPool
+ * @param array &$refsPool
+ * @param int &$objectsCount
+ * @param bool &$valuesAreStatic
+ *
+ * @throws NotInstantiableTypeException When a value cannot be serialized
+ */
+ public static function prepare($values, $objectsPool, &$refsPool, &$objectsCount, &$valuesAreStatic): array
+ {
+ $refs = $values;
+ foreach ($values as $k => $value) {
+ if (\is_resource($value)) {
+ throw new NotInstantiableTypeException(get_resource_type($value) . ' resource');
+ }
+ $refs[$k] = $objectsPool;
+ if ($isRef = !$valueIsStatic = $values[$k] !== $objectsPool) {
+ $values[$k] =& $value;
+ // Break hard references to make $values completely
+ unset($value);
+ // independent from the original structure
+ $refs[$k] = $value = $values[$k];
+ if ($value instanceof Reference && 0 > $value->id) {
+ $valuesAreStatic = \false;
+ ++$value->count;
+ continue;
+ }
+ $refsPool[] = [&$refs[$k], $value, &$value];
+ $refs[$k] = $values[$k] = new Reference(-\count($refsPool), $value);
+ }
+ if (\is_array($value)) {
+ if ($value) {
+ $value = self::prepare($value, $objectsPool, $refsPool, $objectsCount, $valueIsStatic);
+ }
+ goto handle_value;
+ } elseif (!\is_object($value) || $value instanceof \UnitEnum) {
+ goto handle_value;
+ }
+ $valueIsStatic = \false;
+ if (isset($objectsPool[$value])) {
+ ++$objectsCount;
+ $value = new Reference($objectsPool[$value][0]);
+ goto handle_value;
+ }
+ $class = \get_class($value);
+ $reflector = Registry::$reflectors[$class] ?? Registry::getClassReflector($class);
+ $properties = [];
+ if ($reflector->hasMethod('__serialize')) {
+ if (!$reflector->getMethod('__serialize')->isPublic()) {
+ throw new \Error(sprintf('Call to %s method "%s::__serialize()".', $reflector->getMethod('__serialize')->isProtected() ? 'protected' : 'private', $class));
+ }
+ if (!\is_array($serializeProperties = $value->__serialize())) {
+ throw new \TypeError($class . '::__serialize() must return an array');
+ }
+ if ($reflector->hasMethod('__unserialize')) {
+ $properties = $serializeProperties;
+ } else {
+ foreach ($serializeProperties as $n => $v) {
+ $c = (\PHP_VERSION_ID >= 80100 && $reflector->hasProperty($n) && ($p = $reflector->getProperty($n))->isReadOnly()) ? $p->class : 'stdClass';
+ $properties[$c][$n] = $v;
+ }
+ }
+ goto prepare_value;
+ }
+ $sleep = null;
+ $proto = Registry::$prototypes[$class];
+ if (($value instanceof \ArrayIterator || $value instanceof \ArrayObject) && null !== $proto) {
+ // ArrayIterator and ArrayObject need special care because their "flags"
+ // option changes the behavior of the (array) casting operator.
+ [$arrayValue, $properties] = self::getArrayObjectProperties($value, $proto);
+ // populates Registry::$prototypes[$class] with a new instance
+ Registry::getClassReflector($class, Registry::$instantiableWithoutConstructor[$class], Registry::$cloneable[$class]);
+ } elseif ($value instanceof \SplObjectStorage && Registry::$cloneable[$class] && null !== $proto) {
+ // By implementing Serializable, SplObjectStorage breaks
+ // internal references; let's deal with it on our own.
+ foreach (clone $value as $v) {
+ $properties[] = $v;
+ $properties[] = $value[$v];
+ }
+ $properties = ['SplObjectStorage' => ["\x00" => $properties]];
+ $arrayValue = (array) $value;
+ } elseif ($value instanceof \Serializable || $value instanceof \__PHP_Incomplete_Class || \PHP_VERSION_ID < 80200 && $value instanceof \DatePeriod) {
+ ++$objectsCount;
+ $objectsPool[$value] = [$id = \count($objectsPool), serialize($value), [], 0];
+ $value = new Reference($id);
+ goto handle_value;
+ } else {
+ if (method_exists($class, '__sleep')) {
+ if (!\is_array($sleep = $value->__sleep())) {
+ trigger_error('serialize(): __sleep should return an array only containing the names of instance-variables to serialize', \E_USER_NOTICE);
+ $value = null;
+ goto handle_value;
+ }
+ $sleep = array_flip($sleep);
+ }
+ $arrayValue = (array) $value;
+ }
+ $proto = (array) $proto;
+ foreach ($arrayValue as $name => $v) {
+ $i = 0;
+ $n = (string) $name;
+ if ('' === $n || "\x00" !== $n[0]) {
+ $c = (\PHP_VERSION_ID >= 80100 && $reflector->hasProperty($n) && ($p = $reflector->getProperty($n))->isReadOnly()) ? $p->class : 'stdClass';
+ } elseif ('*' === $n[1]) {
+ $n = substr($n, 3);
+ $c = $reflector->getProperty($n)->class;
+ if ('Error' === $c) {
+ $c = 'TypeError';
+ } elseif ('Exception' === $c) {
+ $c = 'ErrorException';
+ }
+ } else {
+ $i = strpos($n, "\x00", 2);
+ $c = substr($n, 1, $i - 1);
+ $n = substr($n, 1 + $i);
+ }
+ if (null !== $sleep) {
+ if (!isset($sleep[$name]) && (!isset($sleep[$n]) || $i && $c !== $class)) {
+ unset($arrayValue[$name]);
+ continue;
+ }
+ unset($sleep[$name], $sleep[$n]);
+ }
+ if (!\array_key_exists($name, $proto) || $proto[$name] !== $v || "\x00Error\x00trace" === $name || "\x00Exception\x00trace" === $name) {
+ $properties[$c][$n] = $v;
+ }
+ }
+ if ($sleep) {
+ foreach ($sleep as $n => $v) {
+ trigger_error(sprintf('serialize(): "%s" returned as member variable from __sleep() but does not exist', $n), \E_USER_NOTICE);
+ }
+ }
+ if (method_exists($class, '__unserialize')) {
+ $properties = $arrayValue;
+ }
+ prepare_value:
+ $objectsPool[$value] = [$id = \count($objectsPool)];
+ $properties = self::prepare($properties, $objectsPool, $refsPool, $objectsCount, $valueIsStatic);
+ ++$objectsCount;
+ $objectsPool[$value] = [$id, $class, $properties, method_exists($class, '__unserialize') ? -$objectsCount : (method_exists($class, '__wakeup') ? $objectsCount : 0)];
+ $value = new Reference($id);
+ handle_value:
+ if ($isRef) {
+ unset($value);
+ // Break the hard reference created above
+ } elseif (!$valueIsStatic) {
+ $values[$k] = $value;
+ }
+ $valuesAreStatic = $valueIsStatic && $valuesAreStatic;
+ }
+ return $values;
+ }
+ public static function export($value, string $indent = '')
+ {
+ switch (\true) {
+ case \is_int($value) || \is_float($value):
+ return var_export($value, \true);
+ case [] === $value:
+ return '[]';
+ case \false === $value:
+ return 'false';
+ case \true === $value:
+ return 'true';
+ case null === $value:
+ return 'null';
+ case '' === $value:
+ return "''";
+ case $value instanceof \UnitEnum:
+ return '\\' . ltrim(var_export($value, \true), '\\');
+ }
+ if ($value instanceof Reference) {
+ if (0 <= $value->id) {
+ return '$o[' . $value->id . ']';
+ }
+ if (!$value->count) {
+ return self::export($value->value, $indent);
+ }
+ $value = -$value->id;
+ return '&$r[' . $value . ']';
+ }
+ $subIndent = $indent . ' ';
+ if (\is_string($value)) {
+ $code = sprintf("'%s'", addcslashes($value, "'\\"));
+ $code = preg_replace_callback("/((?:[\\0\\r\\n]|||||||||)++)(.)/", function ($m) use ($subIndent) {
+ $m[1] = sprintf('\'."%s".\'', str_replace(["\x00", "\r", "\n", "", "", "", "", "", "", "", "", "", '\n\\'], ['\0', '\r', '\n', '\u{202A}', '\u{202B}', '\u{202D}', '\u{202E}', '\u{2066}', '\u{2067}', '\u{2068}', '\u{202C}', '\u{2069}', '\n"' . "\n" . $subIndent . '."\\'], $m[1]));
+ if ("'" === $m[2]) {
+ return substr($m[1], 0, -2);
+ }
+ if ('n".\'' === substr($m[1], -4)) {
+ return substr_replace($m[1], "\n" . $subIndent . ".'" . $m[2], -2);
+ }
+ return $m[1] . $m[2];
+ }, $code, -1, $count);
+ if ($count && str_starts_with($code, "''.")) {
+ $code = substr($code, 3);
+ }
+ return $code;
+ }
+ if (\is_array($value)) {
+ $j = -1;
+ $code = '';
+ foreach ($value as $k => $v) {
+ $code .= $subIndent;
+ if (!\is_int($k) || 1 !== $k - $j) {
+ $code .= self::export($k, $subIndent) . ' => ';
+ }
+ if (\is_int($k) && $k > $j) {
+ $j = $k;
+ }
+ $code .= self::export($v, $subIndent) . ",\n";
+ }
+ return "[\n" . $code . $indent . ']';
+ }
+ if ($value instanceof Values) {
+ $code = $subIndent . "\$r = [],\n";
+ foreach ($value->values as $k => $v) {
+ $code .= $subIndent . '$r[' . $k . '] = ' . self::export($v, $subIndent) . ",\n";
+ }
+ return "[\n" . $code . $indent . ']';
+ }
+ if ($value instanceof Registry) {
+ return self::exportRegistry($value, $indent, $subIndent);
+ }
+ if ($value instanceof Hydrator) {
+ return self::exportHydrator($value, $indent, $subIndent);
+ }
+ throw new \UnexpectedValueException(sprintf('Cannot export value of type "%s".', get_debug_type($value)));
+ }
+ private static function exportRegistry(Registry $value, string $indent, string $subIndent): string
+ {
+ $code = '';
+ $serializables = [];
+ $seen = [];
+ $prototypesAccess = 0;
+ $factoriesAccess = 0;
+ $r = '\\' . Registry::class;
+ $j = -1;
+ foreach ($value->classes as $k => $class) {
+ if (':' === ($class[1] ?? null)) {
+ $serializables[$k] = $class;
+ continue;
+ }
+ if (!Registry::$instantiableWithoutConstructor[$class]) {
+ if (is_subclass_of($class, 'Serializable') && !method_exists($class, '__unserialize')) {
+ $serializables[$k] = 'C:' . \strlen($class) . ':"' . $class . '":0:{}';
+ } else {
+ $serializables[$k] = 'O:' . \strlen($class) . ':"' . $class . '":0:{}';
+ }
+ if (is_subclass_of($class, 'Throwable')) {
+ $eol = is_subclass_of($class, 'Error') ? "\x00Error\x00" : "\x00Exception\x00";
+ $serializables[$k] = substr_replace($serializables[$k], '1:{s:' . (5 + \strlen($eol)) . ':"' . $eol . 'trace";a:0:{}}', -4);
+ }
+ continue;
+ }
+ $code .= $subIndent . ((1 !== $k - $j) ? $k . ' => ' : '');
+ $j = $k;
+ $eol = ",\n";
+ $c = '[' . self::export($class) . ']';
+ if ($seen[$class] ?? \false) {
+ if (Registry::$cloneable[$class]) {
+ ++$prototypesAccess;
+ $code .= 'clone $p' . $c;
+ } else {
+ ++$factoriesAccess;
+ $code .= '$f' . $c . '()';
+ }
+ } else {
+ $seen[$class] = \true;
+ if (Registry::$cloneable[$class]) {
+ $code .= 'clone (' . ($prototypesAccess++ ? '$p' : ('($p = &' . $r . '::$prototypes)')) . $c . ' ?? ' . $r . '::p';
+ } else {
+ $code .= '(' . ($factoriesAccess++ ? '$f' : ('($f = &' . $r . '::$factories)')) . $c . ' ?? ' . $r . '::f';
+ $eol = '()' . $eol;
+ }
+ $code .= '(' . substr($c, 1, -1) . '))';
+ }
+ $code .= $eol;
+ }
+ if (1 === $prototypesAccess) {
+ $code = str_replace('($p = &' . $r . '::$prototypes)', $r . '::$prototypes', $code);
+ }
+ if (1 === $factoriesAccess) {
+ $code = str_replace('($f = &' . $r . '::$factories)', $r . '::$factories', $code);
+ }
+ if ('' !== $code) {
+ $code = "\n" . $code . $indent;
+ }
+ if ($serializables) {
+ $code = $r . '::unserialize([' . $code . '], ' . self::export($serializables, $indent) . ')';
+ } else {
+ $code = '[' . $code . ']';
+ }
+ return '$o = ' . $code;
+ }
+ private static function exportHydrator(Hydrator $value, string $indent, string $subIndent): string
+ {
+ $code = '';
+ foreach ($value->properties as $class => $properties) {
+ $code .= $subIndent . ' ' . self::export($class) . ' => ' . self::export($properties, $subIndent . ' ') . ",\n";
+ }
+ $code = [self::export($value->registry, $subIndent), self::export($value->values, $subIndent), ('' !== $code) ? "[\n" . $code . $subIndent . ']' : '[]', self::export($value->value, $subIndent), self::export($value->wakeups, $subIndent)];
+ return '\\' . \get_class($value) . "::hydrate(\n" . $subIndent . implode(",\n" . $subIndent, $code) . "\n" . $indent . ')';
+ }
+ /**
+ * @param \ArrayIterator|\ArrayObject $value
+ * @param \ArrayIterator|\ArrayObject $proto
+ */
+ private static function getArrayObjectProperties($value, $proto): array
+ {
+ $reflector = ($value instanceof \ArrayIterator) ? 'ArrayIterator' : 'ArrayObject';
+ $reflector = Registry::$reflectors[$reflector] ?? Registry::getClassReflector($reflector);
+ $properties = [$arrayValue = (array) $value, $reflector->getMethod('getFlags')->invoke($value), ($value instanceof \ArrayObject) ? $reflector->getMethod('getIteratorClass')->invoke($value) : 'ArrayIterator'];
+ $reflector = $reflector->getMethod('setFlags');
+ $reflector->invoke($proto, \ArrayObject::STD_PROP_LIST);
+ if ($properties[1] & \ArrayObject::STD_PROP_LIST) {
+ $reflector->invoke($value, 0);
+ $properties[0] = (array) $value;
+ } else {
+ $reflector->invoke($value, \ArrayObject::STD_PROP_LIST);
+ $arrayValue = (array) $value;
+ }
+ $reflector->invoke($value, $properties[1]);
+ if ([[], 0, 'ArrayIterator'] === $properties) {
+ $properties = [];
+ } else {
+ if ('ArrayIterator' === $properties[2]) {
+ unset($properties[2]);
+ }
+ $properties = [$reflector->class => ["\x00" => $properties]];
+ }
+ return [$arrayValue, $properties];
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/var-exporter/Internal/Hydrator.php b/src/modules/common/third-party/vendor/symfony/var-exporter/Internal/Hydrator.php
new file mode 100644
index 0000000000..c2db114a73
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/var-exporter/Internal/Hydrator.php
@@ -0,0 +1,136 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\VarExporter\Internal;
+
+use Wordlift\Modules\Common\Symfony\Component\VarExporter\Exception\ClassNotFoundException;
+/**
+ * @author Nicolas Grekas
+ *
+ * @internal
+ */
+class Hydrator
+{
+ public static $hydrators = [];
+ public $registry;
+ public $values;
+ public $properties;
+ public $value;
+ public $wakeups;
+ public function __construct(?Registry $registry, ?Values $values, array $properties, $value, array $wakeups)
+ {
+ $this->registry = $registry;
+ $this->values = $values;
+ $this->properties = $properties;
+ $this->value = $value;
+ $this->wakeups = $wakeups;
+ }
+ public static function hydrate($objects, $values, $properties, $value, $wakeups)
+ {
+ foreach ($properties as $class => $vars) {
+ (self::$hydrators[$class] ?? self::getHydrator($class))($vars, $objects);
+ }
+ foreach ($wakeups as $k => $v) {
+ if (\is_array($v)) {
+ $objects[-$k]->__unserialize($v);
+ } else {
+ $objects[$v]->__wakeup();
+ }
+ }
+ return $value;
+ }
+ public static function getHydrator($class)
+ {
+ switch ($class) {
+ case 'stdClass':
+ return self::$hydrators[$class] = static function ($properties, $objects) {
+ foreach ($properties as $name => $values) {
+ foreach ($values as $i => $v) {
+ $objects[$i]->{$name} = $v;
+ }
+ }
+ };
+ case 'ErrorException':
+ return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null, new class extends \ErrorException
+ {
+ });
+ case 'TypeError':
+ return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null, new class extends \Error
+ {
+ });
+ case 'SplObjectStorage':
+ return self::$hydrators[$class] = static function ($properties, $objects) {
+ foreach ($properties as $name => $values) {
+ if ("\x00" === $name) {
+ foreach ($values as $i => $v) {
+ for ($j = 0; $j < \count($v); ++$j) {
+ $objects[$i]->attach($v[$j], $v[++$j]);
+ }
+ }
+ continue;
+ }
+ foreach ($values as $i => $v) {
+ $objects[$i]->{$name} = $v;
+ }
+ }
+ };
+ }
+ if (!class_exists($class) && !interface_exists($class, \false) && !trait_exists($class, \false)) {
+ throw new ClassNotFoundException($class);
+ }
+ $classReflector = new \ReflectionClass($class);
+ switch ($class) {
+ case 'ArrayIterator':
+ case 'ArrayObject':
+ $constructor = \Closure::fromCallable([$classReflector->getConstructor(), 'invokeArgs']);
+ return self::$hydrators[$class] = static function ($properties, $objects) use ($constructor) {
+ foreach ($properties as $name => $values) {
+ if ("\x00" !== $name) {
+ foreach ($values as $i => $v) {
+ $objects[$i]->{$name} = $v;
+ }
+ }
+ }
+ foreach ($properties["\x00"] ?? [] as $i => $v) {
+ $constructor($objects[$i], $v);
+ }
+ };
+ }
+ if (!$classReflector->isInternal()) {
+ return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null, $class);
+ }
+ if ($classReflector->name !== $class) {
+ return self::$hydrators[$classReflector->name] ?? self::getHydrator($classReflector->name);
+ }
+ $propertySetters = [];
+ foreach ($classReflector->getProperties() as $propertyReflector) {
+ if (!$propertyReflector->isStatic()) {
+ $propertyReflector->setAccessible(\true);
+ $propertySetters[$propertyReflector->name] = \Closure::fromCallable([$propertyReflector, 'setValue']);
+ }
+ }
+ if (!$propertySetters) {
+ return self::$hydrators[$class] = self::$hydrators['stdClass'] ?? self::getHydrator('stdClass');
+ }
+ return self::$hydrators[$class] = static function ($properties, $objects) use ($propertySetters) {
+ foreach ($properties as $name => $values) {
+ if ($setValue = $propertySetters[$name] ?? null) {
+ foreach ($values as $i => $v) {
+ $setValue($objects[$i], $v);
+ }
+ continue;
+ }
+ foreach ($values as $i => $v) {
+ $objects[$i]->{$name} = $v;
+ }
+ }
+ };
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/var-exporter/Internal/Reference.php b/src/modules/common/third-party/vendor/symfony/var-exporter/Internal/Reference.php
new file mode 100644
index 0000000000..c64d0131a9
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/var-exporter/Internal/Reference.php
@@ -0,0 +1,28 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\VarExporter\Internal;
+
+/**
+ * @author Nicolas Grekas
+ *
+ * @internal
+ */
+class Reference
+{
+ public $id;
+ public $value;
+ public $count = 0;
+ public function __construct(int $id, $value = null)
+ {
+ $this->id = $id;
+ $this->value = $value;
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/var-exporter/Internal/Registry.php b/src/modules/common/third-party/vendor/symfony/var-exporter/Internal/Registry.php
new file mode 100644
index 0000000000..8d83f8916d
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/var-exporter/Internal/Registry.php
@@ -0,0 +1,122 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\VarExporter\Internal;
+
+use Wordlift\Modules\Common\Symfony\Component\VarExporter\Exception\ClassNotFoundException;
+use Wordlift\Modules\Common\Symfony\Component\VarExporter\Exception\NotInstantiableTypeException;
+/**
+ * @author Nicolas Grekas
+ *
+ * @internal
+ */
+class Registry
+{
+ public static $reflectors = [];
+ public static $prototypes = [];
+ public static $factories = [];
+ public static $cloneable = [];
+ public static $instantiableWithoutConstructor = [];
+ public $classes = [];
+ public function __construct(array $classes)
+ {
+ $this->classes = $classes;
+ }
+ public static function unserialize($objects, $serializables)
+ {
+ $unserializeCallback = ini_set('unserialize_callback_func', __CLASS__ . '::getClassReflector');
+ try {
+ foreach ($serializables as $k => $v) {
+ $objects[$k] = unserialize($v);
+ }
+ } finally {
+ ini_set('unserialize_callback_func', $unserializeCallback);
+ }
+ return $objects;
+ }
+ public static function p($class)
+ {
+ self::getClassReflector($class, \true, \true);
+ return self::$prototypes[$class];
+ }
+ public static function f($class)
+ {
+ $reflector = self::$reflectors[$class] ?? self::getClassReflector($class, \true, \false);
+ return self::$factories[$class] = \Closure::fromCallable([$reflector, 'newInstanceWithoutConstructor']);
+ }
+ public static function getClassReflector($class, $instantiableWithoutConstructor = \false, $cloneable = null)
+ {
+ if (!($isClass = class_exists($class)) && !interface_exists($class, \false) && !trait_exists($class, \false)) {
+ throw new ClassNotFoundException($class);
+ }
+ $reflector = new \ReflectionClass($class);
+ if ($instantiableWithoutConstructor) {
+ $proto = $reflector->newInstanceWithoutConstructor();
+ } elseif (!$isClass || $reflector->isAbstract()) {
+ throw new NotInstantiableTypeException($class);
+ } elseif ($reflector->name !== $class) {
+ $reflector = self::$reflectors[$name = $reflector->name] ?? self::getClassReflector($name, \false, $cloneable);
+ self::$cloneable[$class] = self::$cloneable[$name];
+ self::$instantiableWithoutConstructor[$class] = self::$instantiableWithoutConstructor[$name];
+ self::$prototypes[$class] = self::$prototypes[$name];
+ return self::$reflectors[$class] = $reflector;
+ } else {
+ try {
+ $proto = $reflector->newInstanceWithoutConstructor();
+ $instantiableWithoutConstructor = \true;
+ } catch (\ReflectionException $e) {
+ $proto = ($reflector->implementsInterface('Serializable') && !method_exists($class, '__unserialize')) ? 'C:' : 'O:';
+ if ('C:' === $proto && !$reflector->getMethod('unserialize')->isInternal()) {
+ $proto = null;
+ } else {
+ try {
+ $proto = @unserialize($proto . \strlen($class) . ':"' . $class . '":0:{}');
+ } catch (\Exception $e) {
+ if (__FILE__ !== $e->getFile()) {
+ throw $e;
+ }
+ throw new NotInstantiableTypeException($class, $e);
+ }
+ if (\false === $proto) {
+ throw new NotInstantiableTypeException($class);
+ }
+ }
+ }
+ if (null !== $proto && !$proto instanceof \Throwable && !$proto instanceof \Serializable && !method_exists($class, '__sleep') && (\PHP_VERSION_ID < 70400 || !method_exists($class, '__serialize'))) {
+ try {
+ serialize($proto);
+ } catch (\Exception $e) {
+ throw new NotInstantiableTypeException($class, $e);
+ }
+ }
+ }
+ if (null === $cloneable) {
+ if (($proto instanceof \Reflector || $proto instanceof \ReflectionGenerator || $proto instanceof \ReflectionType || $proto instanceof \IteratorIterator || $proto instanceof \RecursiveIteratorIterator) && (!$proto instanceof \Serializable && !method_exists($proto, '__wakeup') && (\PHP_VERSION_ID < 70400 || !method_exists($class, '__unserialize')))) {
+ throw new NotInstantiableTypeException($class);
+ }
+ $cloneable = $reflector->isCloneable() && !$reflector->hasMethod('__clone');
+ }
+ self::$cloneable[$class] = $cloneable;
+ self::$instantiableWithoutConstructor[$class] = $instantiableWithoutConstructor;
+ self::$prototypes[$class] = $proto;
+ if ($proto instanceof \Throwable) {
+ static $setTrace;
+ if (null === $setTrace) {
+ $setTrace = [new \ReflectionProperty(\Error::class, 'trace'), new \ReflectionProperty(\Exception::class, 'trace')];
+ $setTrace[0]->setAccessible(\true);
+ $setTrace[1]->setAccessible(\true);
+ $setTrace[0] = \Closure::fromCallable([$setTrace[0], 'setValue']);
+ $setTrace[1] = \Closure::fromCallable([$setTrace[1], 'setValue']);
+ }
+ $setTrace[$proto instanceof \Exception]($proto, []);
+ }
+ return self::$reflectors[$class] = $reflector;
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/var-exporter/Internal/Values.php b/src/modules/common/third-party/vendor/symfony/var-exporter/Internal/Values.php
new file mode 100644
index 0000000000..973ce2d03f
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/var-exporter/Internal/Values.php
@@ -0,0 +1,25 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\VarExporter\Internal;
+
+/**
+ * @author Nicolas Grekas
+ *
+ * @internal
+ */
+class Values
+{
+ public $values;
+ public function __construct(array $values)
+ {
+ $this->values = $values;
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/var-exporter/VarExporter.php b/src/modules/common/third-party/vendor/symfony/var-exporter/VarExporter.php
new file mode 100644
index 0000000000..94eb37613c
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/var-exporter/VarExporter.php
@@ -0,0 +1,102 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Wordlift\Modules\Common\Symfony\Component\VarExporter;
+
+use Wordlift\Modules\Common\Symfony\Component\VarExporter\Exception\ExceptionInterface;
+use Wordlift\Modules\Common\Symfony\Component\VarExporter\Internal\Exporter;
+use Wordlift\Modules\Common\Symfony\Component\VarExporter\Internal\Hydrator;
+use Wordlift\Modules\Common\Symfony\Component\VarExporter\Internal\Registry;
+use Wordlift\Modules\Common\Symfony\Component\VarExporter\Internal\Values;
+/**
+ * Exports serializable PHP values to PHP code.
+ *
+ * VarExporter allows serializing PHP data structures to plain PHP code (like var_export())
+ * while preserving all the semantics associated with serialize() (unlike var_export()).
+ *
+ * By leveraging OPcache, the generated PHP code is faster than doing the same with unserialize().
+ *
+ * @author Nicolas Grekas
+ */
+final class VarExporter
+{
+ /**
+ * Exports a serializable PHP value to PHP code.
+ *
+ * @param mixed $value The value to export
+ * @param bool &$isStaticValue Set to true after execution if the provided value is static, false otherwise
+ * @param array &$foundClasses Classes found in the value are added to this list as both keys and values
+ *
+ * @throws ExceptionInterface When the provided value cannot be serialized
+ */
+ public static function export($value, ?bool &$isStaticValue = null, array &$foundClasses = []): string
+ {
+ $isStaticValue = \true;
+ if (!\is_object($value) && !(\is_array($value) && $value) && !\is_resource($value) || $value instanceof \UnitEnum) {
+ return Exporter::export($value);
+ }
+ $objectsPool = new \SplObjectStorage();
+ $refsPool = [];
+ $objectsCount = 0;
+ try {
+ $value = Exporter::prepare([$value], $objectsPool, $refsPool, $objectsCount, $isStaticValue)[0];
+ } finally {
+ $references = [];
+ foreach ($refsPool as $i => $v) {
+ if ($v[0]->count) {
+ $references[1 + $i] = $v[2];
+ }
+ $v[0] = $v[1];
+ }
+ }
+ if ($isStaticValue) {
+ return Exporter::export($value);
+ }
+ $classes = [];
+ $values = [];
+ $states = [];
+ foreach ($objectsPool as $i => $v) {
+ [, $class, $values[], $wakeup] = $objectsPool[$v];
+ $foundClasses[$class] = $classes[] = $class;
+ if (0 < $wakeup) {
+ $states[$wakeup] = $i;
+ } elseif (0 > $wakeup) {
+ $states[-$wakeup] = [$i, array_pop($values)];
+ $values[] = [];
+ }
+ }
+ ksort($states);
+ $wakeups = [null];
+ foreach ($states as $v) {
+ if (\is_array($v)) {
+ $wakeups[-$v[0]] = $v[1];
+ } else {
+ $wakeups[] = $v;
+ }
+ }
+ if (null === $wakeups[0]) {
+ unset($wakeups[0]);
+ }
+ $properties = [];
+ foreach ($values as $i => $vars) {
+ foreach ($vars as $class => $values) {
+ foreach ($values as $name => $v) {
+ $properties[$class][$name][$i] = $v;
+ }
+ }
+ }
+ if ($classes || $references) {
+ $value = new Hydrator(new Registry($classes), $references ? new Values($references) : null, $properties, $value, $wakeups);
+ } else {
+ $isStaticValue = \true;
+ }
+ return Exporter::export($value);
+ }
+}
diff --git a/src/modules/common/third-party/vendor/symfony/var-exporter/composer.json b/src/modules/common/third-party/vendor/symfony/var-exporter/composer.json
new file mode 100644
index 0000000000..60cb40cb9c
--- /dev/null
+++ b/src/modules/common/third-party/vendor/symfony/var-exporter/composer.json
@@ -0,0 +1,41 @@
+{
+ "name": "symfony\/var-exporter",
+ "type": "library",
+ "description": "Allows exporting any serializable PHP data structure to plain PHP code",
+ "keywords": [
+ "export",
+ "serialize",
+ "instantiate",
+ "hydrate",
+ "construct",
+ "clone"
+ ],
+ "homepage": "https:\/\/symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https:\/\/symfony.com\/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=7.2.5",
+ "symfony\/polyfill-php80": "^1.16"
+ },
+ "require-dev": {
+ "symfony\/var-dumper": "^4.4.9|^5.0.9|^6.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Wordlift\\Modules\\Common\\Symfony\\Component\\VarExporter\\": ""
+ },
+ "exclude-from-classmap": [
+ "\/Tests\/"
+ ]
+ },
+ "minimum-stability": "dev"
+}
\ No newline at end of file
diff --git a/src/modules/common/third-party/vendor/symfony/yaml/Command/LintCommand.php b/src/modules/common/third-party/vendor/symfony/yaml/Command/LintCommand.php
index ac755b6fba..1a12ec5312 100644
--- a/src/modules/common/third-party/vendor/symfony/yaml/Command/LintCommand.php
+++ b/src/modules/common/third-party/vendor/symfony/yaml/Command/LintCommand.php
@@ -10,9 +10,13 @@
*/
namespace Wordlift\Modules\Common\Symfony\Component\Yaml\Command;
+use Wordlift\Modules\Common\Symfony\Component\Console\CI\GithubActionReporter;
use Wordlift\Modules\Common\Symfony\Component\Console\Command\Command;
+use Wordlift\Modules\Common\Symfony\Component\Console\Completion\CompletionInput;
+use Wordlift\Modules\Common\Symfony\Component\Console\Completion\CompletionSuggestions;
use Wordlift\Modules\Common\Symfony\Component\Console\Exception\InvalidArgumentException;
use Wordlift\Modules\Common\Symfony\Component\Console\Exception\RuntimeException;
+use Wordlift\Modules\Common\Symfony\Component\Console\Input\InputArgument;
use Wordlift\Modules\Common\Symfony\Component\Console\Input\InputInterface;
use Wordlift\Modules\Common\Symfony\Component\Console\Input\InputOption;
use Wordlift\Modules\Common\Symfony\Component\Console\Output\OutputInterface;
@@ -29,12 +33,13 @@
class LintCommand extends Command
{
protected static $defaultName = 'lint:yaml';
+ protected static $defaultDescription = 'Lint a YAML file and outputs encountered errors';
private $parser;
private $format;
private $displayCorrectFiles;
private $directoryIteratorProvider;
private $isReadableProvider;
- public function __construct($name = null, $directoryIteratorProvider = null, $isReadableProvider = null)
+ public function __construct(?string $name = null, ?callable $directoryIteratorProvider = null, ?callable $isReadableProvider = null)
{
parent::__construct($name);
$this->directoryIteratorProvider = $directoryIteratorProvider;
@@ -45,13 +50,13 @@ public function __construct($name = null, $directoryIteratorProvider = null, $is
*/
protected function configure()
{
- $this->setDescription('Lints a file and outputs encountered errors')->addArgument('filename', null, 'A file or a directory or STDIN')->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt')->addOption('parse-tags', null, InputOption::VALUE_NONE, 'Parse custom tags')->setHelp(<<