settings_repository = new SettingsRepository();
}
/**
* Render page.
*/
public function render(): void {
$this->prepare_page();
$notice = $this->handle_submit();
$settings = $this->settings_repository->get_all();
$this->open_page( __( 'Settings', 'inteltele' ) );
$this->render_step_notice();
$this->render_notice( $notice );
echo '
';
$this->close_page();
}
/**
* Handle form submission.
*
* @return array{type:string,messages:string[]}|null
*/
private function handle_submit(): ?array {
if ( ! $this->is_post_request() ) {
return null;
}
if ( ! current_user_can( 'inteltele_manage' ) ) {
return array(
'type' => 'error',
'messages' => array( __( 'You do not have permission to manage IntelTele settings.', 'inteltele' ) ),
);
}
if ( ! isset( $_POST['inteltele_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['inteltele_nonce'] ) ), 'inteltele_save_settings' ) ) {
return array(
'type' => 'error',
'messages' => array( __( 'Security check failed. Please reload the page and try again.', 'inteltele' ) ),
);
}
$result = $this->settings_repository->sanitize( $_POST, $this->settings_repository->get_all() );
if ( ! empty( $result['errors'] ) ) {
return array(
'type' => 'error',
'messages' => $result['errors'],
);
}
$action = isset( $_POST['inteltele_action'] ) ? sanitize_key( wp_unslash( $_POST['inteltele_action'] ) ) : 'save';
if ( 'check_connection' === $action ) {
return $this->handle_connection_check( $result['settings'] );
}
if ( ! $this->settings_repository->save( $result['settings'] ) ) {
return array(
'type' => 'error',
'messages' => array( __( 'Settings could not be saved. Please try again.', 'inteltele' ) ),
);
}
return array(
'type' => 'success',
'messages' => array( __( 'Saved.', 'inteltele' ) ),
);
}
/**
* Check API connection and update balance.
*
* @param array $settings Settings.
* @return array{type:string,messages:string[]}
*/
private function handle_connection_check( array $settings ): array {
$client = ClientFactory::create( $settings );
$result = $client->get_balance();
if ( ! $result->is_success() ) {
PluginLogger::log(
'error',
'connection_check_failed',
$result->get_error(),
array(
'http_status' => $result->get_status_code(),
'raw' => $result->get_raw(),
),
'SettingsPage'
);
return array(
'type' => 'error',
'messages' => array(
__( 'Connection check failed.', 'inteltele' ),
$result->get_error(),
),
);
}
$balance = sanitize_text_field( (string) $result->get( 'balance', '' ) );
$settings['balance'] = $balance;
PluginLogger::log(
'info',
'connection_check_success',
__( 'API connection checked successfully.', 'inteltele' ),
array(
'balance' => $balance,
'http_status' => $result->get_status_code(),
),
'SettingsPage'
);
if ( ! $this->settings_repository->save( $settings ) ) {
return array(
'type' => 'error',
'messages' => array( __( 'Connection was checked, but settings could not be saved.', 'inteltele' ) ),
);
}
return array(
'type' => 'success',
'messages' => array(
__( 'Connection checked successfully.', 'inteltele' ),
sprintf(
/* translators: %s: account balance. */
__( 'Balance: %s', 'inteltele' ),
'' === $balance ? __( 'not returned by API', 'inteltele' ) : $balance
),
),
);
}
/**
* Render submit notice.
*
* @param array{type:string,messages:string[]}|null $notice Notice data.
*/
private function render_notice( ?array $notice ): void {
if ( null === $notice ) {
return;
}
$class = 'success' === $notice['type'] ? 'notice-success' : 'notice-error';
echo '';
foreach ( $notice['messages'] as $message ) {
echo '
' . esc_html( $message ) . '
';
}
echo '
';
}
/**
* Render a text input row.
*
* @param string $name Field name.
* @param string $label Field label.
* @param string $value Field value.
* @param bool $readonly Whether the field is readonly.
*/
private function render_text_input( string $name, string $label, string $value, bool $readonly = false ): void {
echo '';
echo ' | ';
echo ' | ';
echo '
';
}
/**
* Render a number input row.
*
* @param string $name Field name.
* @param string $label Field label.
* @param string $value Field value.
*/
private function render_number_input( string $name, string $label, string $value, int $min, int $max ): void {
echo '';
echo ' | ';
echo ' | ';
echo '
';
}
/**
* Render readonly text.
*
* @param string $label Field label.
* @param string $value Field value.
*/
private function render_readonly_text( string $label, string $value ): void {
echo '';
echo '| ' . esc_html( $label ) . ' | ';
echo '' . esc_html( $value ) . ' | ';
echo '
';
}
/**
* Render webhook URL field.
*/
private function render_webhook_url(): void {
$url = DeliveryStatusWebhook::get_url();
echo '';
echo ' | ';
echo '';
echo ' ';
echo '';
echo ' ' . esc_html__( 'Copy this URL to the IntelTele cabinet for delivery status webhooks.', 'inteltele' ) . ' ';
echo ' | ';
echo '
';
}
/**
* Render manager phone fields.
*/
private function render_manager_phones( array $phones ): void {
if ( empty( $phones ) ) {
$phones = array( '' );
}
echo '';
echo '| ' . esc_html__( 'Manager phones', 'inteltele' ) . ' | ';
echo '';
echo ' ';
foreach ( $phones as $index => $phone ) {
if ( $index > 0 ) {
echo ' ';
}
echo ' ';
}
echo '';
echo ' ';
echo '' . esc_html__( 'Only digits are allowed. Use international format without plus sign.', 'inteltele' ) . ' ';
echo ' | ';
echo '
';
}
/**
* Format balance for readonly output.
*
* @param string $balance Balance.
*/
private function format_balance( string $balance ): string {
return '' === $balance ? __( 'Not checked yet', 'inteltele' ) : $balance;
}
}