$result Result row. * @return string */ public static function label( array $result ): string { $status = (string) ( $result['status'] ?? Status::PENDING ); if ( Status::is_critical( $result ) ) { return __( 'Closed: security issue', 'brachmelder' ); } switch ( $status ) { case Status::CLOSED: return __( 'Closed', 'brachmelder' ); case Status::ABANDONED: return __( 'Abandoned', 'brachmelder' ); case Status::OUTDATED: return __( 'Outdated', 'brachmelder' ); case Status::OK: return __( 'OK', 'brachmelder' ); case Status::UNKNOWN: return __( 'Not checkable', 'brachmelder' ); case Status::ERROR: return __( 'Check failed', 'brachmelder' ); default: return __( 'Not checked yet', 'brachmelder' ); } } /** * Explanation for a status. * * @param array $result Result row. * @return array{meaning: string, risk: string, todo: string} */ public static function explain( array $result ): array { $status = (string) ( $result['status'] ?? Status::PENDING ); if ( Status::is_critical( $result ) ) { return array( 'meaning' => __( 'WordPress.org has closed this plugin because of a security issue. It can no longer be downloaded there and will not receive any more updates.', 'brachmelder' ), 'risk' => __( 'As long as the plugin is installed, attackers may be able to exploit the vulnerability, for example to read customer data or to take over your website.', 'brachmelder' ), 'todo' => __( 'Deactivate and delete the plugin as soon as possible and replace it with an actively maintained alternative. If your shop depends on it, ask your web developer for help today.', 'brachmelder' ), ); } switch ( $status ) { case Status::CLOSED: return array( 'meaning' => __( 'WordPress.org has closed this plugin. It can no longer be downloaded there and will not receive any more updates.', 'brachmelder' ), 'risk' => __( 'Even without a known security issue, nobody will fix future problems. The risk of errors and security gaps grows with every WordPress, WooCommerce or PHP update.', 'brachmelder' ), 'todo' => __( 'Check whether you still need the plugin. If so, plan to replace it with an actively maintained alternative within the next few weeks.', 'brachmelder' ), ); case Status::ABANDONED: return array( 'meaning' => __( 'The plugin has not been updated for more than two years.', 'brachmelder' ), 'risk' => __( 'Security gaps that are discovered may never be fixed. Problems with new WordPress, WooCommerce or PHP versions become more likely.', 'brachmelder' ), 'todo' => __( 'Check whether you still need the plugin. If so, look for an actively maintained alternative and plan the switch.', 'brachmelder' ), ); case Status::OUTDATED: return array( 'meaning' => __( 'The developer has not confirmed that the plugin works with the last three major WordPress versions.', 'brachmelder' ), 'risk' => __( 'The plugin may well work fine. It is, however, a sign that maintenance is slowing down, and errors after WordPress updates are more likely.', 'brachmelder' ), 'todo' => __( 'No need to act right away. Test your website after updates and keep an eye on the plugin.', 'brachmelder' ), ); case Status::OK: return array( 'meaning' => __( 'The plugin is actively maintained on WordPress.org.', 'brachmelder' ), 'risk' => __( 'No known risk.', 'brachmelder' ), 'todo' => __( 'Keep installing updates regularly.', 'brachmelder' ), ); case Status::UNKNOWN: return array( 'meaning' => __( 'This plugin is not listed on WordPress.org. Usually it is a premium plugin or one that was developed specifically for your website.', 'brachmelder' ), 'risk' => __( 'Brachmelder cannot assess it. This is not a warning.', 'brachmelder' ), 'todo' => __( 'Make sure you receive updates from the vendor, for example through a valid licence.', 'brachmelder' ), ); case Status::ERROR: return array( 'meaning' => __( 'WordPress.org could not be reached when this plugin was checked.', 'brachmelder' ), 'risk' => __( 'No assessment is possible at the moment.', 'brachmelder' ), 'todo' => __( 'Nothing to do. Brachmelder will try again automatically.', 'brachmelder' ), ); default: return array( 'meaning' => __( 'This plugin has not been checked yet.', 'brachmelder' ), 'risk' => __( 'No assessment is possible yet.', 'brachmelder' ), 'todo' => __( 'Click “Check now” or wait for the automatic daily check.', 'brachmelder' ), ); } } /** * Human readable reason for closing a plugin. * * @param array $result Result row. * @return string */ public static function closed_reason( array $result ): string { switch ( (string) ( $result['reason'] ?? '' ) ) { case 'security-issue': return __( 'Security issue', 'brachmelder' ); case 'author-request': return __( 'At the request of the developer', 'brachmelder' ); case 'guideline-violation': return __( 'Violation of the WordPress.org guidelines', 'brachmelder' ); case 'licensing-trademark-violation': return __( 'Licence or trademark violation', 'brachmelder' ); case 'merged-into-core': return __( 'Function is now part of WordPress', 'brachmelder' ); case 'unused': return __( 'No longer in use', 'brachmelder' ); case 'duplicate': return __( 'Duplicate of another plugin', 'brachmelder' ); default: return __( 'No reason given', 'brachmelder' ); } } /** * Texts for the PHP support check. * * @param array{status: string, branch: string, end: string, days_left: int} $php PhpSupport::evaluate() result. * @param string $recommended Recommended PHP branch. * @return array{title: string, text: string, todo: string} */ public static function php( array $php, string $recommended ): array { $end = '' !== $php['end'] ? wp_date( (string) get_option( 'date_format' ), (int) strtotime( $php['end'] . ' 12:00:00 UTC' ) ) : ''; switch ( $php['status'] ) { case PhpSupport::ENDED: return array( /* translators: %s: PHP version, e.g. 8.1 */ 'title' => sprintf( __( 'PHP %s no longer receives security updates', 'brachmelder' ), $php['branch'] ), 'text' => '' !== $end /* translators: 1: PHP version, 2: date */ ? sprintf( __( 'Your server runs PHP %1$s. Security support for this version ended on %2$s. Newly discovered security issues in PHP itself are no longer fixed.', 'brachmelder' ), $php['branch'], $end ) /* translators: %s: PHP version */ : sprintf( __( 'Your server runs PHP %s. This version has not received security updates for a long time.', 'brachmelder' ), $php['branch'] ), /* translators: %s: recommended PHP version, e.g. 8.3 */ 'todo' => sprintf( __( 'Ask your hosting provider or web developer to switch to PHP %s or newer. Usually this is a setting in your hosting control panel. Test your website and checkout afterwards.', 'brachmelder' ), $recommended ), ); case PhpSupport::ENDING: return array( /* translators: 1: PHP version, 2: date */ 'title' => sprintf( __( 'Security support for PHP %1$s ends on %2$s', 'brachmelder' ), $php['branch'], $end ), 'text' => sprintf( /* translators: 1: PHP version, 2: date, 3: number of days */ _n( 'Your server runs PHP %1$s. This version receives security updates only until %2$s, that is for %3$d more day.', 'Your server runs PHP %1$s. This version receives security updates only until %2$s, that is for %3$d more days.', $php['days_left'], 'brachmelder' ), $php['branch'], $end, $php['days_left'] ), /* translators: %s: recommended PHP version, e.g. 8.3 */ 'todo' => sprintf( __( 'Plan the switch to PHP %s or newer before this date. Ask your hosting provider or web developer and test your website and checkout afterwards.', 'brachmelder' ), $recommended ), ); case PhpSupport::SUPPORTED: return array( /* translators: %s: PHP version */ 'title' => sprintf( __( 'PHP %s is supported', 'brachmelder' ), $php['branch'] ), 'text' => '' !== $end /* translators: 1: PHP version, 2: date */ ? sprintf( __( 'Your server runs PHP %1$s, which receives security updates until %2$s.', 'brachmelder' ), $php['branch'], $end ) /* translators: %s: PHP version */ : sprintf( __( 'Your server runs PHP %s, a current version.', 'brachmelder' ), $php['branch'] ), 'todo' => __( 'Nothing to do.', 'brachmelder' ), ); default: return array( 'title' => __( 'PHP version unknown', 'brachmelder' ), 'text' => __( 'Brachmelder could not determine when security support for your PHP version ends.', 'brachmelder' ), 'todo' => __( 'Ask your hosting provider which PHP version you use and how long it is supported.', 'brachmelder' ), ); } } }