: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
$prefix = str_replace( '-', '_', $prefix );
$addon_load_function = '';
// Find addon load function.
foreach ( $callbacks as $callbacks_at_priority ) {
foreach ( $callbacks_at_priority as $key => $callback ) {
if ( strpos( $key, $prefix ) === 0 ) {
$addon_load_function = $key;
return $addon_load_function;
* Normalize version-based requirement.
* @param string $key Requirements key.
private function normalize_version_requirement( string $key ): array {
if ( ! isset( $this->addon_requirements[ $key ] ) ) {
$this->addon_requirements[ $key ] = [];
$requirement = (array) $this->addon_requirements[ $key ];
$version = isset( $requirement[0] ) ?
array_map( 'trim', (array) $requirement[0] ) :
$version = isset( $requirement[ self::VERSION ] ) ?
array_map( 'trim', (array) $requirement[ self::VERSION ] ) :
$compare = isset( $requirement[ self::COMPARE ] ) ?
array_map( 'trim', (array) $requirement[ self::COMPARE ] ) :
[ self::COMPARE_DEFAULT ];
$compare = array_pad( $compare, count( $version ), self::COMPARE_DEFAULT );
self::VERSION => $version,
self::COMPARE => $compare,
$this->addon_requirements[ $key ] = $requirement;
* Normalize array-based requirement.
* @param string $key Requirements key.
private function normalize_array_requirement( string $key ): array {
if ( ! isset( $this->addon_requirements[ $key ] ) ) {
$this->addon_requirements[ $key ] = [];
$requirement = $this->addon_requirements[ $key ];
if ( is_string( $requirement ) ) {
$requirement = explode( ',', $requirement );
if ( ! is_array( $requirement ) ) {
$requirement = array_map( 'trim', $requirement );
$this->addon_requirements[ $key ] = $requirement;
private function validate_php(): bool {
$php = $this->normalize_version_requirement( self::PHP );
! $this->version_compare( PHP_VERSION, $php )
$this->not_validated[ $this->basename ][] = self::PHP;
* Validate php extensions.
private function validate_ext(): bool {
foreach ( $this->normalize_array_requirement( self::EXT ) as $extension ) {
if ( ! extension_loaded( $extension ) ) {
$this->not_validated[ $this->basename ][] = self::EXT;
private function validate_wp(): bool {
$wp = $this->normalize_version_requirement( self::WP );
! $this->version_compare( $wp_version, $wp )
$this->not_validated[ $this->basename ][] = self::WP;
private function validate_wpforms(): bool {
$wpforms = $this->normalize_version_requirement( self::WPFORMS );
if ( empty( $wpforms ) ) {
if ( $wpforms[ self::VERSION ] === self::WPFORMS_DEV_VERSION_IN_ADDON ) {
$wpforms[ self::VERSION ] &&
! $this->version_compare( wpforms()->version, $wpforms )
$this->not_validated[ $this->basename ][] = self::WPFORMS;
* @param string $version Version to compare.
* @param array $requirement Requirement.
private function version_compare( string $version, array $requirement ): bool {
$compare_arr = $this->get_compare_array( $requirement );
foreach ( $compare_arr as $version2 => $compare ) {
$result = version_compare( $version, $version2, $compare );
private function validate_license(): bool {
$license = $this->normalize_array_requirement( self::LICENSE );
if ( empty( $license ) ) {
if ( ! in_array( wpforms_get_license_type(), $license, true ) ) {
$this->not_validated[ $this->basename ][] = self::LICENSE;
private function validate_addon(): bool {
$addon = $this->normalize_version_requirement( self::ADDON );
$addon_version_constant = trim( $this->addon_requirements[ self::ADDON_VERSION_CONSTANT ] );
if ( empty( $addon ) || empty( $addon_version_constant ) ) {
if ( preg_grep( '/{.+_VERSION}/', $addon[ self::VERSION ] ) ) {
$addon[ self::VERSION ] &&
! $this->version_compare( constant( $addon_version_constant ), $addon )
$this->not_validated[ $this->basename ][] = self::ADDON;
* Deactivate not validated addons.
public function deactivate() {
if ( ! self::DEACTIVATE_IF_NOT_MET ) {
if ( empty( $this->not_validated ) ) {
// phpcs:disable WordPress.Security.NonceVerification.Recommended
unset( $_GET['activate'] );
if ( empty( $this->validated ) ) {
unset( $_GET['activate-multi'] );
// phpcs:enable WordPress.Security.NonceVerification.Recommended
require_once ABSPATH . 'wp-admin/includes/plugin.php';
foreach ( $this->not_validated as $basename => $errors ) {
if ( $errors === [ 'license' ] ) {
deactivate_plugins( $basename );
public function show_notices() {
foreach ( $this->get_notices() as $notice ) {
$this->show_notice( $notice );
* @noinspection HtmlUnknownTarget
public function get_notices(): array {
if ( empty( $this->not_validated ) ) {
/* translators: %s - required PHP version. */
__( '<a href="%s" target="_blank" rel="noopener noreferrer">Read more</a> for additional information.', 'wpforms-lite' ),
esc_url( wpforms_utm_link( 'https://wpforms.com/docs/supported-php-version/', 'all-plugins', 'Addon PHP Notice' ) )
foreach ( $this->not_validated as $basename => $errors ) {
$message = $this->get_validation_message( $errors, $basename );
$plugin_headers = get_plugin_data( $this->requirements[ $basename ]['file'] );
/* translators: translators: %1$s - WPForms addon name, %2$d - requirements message. */
__( 'The %1$s addon requires %2$s to work.', 'wpforms-lite' ),
if ( self::SHOW_PHP_NOTICE && in_array( self::PHP, $errors, true ) ) {
$notice .= ' ' . $read_more;
* Filter the requirements notice.
* @param string $notice Notice.
* @param array $errors Validation errors.
* @param string $basename Plugin basename.
* @param array $requirements Addon requirements.
$notice = apply_filters( 'wpforms_requirements_notice', $notice, $errors, $basename, $this->requirements[ $basename ] );
* Get a validation message.
* @param array $errors Validation errors.
* @param string $basename Plugin basename.
private function get_validation_message( array $errors, string $basename ): string {
$messages[] = $this->get_php_validation_message( $errors, $basename );
$messages[] = $this->get_ext_validation_message( $errors, $basename );
$messages[] = $this->get_wp_validation_message( $errors, $basename );
$messages[] = $this->get_wpforms_validation_message( $errors, $basename );
$messages[] = $this->get_license_validation_message( $errors, $basename );
$messages[] = $this->get_addon_validation_message( $errors, $basename );
$messages = array_filter( $messages );
return $this->list_array( $messages );
* Get PHP validation message.
* @param array $errors Validation errors.
* @param string $basename Plugin basename.
private function get_php_validation_message( array $errors, string $basename ): string {
if ( self::SHOW_PHP_NOTICE && in_array( self::PHP, $errors, true ) ) {
return 'PHP ' . $this->list_version( $this->requirements[ $basename ][ self::PHP ] );
* Get EXT validation message.
* @param array $errors Validation errors.
* @param string $basename Plugin basename.
private function get_ext_validation_message( array $errors, string $basename ): string {
if ( self::SHOW_EXT_NOTICE && in_array( self::EXT, $errors, true ) ) {
$extension = $this->list_array( $this->requirements[ $basename ][ self::EXT ] );
/* translators: %s - PHP extension name(s). */
count( $this->requirements[ $basename ][ self::EXT ] ),
* Get WP validation message.
* @param array $errors Validation errors.
* @param string $basename Plugin basename.
private function get_wp_validation_message( array $errors, string $basename ): string {
if ( self::SHOW_WP_NOTICE && in_array( self::WP, $errors, true ) ) {
return 'WordPress ' . $this->list_version( $this->requirements[ $basename ][ self::WP ] );
* Get WPFORMS validation message.
* @param array $errors Validation errors.
* @param string $basename Plugin basename.
private function get_wpforms_validation_message( array $errors, string $basename ): string {
if ( self::SHOW_WPFORMS_NOTICE && in_array( self::WPFORMS, $errors, true ) ) {
return 'WPForms ' . $this->list_version( $this->requirements[ $basename ][ self::WPFORMS ] );