dvadf
File manager - Edit - /home/centroca/public_html/Action.tar
Back
Run_Command.php 0000644 00000011161 15253067654 0007474 0 ustar 00 <?php namespace Action_Scheduler\WP_CLI\Action; /** * WP-CLI command: action-scheduler action run */ class Run_Command extends \ActionScheduler_WPCLI_Command { /** * Array of action IDs to execute. * * @var int[] */ protected $action_ids = array(); /** * Number of executed, failed, ignored, invalid, and total actions. * * @var array<string, int> */ protected $action_counts = array( 'executed' => 0, 'failed' => 0, 'ignored' => 0, 'invalid' => 0, 'total' => 0, ); /** * Construct. * * @param string[] $args Positional arguments. * @param array<string, string> $assoc_args Keyed arguments. */ public function __construct( array $args, array $assoc_args ) { parent::__construct( $args, $assoc_args ); $this->action_ids = array_map( 'absint', $args ); $this->action_counts['total'] = count( $this->action_ids ); add_action( 'action_scheduler_execution_ignored', array( $this, 'on_action_ignored' ) ); add_action( 'action_scheduler_after_execute', array( $this, 'on_action_executed' ) ); add_action( 'action_scheduler_failed_execution', array( $this, 'on_action_failed' ), 10, 2 ); add_action( 'action_scheduler_failed_validation', array( $this, 'on_action_invalid' ), 10, 2 ); } /** * Execute. * * @return void */ public function execute() { $runner = \ActionScheduler::runner(); $progress_bar = \WP_CLI\Utils\make_progress_bar( sprintf( /* translators: %d: number of actions */ _n( 'Executing %d action', 'Executing %d actions', $this->action_counts['total'], 'action-scheduler' ), number_format_i18n( $this->action_counts['total'] ) ), $this->action_counts['total'] ); foreach ( $this->action_ids as $action_id ) { $runner->process_action( $action_id, 'Action Scheduler CLI' ); $progress_bar->tick(); } $progress_bar->finish(); foreach ( array( 'ignored', 'invalid', 'failed', ) as $type ) { $count = $this->action_counts[ $type ]; if ( empty( $count ) ) { continue; } /* * translators: * %1$d: count of actions evaluated. * %2$s: type of action evaluated. */ $format = _n( '%1$d action %2$s.', '%1$d actions %2$s.', $count, 'action-scheduler' ); \WP_CLI::warning( sprintf( $format, number_format_i18n( $count ), $type ) ); } \WP_CLI::success( sprintf( /* translators: %d: number of executed actions */ _n( 'Executed %d action.', 'Executed %d actions.', $this->action_counts['executed'], 'action-scheduler' ), number_format_i18n( $this->action_counts['executed'] ) ) ); } /** * Action: action_scheduler_execution_ignored * * @param int $action_id Action ID. * @return void */ public function on_action_ignored( $action_id ) { if ( 'action_scheduler_execution_ignored' !== current_action() ) { return; } $action_id = absint( $action_id ); if ( ! in_array( $action_id, $this->action_ids, true ) ) { return; } $this->action_counts['ignored']++; \WP_CLI::debug( sprintf( 'Action %d was ignored.', $action_id ) ); } /** * Action: action_scheduler_after_execute * * @param int $action_id Action ID. * @return void */ public function on_action_executed( $action_id ) { if ( 'action_scheduler_after_execute' !== current_action() ) { return; } $action_id = absint( $action_id ); if ( ! in_array( $action_id, $this->action_ids, true ) ) { return; } $this->action_counts['executed']++; \WP_CLI::debug( sprintf( 'Action %d was executed.', $action_id ) ); } /** * Action: action_scheduler_failed_execution * * @param int $action_id Action ID. * @param \Exception $e Exception. * @return void */ public function on_action_failed( $action_id, \Exception $e ) { if ( 'action_scheduler_failed_execution' !== current_action() ) { return; } $action_id = absint( $action_id ); if ( ! in_array( $action_id, $this->action_ids, true ) ) { return; } $this->action_counts['failed']++; \WP_CLI::debug( sprintf( 'Action %d failed execution: %s', $action_id, $e->getMessage() ) ); } /** * Action: action_scheduler_failed_validation * * @param int $action_id Action ID. * @param \Exception $e Exception. * @return void */ public function on_action_invalid( $action_id, \Exception $e ) { if ( 'action_scheduler_failed_validation' !== current_action() ) { return; } $action_id = absint( $action_id ); if ( ! in_array( $action_id, $this->action_ids, true ) ) { return; } $this->action_counts['invalid']++; \WP_CLI::debug( sprintf( 'Action %d failed validation: %s', $action_id, $e->getMessage() ) ); } } Generate_Command.php 0000644 00000006737 15253067654 0010477 0 ustar 00 <?php namespace Action_Scheduler\WP_CLI\Action; use function \WP_CLI\Utils\get_flag_value; /** * WP-CLI command: action-scheduler action generate */ class Generate_Command extends \ActionScheduler_WPCLI_Command { /** * Execute command. * * @return void */ public function execute() { $hook = $this->args[0]; $schedule_start = $this->args[1]; $callback_args = get_flag_value( $this->assoc_args, 'args', array() ); $group = get_flag_value( $this->assoc_args, 'group', '' ); $interval = (int) get_flag_value( $this->assoc_args, 'interval', 0 ); // avoid absint() to support negative intervals $count = absint( get_flag_value( $this->assoc_args, 'count', 1 ) ); if ( ! empty( $callback_args ) ) { $callback_args = json_decode( $callback_args, true ); } $schedule_start = as_get_datetime_object( $schedule_start ); $function_args = array( 'start' => absint( $schedule_start->format( 'U' ) ), 'interval' => $interval, 'count' => $count, 'hook' => $hook, 'callback_args' => $callback_args, 'group' => $group, ); $function_args = array_values( $function_args ); try { $actions_added = $this->generate( ...$function_args ); } catch ( \Exception $e ) { $this->print_error( $e ); } $num_actions_added = count( (array) $actions_added ); $this->print_success( $num_actions_added, 'single' ); } /** * Schedule multiple single actions. * * @param int $schedule_start Starting timestamp of first action. * @param int $interval How long to wait between runs. * @param int $count Limit number of actions to schedule. * @param string $hook The hook to trigger. * @param array $args Arguments to pass when the hook triggers. * @param string $group The group to assign this job to. * @return int[] IDs of actions added. */ protected function generate( $schedule_start, $interval, $count, $hook, array $args = array(), $group = '' ) { $actions_added = array(); $progress_bar = \WP_CLI\Utils\make_progress_bar( sprintf( /* translators: %d is number of actions to create */ _n( 'Creating %d action', 'Creating %d actions', $count, 'action-scheduler' ), number_format_i18n( $count ) ), $count ); for ( $i = 0; $i < $count; $i++ ) { $actions_added[] = as_schedule_single_action( $schedule_start + ( $i * $interval ), $hook, $args, $group ); $progress_bar->tick(); } $progress_bar->finish(); return $actions_added; } /** * Print a success message with the action ID. * * @param int $actions_added Number of actions generated. * @param string $action_type Type of actions scheduled. * @return void */ protected function print_success( $actions_added, $action_type ) { \WP_CLI::success( sprintf( /* translators: %1$d refers to the total number of tasks added, %2$s is the action type */ _n( '%1$d %2$s action scheduled.', '%1$d %2$s actions scheduled.', $actions_added, 'action-scheduler' ), number_format_i18n( $actions_added ), $action_type ) ); } /** * Convert an exception into a WP CLI error. * * @param \Exception $e The error object. * @throws \WP_CLI\ExitException When an error occurs. * @return void */ protected function print_error( \Exception $e ) { \WP_CLI::error( sprintf( /* translators: %s refers to the exception error message. */ __( 'There was an error creating the scheduled action: %s', 'action-scheduler' ), $e->getMessage() ) ); } } Delete_Command.php 0000644 00000005145 15253067654 0010137 0 ustar 00 <?php namespace Action_Scheduler\WP_CLI\Action; /** * WP-CLI command: action-scheduler action delete */ class Delete_Command extends \ActionScheduler_WPCLI_Command { /** * Array of action IDs to delete. * * @var int[] */ protected $action_ids = array(); /** * Number of deleted, failed, and total actions deleted. * * @var array<string, int> */ protected $action_counts = array( 'deleted' => 0, 'failed' => 0, 'total' => 0, ); /** * Construct. * * @param string[] $args Positional arguments. * @param array<string, string> $assoc_args Keyed arguments. */ public function __construct( array $args, array $assoc_args ) { parent::__construct( $args, $assoc_args ); $this->action_ids = array_map( 'absint', $args ); $this->action_counts['total'] = count( $this->action_ids ); add_action( 'action_scheduler_deleted_action', array( $this, 'on_action_deleted' ) ); } /** * Execute. * * @return void */ public function execute() { $store = \ActionScheduler::store(); $progress_bar = \WP_CLI\Utils\make_progress_bar( sprintf( /* translators: %d: number of actions to be deleted */ _n( 'Deleting %d action', 'Deleting %d actions', $this->action_counts['total'], 'action-scheduler' ), number_format_i18n( $this->action_counts['total'] ) ), $this->action_counts['total'] ); foreach ( $this->action_ids as $action_id ) { try { $store->delete_action( $action_id ); } catch ( \Exception $e ) { $this->action_counts['failed']++; \WP_CLI::warning( $e->getMessage() ); } $progress_bar->tick(); } $progress_bar->finish(); /* translators: %1$d: number of actions deleted */ $format = _n( 'Deleted %1$d action', 'Deleted %1$d actions', $this->action_counts['deleted'], 'action-scheduler' ) . ', '; /* translators: %2$d: number of actions deletions failed */ $format .= _n( '%2$d failure.', '%2$d failures.', $this->action_counts['failed'], 'action-scheduler' ); \WP_CLI::success( sprintf( $format, number_format_i18n( $this->action_counts['deleted'] ), number_format_i18n( $this->action_counts['failed'] ) ) ); } /** * Action: action_scheduler_deleted_action * * @param int $action_id Action ID. * @return void */ public function on_action_deleted( $action_id ) { if ( 'action_scheduler_deleted_action' !== current_action() ) { return; } $action_id = absint( $action_id ); if ( ! in_array( $action_id, $this->action_ids, true ) ) { return; } $this->action_counts['deleted']++; \WP_CLI::debug( sprintf( 'Action %d was deleted.', $action_id ) ); } } Create_Command.php 0000644 00000010552 15253067654 0010136 0 ustar 00 <?php namespace Action_Scheduler\WP_CLI\Action; use function \WP_CLI\Utils\get_flag_value; /** * WP-CLI command: action-scheduler action create */ class Create_Command extends \ActionScheduler_WPCLI_Command { const ASYNC_OPTS = array( 'async', 0 ); /** * Execute command. * * @return void */ public function execute() { $hook = $this->args[0]; $schedule_start = $this->args[1]; $callback_args = get_flag_value( $this->assoc_args, 'args', array() ); $group = get_flag_value( $this->assoc_args, 'group', '' ); $interval = absint( get_flag_value( $this->assoc_args, 'interval', 0 ) ); $cron = get_flag_value( $this->assoc_args, 'cron', '' ); $unique = get_flag_value( $this->assoc_args, 'unique', false ); $priority = absint( get_flag_value( $this->assoc_args, 'priority', 10 ) ); if ( ! empty( $callback_args ) ) { $callback_args = json_decode( $callback_args, true ); } $function_args = array( 'start' => $schedule_start, 'cron' => $cron, 'interval' => $interval, 'hook' => $hook, 'callback_args' => $callback_args, 'group' => $group, 'unique' => $unique, 'priority' => $priority, ); try { // Generate schedule start if appropriate. if ( ! in_array( $schedule_start, static::ASYNC_OPTS, true ) ) { $schedule_start = as_get_datetime_object( $schedule_start ); $function_args['start'] = $schedule_start->format( 'U' ); } } catch ( \Exception $e ) { \WP_CLI::error( $e->getMessage() ); } // Default to creating single action. $action_type = 'single'; $function = 'as_schedule_single_action'; if ( ! empty( $interval ) ) { // Creating recurring action. $action_type = 'recurring'; $function = 'as_schedule_recurring_action'; $function_args = array_filter( $function_args, static function( $key ) { return in_array( $key, array( 'start', 'interval', 'hook', 'callback_args', 'group', 'unique', 'priority' ), true ); }, ARRAY_FILTER_USE_KEY ); } elseif ( ! empty( $cron ) ) { // Creating cron action. $action_type = 'cron'; $function = 'as_schedule_cron_action'; $function_args = array_filter( $function_args, static function( $key ) { return in_array( $key, array( 'start', 'cron', 'hook', 'callback_args', 'group', 'unique', 'priority' ), true ); }, ARRAY_FILTER_USE_KEY ); } elseif ( in_array( $function_args['start'], static::ASYNC_OPTS, true ) ) { // Enqueue async action. $action_type = 'async'; $function = 'as_enqueue_async_action'; $function_args = array_filter( $function_args, static function( $key ) { return in_array( $key, array( 'hook', 'callback_args', 'group', 'unique', 'priority' ), true ); }, ARRAY_FILTER_USE_KEY ); } else { // Enqueue single action. $function_args = array_filter( $function_args, static function( $key ) { return in_array( $key, array( 'start', 'hook', 'callback_args', 'group', 'unique', 'priority' ), true ); }, ARRAY_FILTER_USE_KEY ); } $function_args = array_values( $function_args ); try { $action_id = call_user_func_array( $function, $function_args ); } catch ( \Exception $e ) { $this->print_error( $e ); } if ( 0 === $action_id ) { $e = new \Exception( __( 'Unable to create a scheduled action.', 'action-scheduler' ) ); $this->print_error( $e ); } $this->print_success( $action_id, $action_type ); } /** * Print a success message with the action ID. * * @param int $action_id Created action ID. * @param string $action_type Type of action. * * @return void */ protected function print_success( $action_id, $action_type ) { \WP_CLI::success( sprintf( /* translators: %1$s: type of action, %2$d: ID of the created action */ __( '%1$s action (%2$d) scheduled.', 'action-scheduler' ), ucfirst( $action_type ), $action_id ) ); } /** * Convert an exception into a WP CLI error. * * @param \Exception $e The error object. * @throws \WP_CLI\ExitException When an error occurs. * @return void */ protected function print_error( \Exception $e ) { \WP_CLI::error( sprintf( /* translators: %s refers to the exception error message. */ __( 'There was an error creating the scheduled action: %s', 'action-scheduler' ), $e->getMessage() ) ); } } List_Command.php 0000644 00000006067 15253067654 0007654 0 ustar 00 <?php namespace Action_Scheduler\WP_CLI\Action; // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaping output is not necessary in WP CLI. /** * WP-CLI command: action-scheduler action list */ class List_Command extends \ActionScheduler_WPCLI_Command { const PARAMETERS = array( 'hook', 'args', 'date', 'date_compare', 'modified', 'modified_compare', 'group', 'status', 'claimed', 'per_page', 'offset', 'orderby', 'order', ); /** * Execute command. * * @return void */ public function execute() { $store = \ActionScheduler::store(); $logger = \ActionScheduler::logger(); $fields = array( 'id', 'hook', 'status', 'group', 'recurring', 'scheduled_date', ); $this->process_csv_arguments_to_arrays(); if ( ! empty( $this->assoc_args['fields'] ) ) { $fields = $this->assoc_args['fields']; } $formatter = new \WP_CLI\Formatter( $this->assoc_args, $fields ); $query_args = $this->assoc_args; /** * The `claimed` parameter expects a boolean or integer: * check for string 'false', and set explicitly to `false` boolean. */ if ( array_key_exists( 'claimed', $query_args ) && 'false' === strtolower( $query_args['claimed'] ) ) { $query_args['claimed'] = false; } $return_format = 'OBJECT'; if ( in_array( $formatter->format, array( 'ids', 'count' ), true ) ) { $return_format = '\'ids\''; } // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_export $params = var_export( $query_args, true ); if ( empty( $query_args ) ) { $params = 'array()'; } \WP_CLI::debug( sprintf( 'as_get_scheduled_actions( %s, %s )', $params, $return_format ) ); if ( ! empty( $query_args['args'] ) ) { $query_args['args'] = json_decode( $query_args['args'], true ); } switch ( $formatter->format ) { case 'ids': $actions = as_get_scheduled_actions( $query_args, 'ids' ); echo implode( ' ', $actions ); break; case 'count': $actions = as_get_scheduled_actions( $query_args, 'ids' ); $formatter->display_items( $actions ); break; default: $actions = as_get_scheduled_actions( $query_args, OBJECT ); $actions_arr = array(); foreach ( $actions as $action_id => $action ) { $action_arr = array( 'id' => $action_id, 'hook' => $action->get_hook(), 'status' => $store->get_status( $action_id ), 'args' => $action->get_args(), 'group' => $action->get_group(), 'recurring' => $action->get_schedule()->is_recurring() ? 'yes' : 'no', 'scheduled_date' => $this->get_schedule_display_string( $action->get_schedule() ), 'log_entries' => array(), ); foreach ( $logger->get_logs( $action_id ) as $log_entry ) { $action_arr['log_entries'][] = array( 'date' => $log_entry->get_date()->format( static::DATE_FORMAT ), 'message' => $log_entry->get_message(), ); } $actions_arr[] = $action_arr; } $formatter->display_items( $actions_arr ); break; } } } Next_Command.php 0000644 00000003503 15253067654 0007647 0 ustar 00 <?php namespace Action_Scheduler\WP_CLI\Action; // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaping output is not necessary in WP CLI. use function \WP_CLI\Utils\get_flag_value; /** * WP-CLI command: action-scheduler action next */ class Next_Command extends \ActionScheduler_WPCLI_Command { /** * Execute command. * * @return void */ public function execute() { $hook = $this->args[0]; $group = get_flag_value( $this->assoc_args, 'group', '' ); $callback_args = get_flag_value( $this->assoc_args, 'args', null ); $raw = (bool) get_flag_value( $this->assoc_args, 'raw', false ); if ( ! empty( $callback_args ) ) { $callback_args = json_decode( $callback_args, true ); } if ( $raw ) { \WP_CLI::line( as_next_scheduled_action( $hook, $callback_args, $group ) ); return; } $params = array( 'hook' => $hook, 'orderby' => 'date', 'order' => 'ASC', 'group' => $group, ); if ( is_array( $callback_args ) ) { $params['args'] = $callback_args; } $params['status'] = \ActionScheduler_Store::STATUS_RUNNING; // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_export \WP_CLI::debug( 'ActionScheduler()::store()->query_action( ' . var_export( $params, true ) . ' )' ); $store = \ActionScheduler::store(); $action_id = $store->query_action( $params ); if ( $action_id ) { echo $action_id; return; } $params['status'] = \ActionScheduler_Store::STATUS_PENDING; // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_export \WP_CLI::debug( 'ActionScheduler()::store()->query_action( ' . var_export( $params, true ) . ' )' ); $action_id = $store->query_action( $params ); if ( $action_id ) { echo $action_id; return; } \WP_CLI::warning( 'No matching next action.' ); } } Get_Command.php 0000644 00000004240 15253067654 0007447 0 ustar 00 <?php namespace Action_Scheduler\WP_CLI\Action; /** * WP-CLI command: action-scheduler action get */ class Get_Command extends \ActionScheduler_WPCLI_Command { /** * Execute command. * * @return void */ public function execute() { $action_id = $this->args[0]; $store = \ActionScheduler::store(); $logger = \ActionScheduler::logger(); $action = $store->fetch_action( $action_id ); if ( is_a( $action, ActionScheduler_NullAction::class ) ) { /* translators: %d is action ID. */ \WP_CLI::error( sprintf( esc_html__( 'Unable to retrieve action %d.', 'action-scheduler' ), $action_id ) ); } $only_logs = ! empty( $this->assoc_args['field'] ) && 'log_entries' === $this->assoc_args['field']; $only_logs = $only_logs || ( ! empty( $this->assoc_args['fields'] ) && 'log_entries' === $this->assoc_args['fields'] ); $log_entries = array(); foreach ( $logger->get_logs( $action_id ) as $log_entry ) { $log_entries[] = array( 'date' => $log_entry->get_date()->format( static::DATE_FORMAT ), 'message' => $log_entry->get_message(), ); } if ( $only_logs ) { $args = array( 'format' => \WP_CLI\Utils\get_flag_value( $this->assoc_args, 'format', 'table' ), ); $formatter = new \WP_CLI\Formatter( $args, array( 'date', 'message' ) ); $formatter->display_items( $log_entries ); return; } try { $status = $store->get_status( $action_id ); } catch ( \Exception $e ) { \WP_CLI::error( $e->getMessage() ); } $action_arr = array( 'id' => $this->args[0], 'hook' => $action->get_hook(), 'status' => $status, 'args' => $action->get_args(), 'group' => $action->get_group(), 'recurring' => $action->get_schedule()->is_recurring() ? 'yes' : 'no', 'scheduled_date' => $this->get_schedule_display_string( $action->get_schedule() ), 'log_entries' => $log_entries, ); $fields = array_keys( $action_arr ); if ( ! empty( $this->assoc_args['fields'] ) ) { $fields = explode( ',', $this->assoc_args['fields'] ); } $formatter = new \WP_CLI\Formatter( $this->assoc_args, $fields ); $formatter->display_item( $action_arr ); } } Cancel_Command.php 0000644 00000006403 15253067654 0010120 0 ustar 00 <?php namespace Action_Scheduler\WP_CLI\Action; use function \WP_CLI\Utils\get_flag_value; /** * WP-CLI command: action-scheduler action cancel */ class Cancel_Command extends \ActionScheduler_WPCLI_Command { /** * Execute command. * * @return void */ public function execute() { $hook = ''; $group = get_flag_value( $this->assoc_args, 'group', '' ); $callback_args = get_flag_value( $this->assoc_args, 'args', null ); $all = get_flag_value( $this->assoc_args, 'all', false ); if ( ! empty( $this->args[0] ) ) { $hook = $this->args[0]; } if ( ! empty( $callback_args ) ) { $callback_args = json_decode( $callback_args, true ); } if ( $all ) { $this->cancel_all( $hook, $callback_args, $group ); return; } $this->cancel_single( $hook, $callback_args, $group ); } /** * Cancel single action. * * @param string $hook The hook that the job will trigger. * @param array $callback_args Args that would have been passed to the job. * @param string $group The group the job is assigned to. * @return void */ protected function cancel_single( $hook, $callback_args, $group ) { if ( empty( $hook ) ) { \WP_CLI::error( __( 'Please specify hook of action to cancel.', 'action-scheduler' ) ); } try { $result = as_unschedule_action( $hook, $callback_args, $group ); } catch ( \Exception $e ) { $this->print_error( $e, false ); } if ( null === $result ) { $e = new \Exception( __( 'Unable to cancel scheduled action: check the logs.', 'action-scheduler' ) ); $this->print_error( $e, false ); } $this->print_success( false ); } /** * Cancel all actions. * * @param string $hook The hook that the job will trigger. * @param array $callback_args Args that would have been passed to the job. * @param string $group The group the job is assigned to. * @return void */ protected function cancel_all( $hook, $callback_args, $group ) { if ( empty( $hook ) && empty( $group ) ) { \WP_CLI::error( __( 'Please specify hook and/or group of actions to cancel.', 'action-scheduler' ) ); } try { $result = as_unschedule_all_actions( $hook, $callback_args, $group ); } catch ( \Exception $e ) { $this->print_error( $e, true ); } /** * Because as_unschedule_all_actions() does not provide a result, * neither confirm or deny actions cancelled. */ \WP_CLI::success( __( 'Request to cancel scheduled actions completed.', 'action-scheduler' ) ); } /** * Print a success message. * * @return void */ protected function print_success() { \WP_CLI::success( __( 'Scheduled action cancelled.', 'action-scheduler' ) ); } /** * Convert an exception into a WP CLI error. * * @param \Exception $e The error object. * @param bool $multiple Boolean if multiple actions. * @throws \WP_CLI\ExitException When an error occurs. * @return void */ protected function print_error( \Exception $e, $multiple ) { \WP_CLI::error( sprintf( /* translators: %1$s: singular or plural %2$s: refers to the exception error message. */ __( 'There was an error cancelling the %1$s: %2$s', 'action-scheduler' ), $multiple ? __( 'scheduled actions', 'action-scheduler' ) : __( 'scheduled action', 'action-scheduler' ), $e->getMessage() ) ); } }
dvadf
dvadf
| ver. 1.4 |
Github
|
.
| PHP 7.3.33 | Generation time: 0 |
proxy
|
phpinfo
|
Settings