Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php
/**
* Class Premium_Only_Function_Check.
*
* @package plugin-check
*/

namespace WordPress\Plugin_Check\Checker\Checks\Plugin_Repo;

use WordPress\Plugin_Check\Checker\Check_Categories;
use WordPress\Plugin_Check\Checker\Check_Result;
use WordPress\Plugin_Check\Checker\Checks\Abstract_File_Check;
use WordPress\Plugin_Check\Traits\Amend_Check_Result;
use WordPress\Plugin_Check\Traits\Stable_Check;

/**
* Check to detect functions ending in __premium_only.
*
* @since x.x.x
*/
class Premium_Only_Function_Check extends Abstract_File_Check {

use Amend_Check_Result;
use Stable_Check;

/**
* Gets the categories for the check.
*
* Every check must have at least one category.
*
* @since x.x.x
*
* @return array The categories for the check.
*/
public function get_categories() {
return array( Check_Categories::CATEGORY_PLUGIN_REPO );
}

/**
* Amends the given result by running the check on the given list of files.
*
* @since x.x.x
*
* @param Check_Result $result The check result to amend.
* @param array $files List of absolute file paths.
*/
protected function check_files( Check_Result $result, array $files ) {
$php_files = self::filter_files_by_extension( $files, 'php' );
$matches = self::files_preg_match_all( '/\bfunction\s+[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*__premium_only\s*\(/i', $php_files );

if ( ! empty( $matches ) ) {
foreach ( $matches as $match ) {
$this->add_result_error_for_file(
$result,
__( 'Function declarations ending in __premium_only look like premium/pro-only code and should not be included in a WordPress.org plugin.', 'plugin-check' ),
'premium_only_function_found',
$match['file'],
$match['line'],
$match['column'],
'https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/'
);
}
}
}

/**
* Gets the description for the check.
*
* Every check must have a short description explaining what the check does.
*
* @since x.x.x
*
* @return string Description.
*/
public function get_description(): string {
return __( 'Detects function declarations ending in __premium_only.', 'plugin-check' );
}

/**
* Gets the documentation URL for the check.
*
* Every check must have a URL with further information about the check.
*
* @since x.x.x
*
* @return string The documentation URL.
*/
public function get_documentation_url(): string {
return __( 'https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/', 'plugin-check' );
}
}
2 changes: 2 additions & 0 deletions includes/Checker/Default_Check_Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*/
class Default_Check_Repository extends Empty_Check_Repository {


/**
* True if the class was fully initialized.
*
Expand Down Expand Up @@ -105,6 +106,7 @@ private function register_default_checks() {
'external_admin_menu_links' => new Checks\Plugin_Repo\External_Admin_Menu_Links_Check(),
'wp_functions_compatibility' => new Checks\Plugin_Repo\WP_Functions_Compatibility_Check(),
'ai_provider' => new Checks\General\AI_Provider_Check(),
'premium_only_function' => new Checks\Plugin_Repo\Premium_Only_Function_Check(),
)
);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php
/**
* Plugin Name: Premium Only Function Test
* Description: Test plugin containing functions named with the __premium_only suffix.
* Version: 1.0.0
*/

if ( ! defined( 'ABSPATH' ) ) {
exit;
}

function poft_register_settings__premium_only() {
register_setting( 'poft_settings', 'poft_enabled' );
}

function poft_admin_notice__premium_only() {
echo '<div class="notice notice-info"><p>Premium-only test notice.</p></div>';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php
/**
* Plugin Name: Premium Only Function Clean Test
* Description: Test plugin containing standard functions without __premium_only suffix.
* Version: 1.0.0
*/

if ( ! defined( 'ABSPATH' ) ) {
exit;
}

function poft_register_settings() {
register_setting( 'poft_settings', 'poft_enabled' );
}

function poft_admin_notice() {
echo '<div class="notice notice-info"><p>Standard test notice.</p></div>';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php
/**
* Tests for the Premium_Only_Function_Check class.
*
* @package plugin-check
*/

use WordPress\Plugin_Check\Checker\Check_Context;
use WordPress\Plugin_Check\Checker\Check_Result;
use WordPress\Plugin_Check\Checker\Checks\Plugin_Repo\Premium_Only_Function_Check;

class Premium_Only_Function_Check_Tests extends WP_UnitTestCase {

public function test_run_with_errors() {
$check = new Premium_Only_Function_Check();
$check_context = new Check_Context( UNIT_TESTS_PLUGIN_DIR . 'test-plugin-premium-only-function-with-errors/load.php' );
$check_result = new Check_Result( $check_context );

$check->run( $check_result );

$errors = $check_result->get_errors();

$this->assertNotEmpty( $errors );
$this->assertArrayHasKey( 'load.php', $errors );
$this->assertSame( 2, $check_result->get_error_count() );

$this->assertArrayHasKey( 12, $errors['load.php'] );
$this->assertArrayHasKey( 16, $errors['load.php'] );
$this->assertSame( 'premium_only_function_found', $errors['load.php'][12][1][0]['code'] );
$this->assertSame( 'premium_only_function_found', $errors['load.php'][16][1][0]['code'] );
}

public function test_run_without_errors() {
$check = new Premium_Only_Function_Check();
$check_context = new Check_Context( UNIT_TESTS_PLUGIN_DIR . 'test-plugin-premium-only-function-without-errors/load.php' );
$check_result = new Check_Result( $check_context );

$check->run( $check_result );

$errors = $check_result->get_errors();

$this->assertEmpty( $errors );
$this->assertSame( 0, $check_result->get_error_count() );
}
}
Loading