From 5ec9bf08885c0c92cfc7df83641189fcc74d38bb Mon Sep 17 00:00:00 2001 From: Stefan Kalscheuer Date: Sun, 17 Mar 2024 19:10:26 +0100 Subject: [PATCH] docs: extend PHPDocs and fix some minor code style issues --- src/Admin/CommentsColumns.php | 3 +- src/Admin/DashboardWidgets.php | 6 ++ src/Admin/Fields/Checkbox.php | 2 + src/Admin/Fields/CheckboxGroup.php | 11 ++- src/Admin/Fields/Field.php | 4 +- src/Admin/Fields/Inline.php | 15 +++++ src/Admin/Fields/Select.php | 7 ++ src/Admin/Fields/Text.php | 27 ++++++++ src/Admin/Fields/Textarea.php | 2 + src/Admin/Section.php | 30 ++++++--- src/Admin/SettingsPage.php | 19 ++++-- src/Admin/Tab.php | 15 ++++- src/Crons/DeleteSpamCron.php | 39 +++++++++-- src/GeneralOptions/Base.php | 81 +++++++++++++++++++---- src/GeneralOptions/DeleteOldSpam.php | 36 ++++++++++ src/GeneralOptions/IgnoreLinkbacks.php | 29 ++++++++ src/GeneralOptions/Statistics.php | 29 ++++++++ src/GeneralOptions/Uninstall.php | 29 ++++++++ src/Handlers/Comment.php | 20 ++++++ src/Handlers/GeneralOptions.php | 27 +++++++- src/Handlers/Linkback.php | 20 ++++++ src/Handlers/PluginStateChangeHandler.php | 7 +- src/Handlers/PluginUpdate.php | 32 ++++++++- src/Handlers/PostProcessors.php | 39 +++++++++-- src/Handlers/Reaction.php | 43 ++++++++++-- src/Handlers/Rules.php | 77 ++++++++++++++++++++- src/Helpers/ComponentsHelper.php | 32 ++++++--- src/Helpers/ContentTypeHelper.php | 14 ++++ src/Helpers/DashboardHelper.php | 2 + src/Helpers/DataHelper.php | 29 ++++++++ src/Helpers/DebugMode.php | 32 ++++++++- src/Helpers/InterfaceHelper.php | 18 +++-- src/Helpers/IpHelper.php | 11 ++- src/Helpers/LangHelper.php | 10 +++ src/Helpers/Sanitize.php | 43 ++++++++++-- src/Helpers/Settings.php | 60 ++++++++++++++--- src/Helpers/SpamReasonTextHelper.php | 28 +++++++- src/Interfaces/Controllable.php | 60 ++++++++++++++++- src/Interfaces/PostProcessor.php | 27 ++++++++ src/Interfaces/SpamReason.php | 13 ++++ src/Interfaces/Verifiable.php | 36 ++++++++++ src/PostProcessors/Base.php | 44 +++++++++++- src/PostProcessors/ControllableBase.php | 44 +++++++++++- src/PostProcessors/Delete.php | 39 ++++++++++- src/PostProcessors/DeleteForReasons.php | 50 +++++++++++++- src/PostProcessors/SaveReason.php | 35 +++++++++- src/PostProcessors/SendEmail.php | 58 +++++++++++++++- src/PostProcessors/UpdateSpamCount.php | 17 +++++ src/PostProcessors/UpdateSpamLog.php | 17 +++++ src/Rules/ApprovedEmail.php | 18 ++++- src/Rules/BBCode.php | 11 +++ src/Rules/Base.php | 23 ++++++- src/Rules/ControllableBase.php | 5 ++ src/Rules/CountrySpam.php | 11 +++ src/Rules/DbSpam.php | 10 +++ src/Rules/EmptyData.php | 11 +++ src/Rules/Honeypot.php | 19 +++++- src/Rules/InvalidRequest.php | 11 +++ src/Rules/LangSpam.php | 10 +++ src/Rules/LinkbackFromMyself.php | 19 +++++- src/Rules/LinkbackPostTitleIsBlogName.php | 19 +++++- src/Rules/RegexpSpam.php | 11 +++ src/Rules/TooFastSubmit.php | 16 +++++ src/Rules/ValidGravatar.php | 16 +++++ 64 files changed, 1485 insertions(+), 93 deletions(-) diff --git a/src/Admin/CommentsColumns.php b/src/Admin/CommentsColumns.php index 146e34bf..20404a84 100644 --- a/src/Admin/CommentsColumns.php +++ b/src/Admin/CommentsColumns.php @@ -2,7 +2,7 @@ /** * Class registering columns for the "spam comments view". * - * @package AntispamBee\Helpers + * @package AntispamBee\Admin */ namespace AntispamBee\Admin; @@ -93,6 +93,7 @@ public static function print_plugin_column( $column, $comment_id ) { $reasons = explode( ',', $spam_reason ); $reason_texts = SpamReasonTextHelper::get_texts_by_slugs( $reasons ); + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- reason texts pre-sanitized. echo implode( ',
', $reason_texts ); } diff --git a/src/Admin/DashboardWidgets.php b/src/Admin/DashboardWidgets.php index d8333819..392d539b 100644 --- a/src/Admin/DashboardWidgets.php +++ b/src/Admin/DashboardWidgets.php @@ -74,6 +74,12 @@ private static function get_spam_count() { return self::format_number( $count ); } + /** + * Format a number. + * + * @param float $number Number to format. + * @return string + */ private static function format_number( $number ) { return ( get_locale() === 'de_DE' ? number_format( $number, 0, '', '.' ) : number_format_i18n( $number ) ); } diff --git a/src/Admin/Fields/Checkbox.php b/src/Admin/Fields/Checkbox.php index 9cc10768..f45034c6 100644 --- a/src/Admin/Fields/Checkbox.php +++ b/src/Admin/Fields/Checkbox.php @@ -17,6 +17,8 @@ class Checkbox extends Field implements RenderElement { * Get HTML. */ public function render() { + // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped + $label = ! empty( $this->get_label() ) ? sprintf( '', esc_attr( $this->get_name() ), diff --git a/src/Admin/Fields/CheckboxGroup.php b/src/Admin/Fields/CheckboxGroup.php index e7201e1f..f30a63d1 100644 --- a/src/Admin/Fields/CheckboxGroup.php +++ b/src/Admin/Fields/CheckboxGroup.php @@ -1,4 +1,9 @@ option['options'] ) ? $this->option['options'] : []; if ( ! is_array( $options ) ) { return; @@ -38,6 +45,8 @@ public function render() { /** * Get Value. * + * @param string $key Option key. + * * @return mixed Value stored in database. */ protected function get_custom_value( $key ) { diff --git a/src/Admin/Fields/Field.php b/src/Admin/Fields/Field.php index 84c1a50e..ea879bba 100644 --- a/src/Admin/Fields/Field.php +++ b/src/Admin/Fields/Field.php @@ -30,6 +30,8 @@ abstract class Field { /** * Type of controllable. + * + * @var string */ protected $controllable_option_name; @@ -123,7 +125,7 @@ protected function maybe_show_description() { /** * Get HTML for field. * - * @return string Elment HTML. + * @return string Element HTML. */ abstract public function render(); } diff --git a/src/Admin/Fields/Inline.php b/src/Admin/Fields/Inline.php index ec1dc476..507c35c9 100644 --- a/src/Admin/Fields/Inline.php +++ b/src/Admin/Fields/Inline.php @@ -1,12 +1,27 @@ option['input'] instanceof Field ) { echo ''; diff --git a/src/Admin/Fields/Select.php b/src/Admin/Fields/Select.php index ab399b95..d7df9a99 100644 --- a/src/Admin/Fields/Select.php +++ b/src/Admin/Fields/Select.php @@ -1,4 +1,9 @@ get_name(); $multiple = isset( $this->option['multiple'] ) && $this->option['multiple'] ? 'multiple' : ''; echo "', @@ -44,6 +61,11 @@ public function get_injectable_markup() { ); } + /** + * Get element class(es). + * + * @return string + */ protected function get_class() { $classes = [ 'small' => 'small-text', @@ -58,6 +80,11 @@ protected function get_class() { return 'regular-text'; } + /** + * Get type of input field. + * + * @return string + */ protected function get_type() { return isset( $this->option['input_type'] ) ? $this->option['input_type'] : 'text'; } diff --git a/src/Admin/Fields/Textarea.php b/src/Admin/Fields/Textarea.php index 8bde6f0a..59c09e69 100644 --- a/src/Admin/Fields/Textarea.php +++ b/src/Admin/Fields/Textarea.php @@ -17,6 +17,8 @@ class Textarea extends Field implements RenderElement { * Render HTML. */ public function render() { + // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped + printf( '

', esc_attr( $this->get_name() ), diff --git a/src/Admin/Section.php b/src/Admin/Section.php index b69a8329..4e075471 100644 --- a/src/Admin/Section.php +++ b/src/Admin/Section.php @@ -55,11 +55,6 @@ class Section { */ private $type; - /** - * - * @var Controllable[] - */ - private $controllables; /** * Initializing Tab. @@ -76,12 +71,24 @@ public function __construct( $slug, $title, $description = '', $type = null ) { $this->type = $type; } + /** + * Add controllable items to section. + * + * @param array|null $controllables List of controllable items to add. + * @return void + */ public function add_controllables( $controllables ) { if ( ! empty( $controllables ) ) { $this->generate_fields( $controllables ); } } + /** + * Generate settings fields for a list of controllable items. + * + * @param Controllable[] $controllables List of controllable items to add. + * @return void + */ private function generate_fields( $controllables ) { foreach ( $controllables as $controllable ) { $label = $controllable::get_label(); @@ -103,7 +110,7 @@ private function generate_fields( $controllables ) { if ( ! empty( $options ) ) { foreach ( $options as $option ) { $valid_for = isset( $option['valid_for'] ) ? $option['valid_for'] : null; - if ( $valid_for !== null && $this->type !== $valid_for ) { + if ( null !== $valid_for && $this->type !== $valid_for ) { continue; } $fields[] = $this->generate_field( $option, $controllable ); @@ -117,6 +124,13 @@ private function generate_fields( $controllables ) { } } + /** + * Generate field for a controllable item's option. + * + * @param array $option Option name. + * @param Controllable $controllable Controllable item. + * @return Checkbox|CheckboxGroup|Inline|Select|Text|Textarea|null + */ private function generate_field( $option, $controllable ) { switch ( $option['type'] ) { case 'input': @@ -215,14 +229,14 @@ function () use ( $row ) { /** * Renders the fields for a row. * - * @param array $row + * @param array $row Row of fields. */ protected function render_row_fields( $row ) { foreach ( $row['fields'] as $key => $field ) { $field->render(); // Add linebreak after field if not (last and not checkbox without label). - if ( $key !== count( $row['fields'] ) - 1 ) { + if ( ( count( $row['fields'] ) - 1 ) !== $key ) { if ( $field instanceof Checkbox && empty( $field->get_label() ) ) { continue; } diff --git a/src/Admin/SettingsPage.php b/src/Admin/SettingsPage.php index 2e547d26..459106b9 100644 --- a/src/Admin/SettingsPage.php +++ b/src/Admin/SettingsPage.php @@ -35,11 +35,15 @@ class SettingsPage { private $tabs = []; /** + * List of controllable rules. + * * @var Rules[] */ private $rules = []; /** + * List of controllable post processors + * * @var PostProcessors[] */ private $post_processors = []; @@ -59,7 +63,7 @@ public function init() { add_action( 'admin_init', [ $this, 'setup_settings' ] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended - $this->active_tab = isset( $_GET['tab'] ) ? $_GET['tab'] : 'general'; + $this->active_tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : 'general'; } /** @@ -79,14 +83,16 @@ public function add_menu() { * Setup tabs content. */ public function setup_settings() { - // Todo: Add a way to build rows and fields with a fluent interface? (Nice-to-have) + // Todo: Add a way to build rows and fields with a fluent interface? (Nice-to-have). + /* * Todo: Instead of using an array to pass options to a function, one could introduce a class that contains * these options as class attributes. You instantiate an object of this class and pass it to the * Components::filter() method. For frequently used options, one could also use blueprints for options. * This would make refactoring easier, but would slightly increase the complexity. (nice-to-have). */ - // Todo: Fix the confusing naming. We have a lot of type e.g. (Nice-to-have) + + // Todo: Fix the confusing naming. We have a lot of type e.g. (Nice-to-have). $tabs['general'] = new Tab( 'general', @@ -114,7 +120,7 @@ public function setup_settings() { $this->populate_tabs(); - // Register option setting + // Register option setting. foreach ( $this->tabs as $tab ) { foreach ( $tab->get_sections() as $section ) { if ( $tab->get_slug() !== $this->active_tab ) { @@ -134,6 +140,11 @@ public function setup_settings() { ); } + /** + * Populate settings tabs. + * + * @return void + */ protected function populate_tabs() { $type = $this->active_tab; diff --git a/src/Admin/Tab.php b/src/Admin/Tab.php index c3aa7836..dcd914a2 100644 --- a/src/Admin/Tab.php +++ b/src/Admin/Tab.php @@ -1,4 +1,9 @@ sections; } + /** + * Add a section to the settings tab. + * + * @param Section $section Section to add. + * @return void + */ public function add_section( Section $section ) { $this->sections[] = $section; } diff --git a/src/Crons/DeleteSpamCron.php b/src/Crons/DeleteSpamCron.php index 8b851b53..95f4d3b9 100644 --- a/src/Crons/DeleteSpamCron.php +++ b/src/Crons/DeleteSpamCron.php @@ -1,14 +1,27 @@ 'active', + // translators: Number of days inserted at placeholder. 'label' => esc_html__( 'Delete existing spam after %s days', 'antispam-bee' ), 'description' => esc_html__( 'Cleaning up the database from old entries', 'antispam-bee' ), 'sanitize' => function ( $value ) { diff --git a/src/GeneralOptions/IgnoreLinkbacks.php b/src/GeneralOptions/IgnoreLinkbacks.php index 144f028f..e0370975 100644 --- a/src/GeneralOptions/IgnoreLinkbacks.php +++ b/src/GeneralOptions/IgnoreLinkbacks.php @@ -1,18 +1,47 @@ type = $type; } + /** + * Get controllable items for this option. + * + * @param string $type Option type. + * @return array List of controllable items. + */ public static function get_controllables( $type = 'general' ) { - if ( $type !== 'general' ) { + if ( 'general' !== $type ) { return []; } diff --git a/src/Handlers/Linkback.php b/src/Handlers/Linkback.php index 6d4adf41..07291ffc 100644 --- a/src/Handlers/Linkback.php +++ b/src/Handlers/Linkback.php @@ -1,4 +1,9 @@ 'asb-marked-manually', ]; + /** + * Was DB update triggered? + * + * @var bool + */ private static $db_update_triggered = false; + /** + * Is DB at current version? + * + * @var bool|null + */ private static $db_version_is_current = null; /** @@ -55,7 +70,7 @@ private static function maybe_update_database() { update_option( 'antispambee_db_version', self::get_plugin_version() ); - if ( $version_from_db === null ) { + if ( null === $version_from_db ) { return; } @@ -165,6 +180,16 @@ private static function maybe_update_database() { } } + /** + * Convert multiselect values. + * Takes an array of selected keys, applies optional mapping and generated a new array using + * these values as keys and "on" as value. + * + * @param array $values Selected values. + * @param array $mapping Key mapping (optional). + * + * @return array Converted array of selected options. + */ private static function convert_multiselect_values( $values, $mapping = [] ) { if ( ! is_array( $values ) || empty( $values ) ) { return $values; @@ -182,6 +207,11 @@ private static function convert_multiselect_values( $values, $mapping = [] ) { return $new_array; } + /** + * Get plugin version. + * + * @return string + */ private static function get_plugin_version() { $meta = get_file_data( MAIN_PLUGIN_FILE, [ 'Version' => 'Version' ] ); diff --git a/src/Handlers/PostProcessors.php b/src/Handlers/PostProcessors.php index 6daf003a..7a4845f5 100644 --- a/src/Handlers/PostProcessors.php +++ b/src/Handlers/PostProcessors.php @@ -1,4 +1,9 @@ get_spam_reasons() ); if ( ! isset( $item['asb_marked_as_delete'] ) ) { diff --git a/src/Handlers/Rules.php b/src/Handlers/Rules.php index 17e7fb1a..685a750b 100644 --- a/src/Handlers/Rules.php +++ b/src/Handlers/Rules.php @@ -1,4 +1,9 @@ type = $type; } + /** + * Apply rules. + * + * @param array $item Item to apply rules to. + * @return bool Item identified as spam. + */ public function apply( $item ) { $item['reaction_type'] = $this->type; $rules = self::get( $this->type, true ); @@ -64,6 +101,13 @@ public function apply( $item ) { return $score > 0.0; } + /** + * Get applicable rules. + * + * @param string $type Reaction type. + * @param bool $only_active Get only active rules. + * @return array List of applicable rules. + */ public static function get( $type = null, $only_active = false ) { return self::filter( [ @@ -74,6 +118,13 @@ public static function get( $type = null, $only_active = false ) { ); } + /** + * Get controllable items. + * + * @param string $type Reaction type. + * @param bool $only_active Get only active items. + * @return array List of suitable controllables. + */ public static function get_controllables( $type = null, $only_active = false ) { return self::filter( [ @@ -84,7 +135,13 @@ public static function get_controllables( $type = null, $only_active = false ) { ); } - // Todo: Try to find a better suited method name. + /** + * Todo: Try to find a better suited method name. + * + * @param string|null $type Reaction type. + * @param bool $only_active Get only active rules. + * @return array List of applicable rules. + */ public static function get_spam_rules( $type = null, $only_active = false ) { return self::filter( [ @@ -95,15 +152,31 @@ public static function get_spam_rules( $type = null, $only_active = false ) { ); } + /** + * Filter items. + * + * @param array $options Filter options. + * @return array List of filtered elements. + */ private static function filter( $options ) { // Todo: discuss if our rules should be filterable or not. return ComponentsHelper::filter( apply_filters( 'antispam_bee_rules', [] ), $options ); } + /** + * Get spam reasons. + * + * @return array + */ public function get_spam_reasons() { return $this->spam_reasons; } + /** + * Get no-spam reasons. + * + * @return array + */ public function get_no_spam_reasons() { return $this->no_spam_reasons; } diff --git a/src/Helpers/ComponentsHelper.php b/src/Helpers/ComponentsHelper.php index d9fa8426..60d2f696 100644 --- a/src/Helpers/ComponentsHelper.php +++ b/src/Helpers/ComponentsHelper.php @@ -1,4 +1,9 @@ 'comment', - * 'only_active' => true, - * 'is_controllable' => false, - * ); + * Filter a list of components. + * + * @param array $components Components to filter. + * @param array $options { + * Filter options. + * + * @type string $reaction_type Reaction type (e.g. "comment"). + * @type bool $only_active Only active components. + * @type bool $is_controllable Is controllable type. + * } + * @return array Filtered list. */ public static function filter( $components, $options ) { $reaction_type = isset( $options['reaction_type'] ) ? $options['reaction_type'] : null; @@ -39,16 +51,16 @@ public static function filter( $components, $options ) { } } - // Filter by supported types like Comment, Linkback + // Filter by supported types like Comment, Linkback. $supported_types = $component::get_supported_types(); if ( ! is_null( $reaction_type ) && ! in_array( $reaction_type, $supported_types ) ) { continue; } - // Filters if the component implements the Controllable interface + // Filters if the component implements the Controllable interface. $conforms_to_controllable = InterfaceHelper::class_implements_interface( $component, Controllable::class ); - // Filters out components that are not active + // Filters out components that are not active. if ( $only_active ) { if ( $conforms_to_controllable && ! $component::is_active( $reaction_type ) ) { continue; diff --git a/src/Helpers/ContentTypeHelper.php b/src/Helpers/ContentTypeHelper.php index e7729e86..99c7cdc6 100644 --- a/src/Helpers/ContentTypeHelper.php +++ b/src/Helpers/ContentTypeHelper.php @@ -1,13 +1,27 @@ __( 'General', 'antispam-bee' ), diff --git a/src/Helpers/DashboardHelper.php b/src/Helpers/DashboardHelper.php index 4e57395a..cd144ff2 100644 --- a/src/Helpers/DashboardHelper.php +++ b/src/Helpers/DashboardHelper.php @@ -9,6 +9,8 @@ /** * Class DashboardHelper + * + * A helper providing some conditional functions for the dashboard. */ class DashboardHelper { diff --git a/src/Helpers/DataHelper.php b/src/Helpers/DataHelper.php index 10c56b29..8ebc905f 100644 --- a/src/Helpers/DataHelper.php +++ b/src/Helpers/DataHelper.php @@ -1,9 +1,24 @@ $value ) { @@ -28,6 +50,13 @@ public static function get_values_where_key_contains( $substrs, $data ) { return $results; } + /** + * Parse URL wrapper. + * + * @param string $url URL to parse. + * @param string $component URL component (default: "host"). + * @return string URL component. + */ public static function parse_url( $url, $component = 'host' ) { $parts = wp_parse_url( $url ); diff --git a/src/Helpers/DebugMode.php b/src/Helpers/DebugMode.php index 72763daf..e4d2a42a 100644 --- a/src/Helpers/DebugMode.php +++ b/src/Helpers/DebugMode.php @@ -1,26 +1,52 @@ [ 'rule_asb_regexp_active' => 'on', @@ -28,6 +42,11 @@ class Settings { // @todo: check if code is PHP 7 compatible const OPTION_NAME = 'antispam_bee_options'; + /** + * Initialize. + * + * @return void + */ public static function init() { add_action( 'update_option_' . self::OPTION_NAME, @@ -37,11 +56,15 @@ public static function init() { ); } + /** + * Update cache. + * + * @param mixed $old_value The old option value. + * @param mixed $value The new option value. + * @return void + */ public static function update_cache( $old_value, $value ) { - wp_cache_set( - self::OPTION_NAME, - $value - ); + wp_cache_set( self::OPTION_NAME, $value ); } /** @@ -85,10 +108,10 @@ public static function get_option( $option_name, $type = 'general' ) { /** * Get value from array by path. * - * @param string $path Dot-separated path to the wanted value. - * @param array $array + * @param string $path Dot-separated path to the wanted value. + * @param array $array Options array. * - * @return null|mixed + * @return null|mixed Value at given path, if present. */ public static function get_array_value_by_path( $path, $array ) { if ( ! is_array( $array ) ) { @@ -158,7 +181,7 @@ public static function update_option( $field, $value ) { * Check and return an array key * * @param array $array Array with values. - * @param string $key Name of the key. + * @param string $key Name of the key. * * @return mixed Value of the requested key. * @since 2.10.0 Only return `null` if option does not exist. @@ -173,6 +196,13 @@ public static function get_key( $array, $key ) { return $array[ $key ]; } + /** + * Remove array item(s) by key. + * + * @param string $path Dot-separated path to the wanted value. + * @param array $array Array to filter. + * @return void + */ public static function remove_array_key_by_path( $path, &$array ) { if ( ! is_array( $array ) ) { return; @@ -197,6 +227,12 @@ public static function remove_array_key_by_path( $path, &$array ) { } } + /** + * Get path parts from dot-separated notation. + * + * @param mixed $path Dot-separated path to the wanted value. + * @return string[] Path parts. + */ private static function get_path_parts( $path ) { if ( ! is_string( $path ) ) { return []; @@ -210,6 +246,14 @@ private static function get_path_parts( $path ) { return $path_parts; } + /** + * Set an array item at given path. + * + * @param string $path Dot-separated path to the wanted value. + * @param mixed $sanitized Sanitized value. + * @param array $options Options array to process. + * @return void + */ public static function set_array_value_by_path( $path, $sanitized, &$options ) { if ( ! is_array( $options ) ) { return; diff --git a/src/Helpers/SpamReasonTextHelper.php b/src/Helpers/SpamReasonTextHelper.php index e307da48..2b4c32fd 100644 --- a/src/Helpers/SpamReasonTextHelper.php +++ b/src/Helpers/SpamReasonTextHelper.php @@ -1,17 +1,41 @@