diff --git a/README.md b/README.md index a406754..3eada9c 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,12 @@ -# Yard :package_name +# Yard wp-user-roles -[![Code Style](https://github.com/yardinternet/skeleton-package/actions/workflows/format-php.yml/badge.svg?no-cache)](https://github.com/yardinternet/skeleton-package/actions/workflows/format-php.yml) -[![PHPStan](https://github.com/yardinternet/skeleton-package/actions/workflows/phpstan.yml/badge.svg?no-cache)](https://github.com/yardinternet/skeleton-package/actions/workflows/phpstan.yml) -[![Tests](https://github.com/yardinternet/skeleton-package/actions/workflows/run-tests.yml/badge.svg?no-cache)](https://github.com/yardinternet/skeleton-package/actions/workflows/run-tests.yml) -[![Code Coverage Badge](https://github.com/yardinternet/skeleton-package/blob/badges/coverage.svg)](https://github.com/yardinternet/skeleton-package/actions/workflows/badges.yml) -[![Lines of Code Badge](https://github.com/yardinternet/skeleton-package/blob/badges/lines-of-code.svg)](https://github.com/yardinternet/skeleton-package/actions/workflows/badges.yml) +[![Code Style](https://github.com/yardinternet/wp-user-roles/actions/workflows/format-php.yml/badge.svg?no-cache)](https://github.com/yardinternet/wp-user-roles/actions/workflows/format-php.yml) +[![PHPStan](https://github.com/yardinternet/wp-user-roles/actions/workflows/phpstan.yml/badge.svg?no-cache)](https://github.com/yardinternet/wp-user-roles/actions/workflows/phpstan.yml) +[![Tests](https://github.com/yardinternet/wp-user-roles/actions/workflows/run-tests.yml/badge.svg?no-cache)](https://github.com/yardinternet/wp-user-roles/actions/workflows/run-tests.yml) +[![Code Coverage Badge](https://github.com/yardinternet/wp-user-roles/blob/badges/coverage.svg)](https://github.com/yardinternet/wp-user-roles/actions/workflows/badges.yml) +[![Lines of Code Badge](https://github.com/yardinternet/wp-user-roles/blob/badges/lines-of-code.svg)](https://github.com/yardinternet/wp-user-roles/actions/workflows/badges.yml) - ---- -This repository provides a scaffold for creating an Acorn package. For more detailed information, please refer to the [Acorn Package Development](https://roots.io/acorn/docs/package-development/) documentation. -Follow these steps to get started: - -1. Press the "Use this template" button at the top of this repo to create a new repo with the contents of this skeleton. -2. Run "php ./configure.php" to run a script that will replace all placeholders throughout all the files. -3. Have fun creating your package. - ---- - ## Requirements @@ -33,14 +22,14 @@ To install this package using Composer, follow these steps: ```json { "type": "vcs", - "url": "git@github.com:yardinternet/skeleton-package.git" + "url": "git@github.com:yardinternet/wp-user-roles.git" } ``` 2. Install this package with Composer: ```sh - composer require yard/skeleton-package + composer require yard/wp-user-roles ``` 3. Run the Acorn WP-CLI command to discover this package: @@ -52,19 +41,13 @@ To install this package using Composer, follow these steps: You can publish the config file with: ```shell -wp acorn vendor:publish --provider="Yard\SkeletonPackage\SkeletonPackageServiceProvider" +wp acorn vendor:publish --provider="Yard\UserRoles\UserRolesServiceProvider" ``` ## Usage -From a Blade template: - -```blade -@include('skeleton-package::example') -``` - From WP-CLI: ```shell -wp acorn example +wp acorn user-roles ``` diff --git a/composer.json b/composer.json index ffd5278..931042a 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { - "name": "yard/skeleton-package", + "name": "yard/wp-user-roles", "type": "package", - "description": ":package_description", + "description": "This is my package wp-user-roles", "version": "1.0.0", "license": "MIT", "config": { @@ -24,12 +24,12 @@ }, "autoload": { "psr-4": { - "Yard\\SkeletonPackage\\": "src/" + "Yard\\UserRoles\\": "src/" } }, "autoload-dev": { "psr-4": { - "Yard\\SkeletonPackage\\Tests\\": "tests/" + "Yard\\UserRoles\\Tests\\": "tests/" } }, "scripts": { @@ -44,10 +44,10 @@ "extra": { "acorn": { "providers": [ - "Yard\\SkeletonPackage\\SkeletonPackageServiceProvider" + "Yard\\UserRoles\\UserRolesServiceProvider" ], "aliases": { - "Example": "Yard\\SkeletonPackage\\Facades\\Example" + "UserRoles": "Yard\\UserRoles\\Facades\\UserRoles" } } } diff --git a/config/skeleton-package.php b/config/skeleton-package.php deleted file mode 100644 index a65488f..0000000 --- a/config/skeleton-package.php +++ /dev/null @@ -1,25 +0,0 @@ - [ - 'For every Sage there is an Acorn.', - ], -]; diff --git a/config/user-roles.php b/config/user-roles.php new file mode 100644 index 0000000..1e8742c --- /dev/null +++ b/config/user-roles.php @@ -0,0 +1,73 @@ + 'yard', + 'roles' => [ + 'superuser' => [ + 'display_name' => 'Superuser', + 'caps' => [ + 'read' => true, + 'edit_dashboard' => true, + 'edit_files' => true, + 'unfiltered_html' => true, + 'upload_files' => true, + 'manage_categories' => true, + 'edit_theme_options' => true, + 'moderate_comments' => true, + ], + 'post_type_caps' => [ + 'post', + 'page', + ], + 'cap_groups' => [ + 'gravityforms', + 'wpseo', + ], + ], + ], + 'cap_groups' => [ + 'plugins' => [ + 'activate_plugins', + 'delete_plugins', + 'edit_plugins', + 'install_plugins', + 'update_plugins', + ], + 'users' => [ + 'create_users', + 'delete_users', + 'edit_users', + 'list_users', + 'promote_users', + 'remove_users', + ], + 'themes' => [ + 'delete_themes', + 'edit_themes', + 'install_themes', + 'switch_themes', + 'update_themes', + ], + 'gravityforms' => [ + 'gravityforms_create_form', + 'gravityforms_delete_forms', + 'gravityforms_edit_forms', + 'gravityforms_preview_forms', + 'gravityforms_view_entries', + 'gravityforms_edit_entries', + 'gravityforms_delete_entries', + 'gravityforms_view_entry_notes', + 'gravityforms_edit_entry_notes', + ], + 'wpseo' => [ + 'wpseo_bulk_edit', + 'wpseo_manage_options', + 'wpseo_bulk_edit', + 'wpseo_manage_options', + ], + ], + +]; diff --git a/configure.php b/configure.php deleted file mode 100644 index 7b03023..0000000 --- a/configure.php +++ /dev/null @@ -1,154 +0,0 @@ -#!/usr/bin/env php -.*/s', '', $contents) ?: $contents - ); -} - -$currentDirectory = getcwd(); -$folderName = basename($currentDirectory); - -$packageName = ask('Package name', $folderName); -$packageSlug = slugify($packageName); - -$nameSpace = title_case($packageName); -$nameSpace = ask('Namespace', $nameSpace); -$className = ask('Class name', $nameSpace); -$classSlug = slugify($className); -$className = title_case($className); - -$description = ask('Package description', "This is my package {$packageName}"); - -writeln('------'); -writeln("Package : {$packageSlug} <{$description}>"); -writeln("Namespace : Yard\\{$nameSpace}"); -writeln("Class name : {$className}"); -writeln('------'); - -writeln('This script will replace the above values in all relevant files in the project directory.'); - -if (! confirm('Modify files?', true)) { - exit(1); -} - -$files = (str_starts_with(strtoupper(PHP_OS), 'WIN') ? replaceForWindows() : replaceForAllOtherOSes()); - -foreach ($files as $file) { - replace_in_file($file, [ - ':package_name' => $packageName, - 'skeleton-package' => $packageSlug, - 'Example' => $className, - 'SkeletonPackage' => $nameSpace, - 'example' => $classSlug, - ':package_description' => $description, - ]); - - match (true) { - str_contains($file, determineSeparator('src/Example.php')) => rename($file, determineSeparator('./src/'.$className.'.php')), - str_contains($file, determineSeparator('src/SkeletonPackageServiceProvider.php')) => rename($file, determineSeparator('./src/'.$nameSpace.'ServiceProvider.php')), - str_contains($file, determineSeparator('src/Console/ExampleCommand.php')) => rename($file, determineSeparator('./src/console/'.$className.'Command.php')), - str_contains($file, determineSeparator('src/Facades/Example.php')) => rename($file, determineSeparator('./src/Facades/'.$className.'.php')), - str_contains($file, determineSeparator('resources/views/example.blade.php')) => rename($file, determineSeparator('./resources/views/'.$classSlug.'.blade.php')), - str_contains($file, determineSeparator('tests/ExampleTest.php')) => rename($file, determineSeparator('./tests/'.$className.'Test.php')), - str_contains($file, determineSeparator('tests/Console/ExampleCommandTest.php')) => rename($file, determineSeparator('./tests/console/'.$className.'CommandTest.php')), - str_contains($file, determineSeparator('tests/Facades/ExampleTest.php')) => rename($file, determineSeparator('./tests/Facades/'.$className.'Test.php')), - str_contains($file, 'README.md') => remove_readme_paragraphs($file), - default => [], - }; -} - -rename(determineSeparator('./config/example.php'), determineSeparator('./config/'.$packageSlug.'.php')); - -confirm('Execute `composer install`?') && run('composer install'); - -confirm('Let this script delete itself?', true) && unlink(__FILE__); diff --git a/phpstan.neon.dist b/phpstan.neon.dist index e63de75..4b2f4d0 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -3,10 +3,7 @@ includes: - vendor/larastan/larastan/extension.neon parameters: - level: 9 + level: 7 paths: - src tmpDir: build/phpstan - ignoreErrors: - - - message: '#Call to an undefined static method Yard\\SkeletonPackage\\Facades\\Example::getQuote\(\)#' diff --git a/resources/views/example.blade.php b/resources/views/example.blade.php deleted file mode 100644 index 04201f8..0000000 --- a/resources/views/example.blade.php +++ /dev/null @@ -1 +0,0 @@ -{{ Example::getQuote() }} diff --git a/resources/views/userroles.blade.php b/resources/views/userroles.blade.php new file mode 100644 index 0000000..2bd7caa --- /dev/null +++ b/resources/views/userroles.blade.php @@ -0,0 +1 @@ +{{ UserRoles::getQuote() }} diff --git a/src/Console/ExampleCommand.php b/src/Console/ExampleCommand.php deleted file mode 100644 index d4556d6..0000000 --- a/src/Console/ExampleCommand.php +++ /dev/null @@ -1,35 +0,0 @@ -info( - Example::getQuote() - ); - } -} diff --git a/src/Console/UserRolesCommand.php b/src/Console/UserRolesCommand.php new file mode 100644 index 0000000..1e312dc --- /dev/null +++ b/src/Console/UserRolesCommand.php @@ -0,0 +1,30 @@ +info('Created user roles'); + } +} diff --git a/src/Example.php b/src/Example.php deleted file mode 100644 index 9b00c8f..0000000 --- a/src/Example.php +++ /dev/null @@ -1,47 +0,0 @@ -post_content : 'Post not found'; - } -} diff --git a/src/Facades/Example.php b/src/Facades/UserRoles.php similarity index 61% rename from src/Facades/Example.php rename to src/Facades/UserRoles.php index 2572835..934d9f0 100644 --- a/src/Facades/Example.php +++ b/src/Facades/UserRoles.php @@ -2,17 +2,20 @@ declare(strict_types=1); -namespace Yard\SkeletonPackage\Facades; +namespace Yard\UserRoles\Facades; use Illuminate\Support\Facades\Facade; -class Example extends Facade +/** + * @method static void setRoles() + */ +class UserRoles extends Facade { /** * Get the registered name of the component. */ protected static function getFacadeAccessor(): string { - return 'Example'; + return 'UserRoles'; } } diff --git a/src/SkeletonPackageServiceProvider.php b/src/SkeletonPackageServiceProvider.php deleted file mode 100644 index 98f8d04..0000000 --- a/src/SkeletonPackageServiceProvider.php +++ /dev/null @@ -1,31 +0,0 @@ -name('skeleton-package') - ->hasConfigFile() - ->hasViews() - ->hasCommand(ExampleCommand::class); - } - - public function packageRegistered(): void - { - $this->app->singleton('Example', fn () => new Example($this->app)); - } - - public function packageBooted(): void - { - $this->app->make('Example'); - } -} diff --git a/src/UserRoles.php b/src/UserRoles.php new file mode 100644 index 0000000..10681a5 --- /dev/null +++ b/src/UserRoles.php @@ -0,0 +1,85 @@ + 'ids']) as $siteId) { + switch_to_blog($siteId); + $this->setRolesForSite(); + } + } else { + $this->setRolesForSite(); + } + } + + private function setRolesForSite(): void + { + + $roles = config('user-roles.roles'); + $prefix = config('user-roles.prefix'); + + Assert::isArray($roles); + Assert::stringNotEmpty($prefix); + + + //Remove current custom roles + $current_roles = \wp_roles()->roles; + $current_roles = array_filter( + array_keys($current_roles), + fn (string $role): bool => str_starts_with($role, $prefix) + ); + foreach($current_roles as $role) { + remove_role($role); + } + + // Add custom roles + foreach($roles as $role => $properties) { + $capabilities = []; + + $capGroups = config('user-roles.cap_groups'); + Assert::isArray($capGroups); + foreach ($properties['cap_groups'] as $group) { + $groupCaps = $capGroups[$group]; + Assert::isArray($groupCaps); + + foreach ($groupCaps as $cap) { + $capabilities[$cap] = true; + } + } + + foreach ($properties['post_type_caps'] as $postType) { + $postTypeCaps = get_post_type_object($postType)?->cap; + Assert::object($postTypeCaps); + foreach(array_values((array)$postTypeCaps) as $cap) { + $capabilities[$cap] = true; + } + } + + foreach($properties['caps'] as $cap => $value) { + $capabilities[$cap] = $value; + } + + add_role( + $prefix . '_' . $role, + $properties['display_name'], + $capabilities + ); + } + } +} diff --git a/src/UserRolesServiceProvider.php b/src/UserRolesServiceProvider.php new file mode 100644 index 0000000..e1a0a43 --- /dev/null +++ b/src/UserRolesServiceProvider.php @@ -0,0 +1,30 @@ +name('wp-user-roles') + ->hasConfigFile('user-roles') + ->hasCommand(UserRolesCommand::class); + } + + public function packageRegistered(): void + { + $this->app->singleton('UserRoles', fn () => new UserRoles($this->app)); + } + + public function packageBooted(): void + { + $this->app->make('UserRoles'); + } +} diff --git a/tests/Console/ExampleCommandTest.php b/tests/Console/ExampleCommandTest.php deleted file mode 100644 index 141dbdb..0000000 --- a/tests/Console/ExampleCommandTest.php +++ /dev/null @@ -1,9 +0,0 @@ -artisan('example') - ->expectsOutput('For every Sage there is an Acorn.') - ->assertExitCode(0); -}); diff --git a/tests/Console/UserRolesCommandTest.php b/tests/Console/UserRolesCommandTest.php new file mode 100644 index 0000000..265c209 --- /dev/null +++ b/tests/Console/UserRolesCommandTest.php @@ -0,0 +1,4 @@ +make('Example')->getQuote(); - - expect($quote)->tobe('For every Sage there is an Acorn.'); -}); - -it('can retrieve post content', function () { - $postId = 123; - $post = new stdClass(); - $post->post_content = 'Hello World!'; - - WP_Mock::userFunction('get_post') - ->once() - ->with(123) - ->andReturn($post); - - $postContent = app()->make('Example')->getPostContent($postId); - - expect($postContent)->tobe('Hello World!'); -}); diff --git a/tests/Facades/ExampleTest.php b/tests/Facades/ExampleTest.php deleted file mode 100644 index b490ec1..0000000 --- a/tests/Facades/ExampleTest.php +++ /dev/null @@ -1,11 +0,0 @@ -tobe('For every Sage there is an Acorn.'); -}); diff --git a/tests/Facades/UserRolesTest.php b/tests/Facades/UserRolesTest.php new file mode 100644 index 0000000..1a3e575 --- /dev/null +++ b/tests/Facades/UserRolesTest.php @@ -0,0 +1,5 @@ +in(__DIR__); diff --git a/tests/TestCase.php b/tests/TestCase.php index 7cc0174..9d4d468 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Yard\SkeletonPackage\Tests; +namespace Yard\UserRoles\Tests; use Orchestra\Testbench\TestCase as Orchestra; @@ -19,7 +19,7 @@ protected function tearDown(): void { parent::tearDown(); - \WP_Mock::tearDown(); + \WP_Mock::tearDown(); } /** @@ -32,7 +32,7 @@ protected function tearDown(): void protected function getPackageProviders($app) { return [ - 'Yard\SkeletonPackage\SkeletonPackageServiceProvider', + 'Yard\UserRoles\UserRolesServiceProvider', ]; } } diff --git a/tests/UserRolesTest.php b/tests/UserRolesTest.php new file mode 100644 index 0000000..265c209 --- /dev/null +++ b/tests/UserRolesTest.php @@ -0,0 +1,4 @@ +