diff --git a/.editorconfig b/.editorconfig index 2708ec4..5087309 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,19 +1,13 @@ -# EditorConfig helps maintain consistent coding styles for developers working on the same project across various editors and IDEs. -# See https://editorconfig.org. - root = true [*] charset = utf-8 end_of_line = lf -indent_size = 2 -indent_style = space -insert_final_newline = true trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 2 -[*.php] +[*.{html,php}] indent_size = 4 indent_style = tab - -[*.xml] -indent_size = 4 diff --git a/.gitattributes b/.gitattributes index f7c0249..e4189e2 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,15 +2,16 @@ # Exclude these files from release archives. # # This will also make the files unavailable when using Composer with `--prefer-dist`. -# If you develop using Composer, use `--prefer-source`. # # Via WPCS. # -/phpcs.xml export-ignore -/phpunit.xml export-ignore /.github export-ignore -/.php-cs-fixer.dist.php export-ignore +/.phpcs.xml export-ignore +/.phpcs export-ignore +/phpunit.xml export-ignore /tests export-ignore +/configure.php export-ignore +/Makefile export-ignore # # Auto detect text files and perform LF normalization. diff --git a/.github/workflows/all-pr-tests.yml b/.github/workflows/all-pr-tests.yml new file mode 100644 index 0000000..3a10dc2 --- /dev/null +++ b/.github/workflows/all-pr-tests.yml @@ -0,0 +1,45 @@ +name: "All Pull Request Tests" + +on: + pull_request: + branches: + - main + types: [opened, synchronize, reopened, ready_for_review] + +jobs: + # We use a single job to ensure that all steps run in the same environment and + # reduce the number of minutes used. + pr-tests: + # Don't run on draft PRs + if: github.event.pull_request.draft == false + # Timeout after 10 minutes + timeout-minutes: 10 + # Define a matrix of PHP/WordPress versions to test against + strategy: + matrix: + php: [8.2, 8.3] + wordpress: ["latest"] + multisite: [false, true] + runs-on: ubuntu-latest + # Cancel any existing runs of this workflow + concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref }}-P${{ matrix.php }}-WP${{ matrix.wordpress }}-MS${{ matrix.multisite }} + cancel-in-progress: true + # Name the job in the matrix + name: "PR Tests PHP ${{ matrix.php }} WordPress ${{ matrix.wordpress }} multisite ${{ matrix.multisite }}" + steps: + - uses: actions/checkout@v4 + + - name: Run General Tests + # See https://github.com/alleyinteractive/action-test-general for more options + uses: alleyinteractive/action-test-general@develop + + - name: Run PHP Tests + # See https://github.com/alleyinteractive/action-test-php for more options + uses: alleyinteractive/action-test-php@develop + with: + php-version: '${{ matrix.php }}' + audit-command: 'composer audit --no-dev --ansi --no-interaction' + wordpress-version: '${{ matrix.wordpress }}' + wordpress-multisite: '${{ matrix.multisite }}' + skip-wordpress-install: 'true' diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml deleted file mode 100644 index bd66de4..0000000 --- a/.github/workflows/coding-standards.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: Coding Standards - -on: - pull_request: - branches: - - main - types: [opened, synchronize, reopened, ready_for_review] - -jobs: - coding-standards: - if: github.event.pull_request.draft == false - uses: alleyinteractive/.github/.github/workflows/php-coding-standards.yml@main diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml deleted file mode 100644 index de6d38b..0000000 --- a/.github/workflows/unit-test.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Testing Suite - -on: - pull_request: - branches: - - main - types: [opened, synchronize, reopened, ready_for_review] - -jobs: - php-tests: - if: github.event.pull_request.draft == false - strategy: - matrix: - php: ["8.2", "8.1", "8.0"] - wordpress: ["latest"] - multisite: [false, true] - uses: alleyinteractive/.github/.github/workflows/php-tests.yml@main - with: - php: ${{ matrix.php }} - wordpress: ${{ matrix.wordpress }} - multisite: ${{ matrix.multisite }} diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php deleted file mode 100644 index ff95cb5..0000000 --- a/.php-cs-fixer.dist.php +++ /dev/null @@ -1,36 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - * - * @package wp-find-one - */ - -$finder = PhpCsFixer\Finder::create()->in( - [ - __DIR__ . '/src/', - __DIR__ . '/tests/', - ] -); - -$config = new PhpCsFixer\Config(); -$config->setRules( - [ - '@PHP81Migration' => true, - // Enabled by '@PHP81Migration' but generates invalid spacing for WordPress. - 'method_argument_space' => false, - - 'final_class' => true, - 'native_constant_invocation' => true, - 'native_function_casing' => true, - 'native_function_invocation' => true, - 'native_function_type_declaration_casing' => true, - ] -); -$config->setFinder( $finder ); - -return $config; diff --git a/.phpcs.xml b/.phpcs.xml new file mode 100644 index 0000000..2998e4b --- /dev/null +++ b/.phpcs.xml @@ -0,0 +1,43 @@ + + + PHP_CodeSniffer standard for alleyinteractive/wp-find-one. + + + + + + + + src/ + tests/ + vendor/ + + + + + + + + + + + + + + + + + + + + + + + + tests/* + + diff --git a/CHANGELOG.md b/CHANGELOG.md index f9f211e..1eeb13e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ This library adheres to [Semantic Versioning](https://semver.org/) and [Keep a C Nothing yet. +## 3.0.0 + +### Changed + +- The minimum PHP version is now 8.2. + ## 2.0.0 ### Removed diff --git a/README.md b/README.md index 93857c8..fbad800 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ The `find_one()` family of functions are wrappers for common WordPress retrieval Install the latest version with: ```bash -$ composer require alleyinteractive/wp-find-one +composer require alleyinteractive/wp-find-one ``` ## Basic usage diff --git a/composer.json b/composer.json index e175f0e..9554226 100644 --- a/composer.json +++ b/composer.json @@ -1,49 +1,72 @@ { "name": "alleyinteractive/wp-find-one", "description": "Query for and return one WordPress post, term, or other object, bypassing intermediate arrays.", - "type": "library", "license": "GPL-2.0-or-later", + "type": "library", "authors": [ { "name": "Alley", "email": "info@alley.com" } ], + "require": { + "php": "^8.2" + }, + "require-dev": { + "alleyinteractive/alley-coding-standards": "^2.0", + "ergebnis/composer-normalize": "^2.44", + "mantle-framework/testkit": "^1.2", + "szepeviktor/phpstan-wordpress": "^1.3" + }, + "minimum-stability": "dev", + "prefer-stable": true, "autoload": { "files": [ - "src/alley/wp/find-one.php", - "src/alley/wp/find-result.php" + "src/find-one.php", + "src/find-result.php" ] }, + "autoload-dev": { + "psr-4": { + "Alley\\WP\\Tests\\": "tests/" + } + }, "config": { "allow-plugins": { "alleyinteractive/composer-wordpress-autoloader": true, - "dealerdirect/phpcodesniffer-composer-installer": true + "dealerdirect/phpcodesniffer-composer-installer": true, + "ergebnis/composer-normalize": true }, - "lock": false - }, - "require": { - "php": "^8.0" - }, - "require-dev": { - "alleyinteractive/alley-coding-standards": "^1.0.0", - "friendsofphp/php-cs-fixer": "^3.8", - "mantle-framework/testkit": "^0.9" - }, - "scripts": { - "fixer": "php-cs-fixer -v fix --allow-risky=yes", - "phpcbf": "phpcbf", - "phpcs": "phpcs", - "phpunit": "phpunit" + "lock": false, + "sort-packages": true }, "extra": { + "composer-normalize": { + "indent-size": 2, + "indent-style": "space" + }, "wordpress-autoloader": { "autoload": { - "Alley\\": "src/alley/" - }, - "autoload-dev": { - "Alley\\": "tests/alley/" + "Alley\\WP\\": "src/" } } + }, + "scripts": { + "pre-install-cmd": [ + "@tidy" + ], + "post-install-cmd": [ + "@tidy" + ], + "phpcbf": "phpcbf", + "phpcs": "phpcs", + "phpstan": "phpstan -v --memory-limit=512M", + "phpunit": "phpunit", + "test": [ + "@phpcs", + "@phpstan", + "@phpunit" + ], + "tidy": "[ $COMPOSER_DEV_MODE -eq 0 ] || composer normalize" } -} +} \ No newline at end of file diff --git a/phpcs.xml b/phpcs.xml deleted file mode 100644 index f5a5dc8..0000000 --- a/phpcs.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - PHP_CodeSniffer standard for alleyinteractive/wp-find-one. - - src/ - tests/ - vendor/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - tests/ - - - - - diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..f8d6303 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,9 @@ +includes: + - vendor/szepeviktor/phpstan-wordpress/extension.neon + +parameters: + # Level 9 is the highest level + level: max + + paths: + - src/ diff --git a/phpunit.xml b/phpunit.xml index 90707de..1521c9f 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,12 +1,20 @@ + - - tests/alley/wp/ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + bootstrap="tests/bootstrap.php" + colors="true" + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.2/phpunit.xsd" + cacheDirectory=".phpunit.result.cache"> + + + tests/Feature + + tests/Unit + + + + + + diff --git a/src/alley/wp/find-one.php b/src/find-one.php similarity index 72% rename from src/alley/wp/find-one.php rename to src/find-one.php index 8224c33..0e6cc53 100644 --- a/src/alley/wp/find-one.php +++ b/src/find-one.php @@ -15,7 +15,7 @@ /** * Query for and return one post. * - * @param array $args Query arguments. + * @param mixed[] $args Query arguments. * @return mixed|null A \WP_Post object, an alternate return type if requested * in $args, or null. */ @@ -23,7 +23,8 @@ function find_one_post( array $args ) { return find_result( \WP_Post::class, get_posts( // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.get_posts_get_posts - array_merge( + // Not attempting to re-enumerate all documented arguments. + array_merge( // @phpstan-ignore argument.type $args, [ 'posts_per_page' => 1, @@ -37,7 +38,7 @@ function find_one_post( array $args ) { /** * Query for and return one term. * - * @param array $args Query arguments. + * @param mixed[] $args Query arguments. * @return mixed|null A \WP_Term object, an alternate return type if requested * in $args, or null. */ @@ -45,7 +46,8 @@ function find_one_term( array $args ) { return find_result( \WP_Term::class, get_terms( - array_merge( + // Not attempting to re-enumerate all documented arguments. + array_merge( // @phpstan-ignore argument.type $args, [ 'number' => 1, @@ -58,7 +60,7 @@ function find_one_term( array $args ) { /** * Query for and return one comment. * - * @param array $args Query arguments. + * @param mixed[] $args Query arguments. * @return mixed|null A \WP_Comment object, an alternate return type if * requested in $args, or null. */ @@ -66,7 +68,8 @@ function find_one_comment( array $args ) { return find_result( \WP_Comment::class, get_comments( - array_merge( + // Not attempting to re-enumerate all documented arguments. + array_merge( // @phpstan-ignore argument.type $args, [ 'number' => 1, @@ -79,7 +82,7 @@ function find_one_comment( array $args ) { /** * Query for and return one user. * - * @param array $args Query arguments. + * @param mixed[] $args Query arguments. * @return mixed|null A \WP_User object, an alternate return type if requested * in $args, or null. */ @@ -87,7 +90,8 @@ function find_one_user( array $args ) { return find_result( \WP_User::class, get_users( - array_merge( + // Not attempting to re-enumerate all documented arguments. + array_merge( // @phpstan-ignore argument.type $args, [ 'number' => 1, @@ -100,7 +104,7 @@ function find_one_user( array $args ) { /** * Query for and return one site. * - * @param array $args Query arguments. + * @param mixed[] $args Query arguments. * @return mixed|null A \WP_Site object, an alternate return type if requested * in $args, or null. */ @@ -108,7 +112,8 @@ function find_one_site( array $args ) { return find_result( \WP_Site::class, get_sites( - array_merge( + // Not attempting to re-enumerate all documented arguments. + array_merge( // @phpstan-ignore argument.type $args, [ 'number' => 1, diff --git a/src/alley/wp/find-result.php b/src/find-result.php similarity index 61% rename from src/alley/wp/find-result.php rename to src/find-result.php index 576ba8a..a1deed5 100644 --- a/src/alley/wp/find-result.php +++ b/src/find-result.php @@ -16,14 +16,14 @@ * Returns the first item in the given array if the item is an instance of a * specific class or is a non-object. * - * @param string $class If the result plucked from $results is an object, the - * name of the class the object must be an instance of - * for it to be returned. - * @param array $results The array of results from the WordPress query - * function to retrieve the result from. + * @param string $class If the result plucked from $results is an object, the + * name of the class the object must be an instance of + * for it to be returned. + * @param mixed|mixed[] $results The array of results from the WordPress query + * function to retrieve the result from. * @return mixed|null An object of the given $class; a non-object if the item - * plucked from $results is not an object; null if no - * result is found. + * plucked from $results is not an object; null if no + * result is found. */ function find_result( string $class, $results ) { if ( ! $results || ! \is_array( $results ) ) { diff --git a/tests/Feature/.gitkeep b/tests/Feature/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/alley/wp/fixtures/class-noop.php b/tests/Fixtures/Noop.php similarity index 92% rename from tests/alley/wp/fixtures/class-noop.php rename to tests/Fixtures/Noop.php index 9eb21d5..5a48ead 100644 --- a/tests/alley/wp/fixtures/class-noop.php +++ b/tests/Fixtures/Noop.php @@ -10,7 +10,7 @@ * @package wp-find-one */ -namespace Alley\WP\Fixtures; +namespace Alley\WP\Tests\Fixtures; /** * A class that does nothing but can be instantiated and referenced. diff --git a/tests/Unit/.gitkeep b/tests/Unit/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/alley/wp/test-find-one.php b/tests/Unit/FindOneTest.php similarity index 82% rename from tests/alley/wp/test-find-one.php rename to tests/Unit/FindOneTest.php index cea4959..c7cd7df 100644 --- a/tests/alley/wp/test-find-one.php +++ b/tests/Unit/FindOneTest.php @@ -1,6 +1,6 @@ * @@ -10,19 +10,25 @@ * @package wp-find-one */ -namespace Alley\WP; +namespace Alley\WP\Tests\Unit; use Mantle\Testkit\Test_Case; +use function Alley\WP\find_one_comment; +use function Alley\WP\find_one_post; +use function Alley\WP\find_one_site; +use function Alley\WP\find_one_term; +use function Alley\WP\find_one_user; + /** * Unit tests for the `find_one()` functions. */ -final class Test_Find_One extends Test_Case { +final class FindOneTest extends Test_Case { /** * Test that `find_one_post()` finds an expected \WP_Post object. */ public function test_find_one_post_finds_post() { - $post_id = static::factory()->post->create( + $post_id = self::factory()->post->create( [ 'post_status' => 'draft', ] @@ -43,7 +49,7 @@ public function test_find_one_post_finds_post() { * Test that `find_one_term()` finds an expected \WP_Term object. */ public function test_find_one_term_finds_term() { - $term_id = static::factory()->term->create( + $term_id = self::factory()->term->create( [ 'name' => 'data1', ] @@ -66,7 +72,7 @@ public function test_find_one_term_finds_term() { public function test_find_one_comment_finds_comment() { $url = 'https://alley.co'; - $comment_id = static::factory()->comment->create( + $comment_id = self::factory()->comment->create( [ 'comment_author_url' => $url, ] @@ -86,7 +92,7 @@ public function test_find_one_comment_finds_comment() { * Test that `find_one_user()` finds an expected \WP_User object. */ public function test_find_one_user_finds_user() { - $user_id = static::factory()->user->create( + $user_id = self::factory()->user->create( [ 'user_login' => 'data1', ] @@ -113,7 +119,7 @@ public function test_find_one_site_finds_site() { // WordPress < 5.0 doesn't ensure paths are wrapped in slashes. $path = '/data1/'; - $blog_id = static::factory()->blog->create( + $blog_id = self::factory()->blog->create( [ 'path' => $path, ] diff --git a/tests/alley/wp/test-find-result.php b/tests/Unit/FindResultTest.php similarity index 77% rename from tests/alley/wp/test-find-result.php rename to tests/Unit/FindResultTest.php index 62899eb..674f9b6 100644 --- a/tests/alley/wp/test-find-result.php +++ b/tests/Unit/FindResultTest.php @@ -1,6 +1,6 @@ * @@ -10,23 +10,26 @@ * @package wp-find-one */ -namespace Alley\WP; +namespace Alley\WP\Tests\Unit; -use Alley\WP\Fixtures\Noop; +use Alley\WP\Tests\Fixtures\Noop; use Mantle\Testkit\Test_Case; +use PHPUnit\Framework\Attributes\DataProvider; + +use function Alley\WP\find_result; + /** * Unit tests for `find_result()`. */ -final class Test_Find_Result extends Test_Case { +final class FindResultTest extends Test_Case { /** * Test that `find_result()` plucks the expected value from the given args. * - * @dataProvider data_find_result - * * @param array $args Function arguments. * @param mixed $expected Expected return value. */ + #[dataProvider( 'data_find_result' )] public function test_find_result( $args, $expected ) { // phpcs:ignore Generic.NamingConventions.ConstructorName.OldStyle $this->assertSame( $expected, find_result( ...$args ) ); } @@ -36,7 +39,7 @@ public function test_find_result( $args, $expected ) { // phpcs:ignore Generic.N * * @return array Array of data. */ - public function data_find_result() { + public static function data_find_result() { $noop = new Noop(); $post = 123;