File: /var/www/html/wp-content/plugins/wp-fail2ban/admin/lib/tab.php
<?php declare(strict_types=1);
/**
* Tab base class
*
* @package wp-fail2ban
* @since 4.4.0 Require PHP 7.4
* @since 4.0.0
*/
namespace org\lecklider\charles\wordpress\wp_fail2ban;
defined( 'ABSPATH' ) or exit;
/**
* Tab: Base class
*
* @since 4.0.0
*/
abstract class TabBase {
/**
* @since 4.3.2.1
* @var string Help link: Documentation
*/
const HELP_LINK_DOCS = 'https://life-with.wp-fail2ban.com';
/**
* @since 4.3.2.1
* @var string Help link: Reference
*/
const HELP_LINK_REFERENCE = 'https://docs.wp-fail2ban.com/en/' . WP_FAIL2BAN_VER2;
/**
* @since 4.3.2.1
* @var string Help link: Support
*/
const HELP_LINK_SUPPORT = 'https://forums.invis.net/c/wp-fail2ban/support/';
/**
* @var array Array of Tab objects
* @todo Set type to array
*/
protected static $tabs = array();
/**
* @var string Default tab slug
* @todo Set type to string
*/
protected static $default_tab;
/**
* @var TabBase Active tab
* @todo Set type to TabBase
*/
protected static $active_tab;
/**
* @var string Tab slug
* @todo Set type to string
*/
protected $tab_slug;
/**
* @var string Tab name
* @todo Set type to string
*/
protected $tab_name;
/**
* @since 4.3.0
* @var bool Apply/Reset buttons?
* @todo Set type to bool
*/
protected $tab_apply;
/**
* @var int admin_init priority
* @since 4.3.0
* @todo Set type to int
*/
protected $admin_init_priority = 10;
/**
* @since 4.3.3.0
* @var array i18n
* @todo Set tpye to array
*
* @phpcs:disable PSR2.Classes.PropertyDeclaration.Underscore
*/
protected $__ = array();
/**
* Hook: admin_init
*
* @since 4.4.0 Add return type
* @since 4.0.0
*/
abstract public function admin_init(): void;
/**
* Hook: current_screen
*
* @since 4.4.0 Add return type
* @since 4.3.2.1 Add links to override
* @since 4.3.0
*
* @param string $linkDocumentation
* @param string $linkSupport
* @param string $linkReference
*
* @return void
*/
public function current_screen(): void {
get_current_screen()->set_help_sidebar(
'<p><strong>' . __( 'For more information:', 'wp-fail2ban' ) . '</strong></p>' .
sprintf( '<p><a href="%s" rel="noopener" target="_blank">%s</a></p>', static::HELP_LINK_DOCS, __( 'Documentation', 'wp-fail2ban' ) ) .
sprintf( '<p><a href="%s" rel="noopener" target="_blank">%s</a></p>', static::HELP_LINK_REFERENCE, __( 'Reference', 'wp-fail2ban' ) ) .
sprintf( '<p><a href="%s" rel="noopener" target="_blank">%s</a></p>', static::HELP_LINK_SUPPORT, __( 'Support', 'wp-fail2ban' ) )
);
}
/**
* Helper: Create dt/dd pair
*
* @since 4.4.0 Add return type
* @since 4.3.3.0
*
* @param string $id
* @param array $paras
* @param string|null $title
*
* @return string
*/
protected function help_entry( $id, array $paras, $title = null ): string {
if ( is_null( $title ) ) {
$title = $this->__[ $id ];
}
$paras = apply_filters( "help-entry::{$id}.paras", $paras );
$entry = apply_filters( "help-entry::{$id}.pre", '' );
$entry .= "<dt>{$title}</dt><dd>";
$entry .= $this->process_paras( $paras );
$entry .= '</dd>';
$entry .= apply_filters( "help-entry::{$id}.post", '' );
return $entry;
}
/**
* Helper: Create paragraphs
*
* @since 4.4.0 Add return type
* @since 4.3.3.0
*
* @param array|string $paras
*
* @throws \InvalidArgumentException
*
* @return string
*/
protected function process_paras( $paras ): string {
if ( empty( $paras ) ) {
return '';
} elseif ( is_array( $paras ) ) {
return '<p>' . join( '</p><p>', array_map( array( $this, 'process_para' ), $paras ) ) . '</p>';
} elseif ( is_string( $paras ) ) {
return $paras;
} else {
throw new \InvalidArgumentException();
}
}
/**
* Helper: Create paragraph content
*
* @since 4.4.0 Add return type
* @since 4.3.3.0
*
* @param array|string $para
*
* @return string
*/
protected function process_para( $para ): string {
if ( is_array( $para ) ) {
$para = join( '<br>', $para );
}
return $para;
}
/**
* Helper: Add help tab
*
* @since 4.4.0 Add return type
* @since 4.3.3.0
*
* @param string $id
* @param array|string $dl
* @param array|string $pre
* @param array|string $post
*
* @return void
*/
protected function add_help_tab( $id, $dl, $pre = '', $post = '' ): void {
$pre = apply_filters( "help-tab::{$id}.pre", $pre );
$post = apply_filters( "help-tab::{$id}.post", $post );
$content = $this->process_paras( $pre );
if ( is_array( $dl ) ) {
$content .= apply_filters( "help-tab::{$id}.dl.pre", "<dl>\n" );
$content .= join( "\n", $dl );
$content .= apply_filters( "help-tab::{$id}.dl.post", "</dl>\n" );
} else {
$content .= apply_filters( "help-tab::{$id}.dl.pre", '' );
$content .= $dl;
$content .= apply_filters( "help-tab::{$id}.dl.post", '' );
}
$content .= $this->process_paras( $post );
get_current_screen()->add_help_tab(
array(
'id' => $id,
'title' => $this->__[ $id ],
'content' => $content,
)
);
}
/**
* Sanitize and store form fields
*
* @since 4.4.0 Add return type
* @since 4.3.0 Refactor
* @since 4.0.0
*
* @param array $input Form fields
*
* @return array
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function sanitize( array $input = null ): array {
return array();
}
/**
* Contruct.
*
* @since 4.4.0 Add type hints
* @since 4.0.0
*
* @param string $slug Tab slug
* @param string $name Tab name
* @param bool $apply Show Apply/Reset buttons
*/
public function __construct( string $slug, string $name, bool $apply = true ) {
$this->tab_slug = $slug;
$this->tab_name = $name;
$this->tab_apply = $apply;
self::$tabs[ $slug ] = $this;
$this->admin_init();
add_filter( 'gettext', array( $this, 'gettext' ), PHP_INT_MAX, 3 );
}
/**
* Hook: gettext
*
* @since 4.4.0 Add type hints, return type
* @since 4.3.0
*
* @param string $translation
* @param string $text
* @param string $domain
*
* @return string
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function gettext( string $translation, string $text, string $domain ): string {
return str_replace( '___WPF2BVER___', WP_FAIL2BAN_VER2, $translation );
}
/**
* Getter - slug
*
* @since 4.4.0 Add return type
* @since 4.0.0
*
* @return string Tab slug
*/
public function getSlug(): string {
return $this->tab_slug;
}
/**
* Getter - name
*
* @since 4.4.0 Add return type
* @since 4.0.0
*
* @return string Tab name
*/
public function getName(): string {
return $this->tab_name;
}
/**
* Render settings section
*
* @since 4.4.0 Add return type
* @since 4.3.0 Refactored.
* @since 4.0.0
*/
public function render(): void {
do_settings_sections( 'wp-fail2ban-' . $this->tab_slug );
$this->render_buttons();
}
/**
* Render settings section buttons
*
* @since 4.4.0 Add return type
* @since 4.3.0
*
* @return void
*
* phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
*/
protected function render_buttons(): void {
printf(
'<hr><p><strong>%s:</strong> %s<br>%s</p>',
__( 'Note', 'wp-fail2ban' ),
__(
'The Free version of <em>WP fail2ban</em> is configured by defining constants in <code>wp-config.php</code>;
these tabs reflect those values.',
'wp-fail2ban'
),
__( 'Upgrade to the Premium version to enable this interface.', 'wp-fail2ban' )
);
}
/**
* Helper: is this the active tab?
*
* @since 4.4.0 Add return type
* @since 4.3.0
*
* @return bool
*/
protected function isActiveTab(): bool {
return ( $this->tab_name == self::getActiveTab()->getName() );
}
/**
* Helper - tab
*
* @since 4.4.0 Add return type
* @since 4.0.0
*
* @param string $slug Tab slug
*
* @return TabBase Tab
*/
public static function getTab( $slug ): TabBase {
return self::$tabs[ $slug ];
}
/**
* Helper - set the default tab.
*
* @since 4.4.0 Add type hint, return type
* @since 4.3.0
*
* @param string $default Default tab slug
*
* @return void
*/
public static function setDefaultTab( string $default ): void {
self::$default_tab = $default;
}
/**
* Helper - current tab
*
* @since 4.4.0 Add return type
* @since 4.0.0
*
* @return TabBase Tab
*/
public static function getActiveTab(): TabBase {
if ( ! empty( self::$active_tab ) ) {
return self::$active_tab;
}
return ( self::$active_tab = ( array_key_exists( $_GET['tab'] ?? '--', self::$tabs ) )
? self::$tabs[ $_GET['tab'] ]
: self::$tabs[ self::$default_tab ]
);
}
/**
* Helper - tab name
*
* @since 4.4.0 Add type hint, return type
* @since 4.0.0
*
* @param string $slug Tab slug
*
* @return string Tab name
*/
public static function getTabName( string $slug ): string {
return self::getTab( $slug )->getName();
}
/**
* Helper - tab exists?
*
* @since 4.4.0 Add type hint, return type
* @since 4.3.0
*
* @param string $slug Tab slug
*
* @return bool
*/
public static function tabExists( string $slug ): bool {
return array_key_exists( $slug, self::$tabs );
}
/**
* Link to documentation
*
* @since 5.0.0 Simplify
* @since 4.4.0 Add type hint, return type
* @since 4.3.0 Protected
* @since 4.2.0
*
* @param string $define
*
* @return string
*/
protected function doc_link( string $define ): string {
$link = <<< HTML
<a href="%s/defines/constants/%s.html"
style="text-decoration: none;"
target="_blank"
title="%s">%s<span class="dashicons dashicons-external"
style="vertical-align: text-bottom"></span></a>
HTML;
return sprintf( $link, self::HELP_LINK_REFERENCE, $define, __( 'Reference', 'wp-fail2ban' ), $define );
}
/**
* Standard list of links to docs
*
* @since 4.4.0 Add return type
* @since 4.3.0
*
* @param array $defines List of defines
* @param bool $para Wrap in <p>
*
* @return string HTML
*/
protected function see_also( array $defines, $para = true ): string {
$html = sprintf( '<em>%s</em>', __( 'See also:', 'wp-fail2ban' ) );
if ( 1 == count( $defines ) ) {
$html .= ' ' . $this->doc_link( $defines[0] );
} else {
$html .= sprintf(
'<br> — %s',
implode(
'<br> — ',
array_map(
function ( $i ) {
return $this->doc_link( $i );
},
$defines
)
)
);
}
if ( $para ) {
$html = '<p>' . $html . '</p>';
}
return $html;
}
/**
* id="%s" Helper
*
* @since 4.4.0 Add type hint, return type
* @since 4.3.0 Moved here.
* @since 4.0.0
*
* @param string $define
*
* @return string
*/
protected function field_name( string $define ): string {
global $wp_fail2ban;
return 'wp-fail2ban[' . join( '][', $wp_fail2ban['config'][ $define ]['field'] ) . ']';
}
/**
* name="%s" Helper
*
* @since 4.4.0 Add $suffix, type hint, return type
* @since 4.3.0 Moved here.
* @since 4.0.0
*
* @param string $define
* @param string|null $suffix
*
* @return string
*/
protected function field_id( string $define, string $suffix = null ): string {
global $wp_fail2ban;
$rv = join( '-', $wp_fail2ban['config'][ $define ]['field'] );
if ( ! empty( $suffix ) ) {
$rv .= '-' . $suffix;
}
return $rv;
}
/**
* Helper: checked()
*
* @since 4.4.0 Add type hints, return type
* @since 4.3.0
*
* @param string $define
* @param mixed $current
* @param bool $echo
*
* @return string
*/
protected function def_checked( string $define, $current = true, bool $echo = true ): string {
return checked( Config::get( $define ), $current, $echo );
}
/**
* NDEF disabled helper
*
* @since 4.4.0 Add filter, type hints, return type
* @since 4.3.0 Add $override; moved here.
* @since 4.0.0
*
* @param string $define
* @param bool $override
*
* @return string
*/
protected function ndef_disabled( string $define, bool $override = false ): string {
return disabled( Config::def( $define ) || apply_filters( "{$define}.ndef_disabled", $override ), true, false );
}
/**
* Display standard checkbox
*
* @since 4.4.0 Add type hints, return type
* @since 4.3.0
*
* @param string $define Constant
* @param bool $show_desc Show description?
* @param string $plan Freemius plan
* @param bool $echo Echo?
*
* @return string HTML
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
protected function checkbox( string $define, bool $show_desc = true, string $plan = 'bronze', bool $echo = true ): string {
$html = sprintf(
'<input type="checkbox" disabled="disabled" %s>',
checked( Config::get( $define ), true, false )
);
if ( $show_desc ) {
$html = '<label>' . $html . ' <span>' . $this->description( $define, false ) . '</span></label>';
}
if ( $echo ) {
echo $html;
}
return $html;
}
/**
* Display standard radio buttons
*
* @since 4.4.0 Add type hints, return type
* @since 4.3.3
*
* @param array|string $define
* @param bool $show_desc
* @param string $plan
* @param bool $echo
* @param string $cssClass
*
* @return string
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
protected function radio( $define, bool $show_desc = true, string $plan = 'bronze', bool $echo = true ): string {
global $wp_fail2ban;
if ( is_array( $define ) ) {
extract( $define );
}
$html = '';
foreach ( $wp_fail2ban['config'][ $define ]['values'] as $value ) {
$checked = $this->def_checked( $define, $value, false );
if ( $show_desc ) {
$html .= "<p><label><input type=\"radio\" disabled=\"disabled\" {$checked}> " . $this->description( "{$define}.{$value}", false ) . '</label>';
} else {
$html .= "<p><input type=\"radio\" disabled=\"disabled\" {$checked}>";
}
$html .= '</p>';
}
if ( $echo ) {
echo $html;
}
return $html;
}
/**
* Display standard text input
*
* @since 4.4.0 Add type hints, return type
* @since 4.3.0
*
* @param string $define Constant
* @param bool $show_desc Show description?
* @param string $plan Freemius plan
* @param bool $echo Echo?
* @param string $value Text value
* @param string $cssClass CSS class
*
* @return string HTML
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
protected function inputText( string $define, bool $show_desc = true, string $plan = 'bronze', bool $echo = true, string $value = null, string $cssClass = 'regular-text', string $type = 'text' ): string {
if ( is_null( $value ) ) {
$value = Config::get( $define );
}
$html = sprintf(
'<a name="%s"></a><input class="%s" type="%s" value="%s" disabled>',
$this->field_id( $define ),
$cssClass,
$type,
esc_attr( $value )
);
if ( $show_desc ) {
$html .= sprintf( '<p class="description">%s</p>', Config::desc( $define ) );
}
if ( $echo ) {
echo $html;
}
return $html;
}
/**
* Helper: input type=email
*
* @since 4.4.0 Add type hints, return type
* @since 4.3.2.2
*
* @param string $define Constant
* @param bool $show_desc Show description?
* @param string $plan Freemius plan
* @param bool $echo Echo?
* @param string $value Text value
* @param string $cssClass CSS class
*
* @return string HTML
*/
protected function inputEmail(
string $define,
bool $show_desc = true,
string $plan = 'bronze',
bool $echo = true,
string $value = null,
string $cssClass = 'regular-text'
): string {
return $this->inputText( $define, $show_desc, $plan, $echo, $value, $cssClass, 'email' );
}
/**
* Helper: input type=password
*
* @since 4.4.0 Add return type
* @since 4.3.2.2
*
* @param string $define Constant
* @param bool $show_desc Show description?
* @param string $plan Freemius plan
* @param bool $echo Echo?
* @param string $value Text value
* @param string $cssClass CSS class
*
* @return string HTML
*/
protected function inputPassword(
string $define,
bool $show_desc = true,
string $plan = 'bronze',
bool $echo = true,
string $value = null,
string $cssClass = 'regular-text'
): string {
return $this->inputText( $define, $show_desc, $plan, $echo, $value, $cssClass, 'password' );
}
/**
* Helper: setting description
*
* @since 4.4.0 Add type hints, return type
* @since 4.3.0
*
* @param string $define
* @param bool $echo
*
* @return string
*/
protected function description( string $define, bool $echo = true ): string {
if ( ! is_null( $desc = Config::desc( $define ) ) ) {
if ( $echo ) {
echo '<p class="description">' . $desc . '</p>';
}
return $desc;
} else {
return '';
}
}
/**
* Helper: setting description extended
*
* @since 5.1.0
*
* @param string $define
* @param bool $echo
*
* @return string
*/
protected function description_ex( string $define, bool $echo = true ): string {
if ( ! is_null( $desc = Config::desc_ex( $define ) ) ) {
if ( $echo ) {
echo '<p class="description">' . $desc . '</p>';
}
return $desc;
} else {
return '';
}
}
}