├── .distignore ├── .editorconfig ├── .github └── workflows │ ├── code-standards.yml │ └── tests.yml ├── .gitignore ├── .phpcs └── .gitkeep ├── CHANGELOG.md ├── LICENSE ├── behat.yml ├── composer.json ├── features ├── activity-favorite.feature ├── activity-meta.feature ├── activity.feature ├── component.feature ├── friend.feature ├── group-invite.feature ├── group-member.feature ├── group-meta.feature ├── group.feature ├── message.feature ├── notification.feature ├── scaffold.feature ├── signup.feature ├── sitewide-notice.feature ├── tool.feature ├── xprofile-data.feature ├── xprofile-field.feature └── xprofile-group.feature ├── phpcs.xml.dist ├── readme.md ├── src ├── activity-favorite.php ├── activity-fetcher.php ├── activity-meta.php ├── activity.php ├── buddypress.php ├── command.php ├── components.php ├── email.php ├── friends.php ├── group-fetcher.php ├── group-invite.php ├── group-member.php ├── group-meta.php ├── group.php ├── member.php ├── messages.php ├── notification.php ├── scaffold.php ├── signup.php ├── sitewide-notice.php ├── templates │ ├── bootstrap-buddypress.php │ └── install-bp-tests.sh ├── tool.php ├── xprofile-data.php ├── xprofile-field.php ├── xprofile-group.php └── xprofile.php ├── wp-cli-bp.php └── wp-cli.yml /.distignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .git 3 | .gitignore 4 | .gitlab-ci.yml 5 | .editorconfig 6 | .travis.yml 7 | behat.yml 8 | circle.yml 9 | phpcs.xml.dist 10 | phpunit.xml.dist 11 | bin/ 12 | features/ 13 | utils/ 14 | *.zip 15 | *.tar.gz 16 | *.swp 17 | *.txt 18 | *.log 19 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | 4 | # WordPress Coding Standards 5 | # https://make.wordpress.org/core/handbook/coding-standards/ 6 | 7 | root = true 8 | 9 | [*] 10 | charset = utf-8 11 | end_of_line = lf 12 | insert_final_newline = true 13 | trim_trailing_whitespace = true 14 | indent_style = tab 15 | 16 | [{.jshintrc,*.json,*.yml,*.feature}] 17 | indent_style = space 18 | indent_size = 2 19 | 20 | [{*.txt}] 21 | end_of_line = crlf 22 | -------------------------------------------------------------------------------- /.github/workflows/code-standards.yml: -------------------------------------------------------------------------------- 1 | name: Coding Standards 2 | 3 | on: pull_request 4 | 5 | jobs: 6 | tests: 7 | name: PHPCS 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - name: Cancel previous runs of this workflow (pull requests only) 12 | if: ${{ github.event_name == 'pull_request' }} 13 | uses: styfle/cancel-workflow-action@0.12.0 14 | with: 15 | access_token: ${{ github.token }} 16 | 17 | - name: Checkout code 18 | uses: actions/checkout@v4 19 | 20 | - name: Setup PHP 21 | uses: shivammathur/setup-php@v2 22 | with: 23 | php-version: 8.4 24 | coverage: none 25 | tools: composer 26 | 27 | - name: Validate Composer 28 | run: composer validate --strict 29 | 30 | - name: Install dependencies 31 | uses: ramsey/composer-install@v2 32 | 33 | - name: Run Linter 34 | run: composer lint 35 | 36 | - name: Run PHPCS 37 | run: composer phpcs 38 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Testing 2 | 3 | on: pull_request 4 | 5 | jobs: 6 | tests: 7 | name: "WP: ${{ matrix.wp_version }} - PHP: ${{ matrix.php }}" 8 | runs-on: ubuntu-latest 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | php: ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] 13 | wp_version: ['latest'] 14 | mysql: ['8.0'] 15 | include: 16 | - php: '7.4' 17 | wp_version: '6.4' 18 | env: 19 | WP_VERSION: ${{ matrix.wp_version }} 20 | 21 | steps: 22 | - name: Cancel previous runs of this workflow (pull requests only) 23 | if: ${{ github.event_name == 'pull_request' }} 24 | uses: styfle/cancel-workflow-action@0.12.0 25 | with: 26 | access_token: ${{ github.token }} 27 | 28 | - name: Check out source code 29 | uses: actions/checkout@v4 30 | 31 | - name: Check Gitignored files 32 | run: if [[ ! -z $(git ls-files -i --exclude-standard) ]]; then exit 1; fi 33 | 34 | - name: Check existence of composer.json & behat.yml files 35 | uses: andstor/file-existence-action@v3 36 | with: 37 | fail: true 38 | files: "composer.json, behat.yml" 39 | 40 | - name: Setup PHP 41 | uses: shivammathur/setup-php@v2 42 | with: 43 | php-version: ${{ matrix.php }} 44 | extensions: gd, imagick, mysql, zip 45 | coverage: none 46 | tools: composer:v2 47 | 48 | - name: Install Composer dependencies 49 | uses: ramsey/composer-install@v2 50 | 51 | - name: Setup MySQL Server 52 | id: setup-mysql 53 | uses: shogo82148/actions-setup-mysql@v1 54 | with: 55 | mysql-version: ${{ matrix.mysql }} 56 | root-password: root 57 | user: wp_cli_test 58 | password: password1 59 | 60 | - name: Configure DB environment 61 | run: | 62 | echo "MYSQL_HOST=127.0.0.1" >> $GITHUB_ENV 63 | echo "MYSQL_TCP_PORT=3306" >> $GITHUB_ENV 64 | echo "WP_CLI_TEST_DBROOTUSER=root" >> $GITHUB_ENV 65 | echo "WP_CLI_TEST_DBROOTPASS=root" >> $GITHUB_ENV 66 | echo "WP_CLI_TEST_DBNAME=wp_cli_test" >> $GITHUB_ENV 67 | echo "WP_CLI_TEST_DBUSER=wp_cli_test" >> $GITHUB_ENV 68 | echo "WP_CLI_TEST_DBPASS=password1" >> $GITHUB_ENV 69 | echo "WP_CLI_TEST_DBHOST=127.0.0.1:3306" >> $GITHUB_ENV 70 | 71 | - name: Prepare tests 72 | env: 73 | WP_VERSION: '${{ matrix.wp_version }}' 74 | WP_CLI_TEST_DBTYPE: 'mysql' 75 | WP_CLI_TEST_DBSOCKET: '${{ steps.setup-mysql.outputs.base-dir }}/tmp/mysql.sock' 76 | run: composer prepare-tests 77 | 78 | - name: Run Behat 79 | env: 80 | WP_VERSION: '${{ matrix.wp_version }}' 81 | WP_CLI_TEST_DBTYPE: 'mysql' 82 | WP_CLI_TEST_DBSOCKET: '${{ steps.setup-mysql.outputs.base-dir }}/tmp/mysql.sock' 83 | run: composer behat || composer behat-rerun 84 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | wp-cli.local.yml 3 | node_modules/ 4 | vendor/ 5 | *.zip 6 | *.tar.gz 7 | 8 | # Cache files 9 | .phpcs/*.json 10 | composer.lock 11 | -------------------------------------------------------------------------------- /.phpcs/.gitkeep: -------------------------------------------------------------------------------- 1 | # This directory can't be empty. 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | This library adheres to [Semantic Versioning](https://semver.org/) and [Keep a CHANGELOG](https://keepachangelog.com/en/1.0.0/). 4 | 5 | ## 3.0.2 6 | 7 | ### Changed 8 | 9 | * CI: test against PHP 8.4 10 | * CI: WordPress: minimum version tested bumped to 6.4 11 | 12 | ## 3.0.1 13 | 14 | ### Changed 15 | 16 | * `wp bp tool signup` supports multisite. 17 | * `wp bp signup`: 18 | * `list`: list 50 items by default, instead of 1. 19 | * added support for more object fields. 20 | * Avoid the `generate_callback` method to appear as a valid command by turning it into a protected method. 21 | * Added `composer phpunit` as an alias for `composer behat`. 22 | 23 | ## 3.0.0 24 | 25 | ## Added 26 | 27 | * Support for the `--silence` flag introduced to a few `create` commands. 28 | * Support for the `--silence` flag introduced to the `wp bp activity comment` command. 29 | * Support for the `--format` and `--silent` flags for the `generate` commands. 30 | * New commands: 31 | * `wp bp notice` - Use it to manage Sitewide notices. 32 | * `delete-comment` and `remove-comment` aliases added for the `wp bp activity delete_comment` command. 33 | 34 | ### Changed 35 | 36 | * Prefer short array syntax (This is different from WCS supports) 37 | * Composer packages upgraded to their latest versions 38 | * Several linting updates 39 | * CI tests against PHP 8.3 40 | * Updated deprecated function from `bp_get_group_permalink` into `bp_get_group_url` 41 | * Made tests from the Activity command more deterministic 42 | * PHPDoc improvements 43 | * All `generate` commands' output were standardized 44 | * All `create` commands' output were standardized 45 | * All `delete` commands' output were standardized 46 | * All `delete` commands' alias were standardized 47 | * All `list` commands were standardized 48 | * Invalid `--format` option `haml` removed 49 | * Removed mention of default text creation from the `wp bp activity post-update` command 50 | * Removed `user_items` and `items` aliases from the `wp bp activity favorite list` command 51 | * Confirmation message updated for `delete` commands that accepts multiple values 52 | * `wp bp group invite remove` updated to `wp bp group invite uninvite` to avoid conflict with the `delete/remove` command 53 | * `wp bp activity delete_comment` updated to `wp bp activity delete-comment` 54 | * `generate` commands: avoid refetching user objects 55 | * Upgraded the `styfle/cancel-workflow-action` Github Action. 56 | 57 | ## 2.0.2 58 | 59 | * Github Actions: upgraded actions 60 | * Github Actions: decreased the number of legacy PHP versions to test against 61 | * Github Actions: Testing against the PHP 8.2 versions 62 | * Behat: fix a small bug 63 | * Updated `composer.json` packages 64 | * Removed hardcoded `composer.lock` file (let the PHP version decide which packages to install) 65 | 66 | ## 2.0.1 67 | 68 | * Load the `bp scaffold` command only if the composer Scaffold package is installed 69 | * Updated PHPCS ruleset and fixed phpcs rules 70 | * Fix changelog.md markdown bugs 71 | * Moved from Travis to Github Actions for CI tests 72 | * CI tests against PHP 8.0 now 73 | * Upgraded the wp-cli/wp-cli-tests package to latest 74 | * Upgraded the wp-cli/wp-cli package to latest 75 | * Added a new behat.yml file for the test setup 76 | * wp bp component: 77 | * properly listing active components. 78 | * status string updated from uppercase to lowercase. 79 | * we are checking the component status correctly. 80 | * we improved the behat tests. 81 | * we are decidubg the component description. 82 | * we are escaping the component title. 83 | 84 | ## 2.0.0 85 | 86 | * Abstracted activity ID fetching to the `Activity_Fetcher` helper class 87 | * The package was upgraded to follow WP-CLI best practices in code organization and structure 88 | * The `before_invoke` callable was abstracted into their component class 89 | * We made sure all Behat tests were passing correctly 90 | * We fixed several minor bugs in several commands 91 | * We are making the use of `wp-cli/wp-cli-tests` for all tests (phpcs, behat, etc). 92 | * Improved .travis.yml config 93 | * Removed PHP 5.4 support from Travis 94 | * Support to PHP 5.6+ added 95 | * Improved the readme documentation 96 | * Updated to use the more up to date `WP_CLI::log()` instead of `WP_CLI::line()` 97 | * Forced the creation of the signups table when using the `wp bp signup` command and the tabled wasn't present. 98 | * Return proper success/error messages when using `parent::_delete` or `parent::_update` 99 | * Improved the commands PHPDocs, very useful when using the `help` 100 | * Updated to fetch and check values from PHPDoc instead of checking in PHP 101 | * Updated or removed the `default` values from several commands (most of them were wrong) 102 | * New commands: 103 | * `wp bp group meta` - Used to manage Group Meta (custom fields). 104 | * `wp bp activity meta` - Used to manage Activity Meta (custom fields). 105 | * `wp bp tool signup` - Used to (de)activate the Signup feature. 106 | * `wp bp scaffold tests` - Used to scaffold BuddyPress specific testing code for plugins. 107 | 108 | ## 1.8.0 109 | 110 | * `wp-cli-buddypress` requires PHP 5.4 111 | * `bp notification` commands introduced 112 | 113 | ## 1.7.0 114 | 115 | * Updated `bp` and `bp xprofile` commands PHPDoc info 116 | * Fixed `component list` commands output 117 | * Check if the `component` exists first before using it 118 | * Fixed `component` Behat tests 119 | * Removed PHP 5.3 support from Travis 120 | 121 | ## 1.6.0 122 | 123 | * `bp email` commands introduced 124 | * With PSR-4 support for the classes 125 | 126 | ## 1.5.0 127 | 128 | * CRUD commands introduced to the main BuddyPress components 129 | * Behat tests added for all commands 130 | * Codebase fixed for WPCS 131 | 132 | ## 1.4.0 133 | 134 | * New commands: `bp xprofile list_fields`, `bp xprofile delete_field` 135 | * Added the ability to pass multiple comma-separated values when updating xprofile fields 136 | * Fixed bug in component activation 137 | 138 | ## 1.3.1 139 | 140 | * Improved logic for user-id parsing 141 | 142 | ## 1.3.0 143 | 144 | * New commands: `bp group get_members`, `bp group update` 145 | * Ability to pass 'content' when using `bp activity generate` 146 | * When using `bp activity generate` with type=activity_update and component=groups, format the activity action properly 147 | 148 | ## 1.2.0 149 | 150 | * Use wp-cli's new fourth-level commands 151 | * New commands: xprofile create_group, xprofile create_field, xprofile set_data 152 | 153 | ## 1.1.1 154 | 155 | * Ensure that components have their install routine run after activation 156 | 157 | ## 1.1 158 | 159 | * New commands: activate, deactivate, activity_create, activity_generate 160 | * Improved documentation 161 | * Added support for installation via Composer 162 | 163 | ## 1.0 164 | 165 | * Initial release 166 | -------------------------------------------------------------------------------- /behat.yml: -------------------------------------------------------------------------------- 1 | default: 2 | suites: 3 | default: 4 | contexts: 5 | - WP_CLI\Tests\Context\FeatureContext 6 | paths: 7 | - features 8 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "buddypress/wp-cli-buddypress", 3 | "type": "wp-cli-package", 4 | "description": "WP-CLI Community Package of BuddyPress commands", 5 | "homepage": "https://github.com/buddypress/wp-cli-buddypress", 6 | "license": "MIT", 7 | "keywords": [ 8 | "wp-cli", 9 | "buddypress", 10 | "community", 11 | "wordpress", 12 | "bp", 13 | "wp" 14 | ], 15 | "authors": [ 16 | { 17 | "name": "The BuddPress Contributors", 18 | "homepage": "https://buddypress.org/" 19 | } 20 | ], 21 | "support": { 22 | "issues": "https://github.com/buddypress/wp-cli-buddypress/issues", 23 | "source": "https://github.com/buddypress/wp-cli-buddypress" 24 | }, 25 | "require": { 26 | "php": ">=5.6.0", 27 | "wp-cli/wp-cli": "^2" 28 | }, 29 | "require-dev": { 30 | "wp-cli/scaffold-command": "^2", 31 | "wp-cli/extension-command": "^2", 32 | "wp-cli/entity-command": "^2", 33 | "wp-cli/wp-cli-tests": "^4" 34 | }, 35 | "scripts": { 36 | "behat": "run-behat-tests", 37 | "behat-rerun": "rerun-behat-tests", 38 | "phpunit": "behat", 39 | "lint": "run-linter-tests", 40 | "phpcs": "run-phpcs-tests", 41 | "phpcbf": "run-phpcbf-cleanup", 42 | "prepare-tests": "install-package-tests", 43 | "test": [ 44 | "@lint", 45 | "@phpcs", 46 | "@behat" 47 | ] 48 | }, 49 | "minimum-stability": "dev", 50 | "prefer-stable": true, 51 | "autoload": { 52 | "files": [ 53 | "wp-cli-bp.php" 54 | ] 55 | }, 56 | "config": { 57 | "process-timeout": 1800, 58 | "sort-packages": true, 59 | "allow-plugins": { 60 | "dealerdirect/phpcodesniffer-composer-installer": true 61 | } 62 | }, 63 | "extra": { 64 | "bundled": true, 65 | "commands": [ 66 | "wp bp", 67 | "wp bp activity", 68 | "wp bp activity meta", 69 | "wp bp activity favorite", 70 | "wp bp group", 71 | "wp bp group meta", 72 | "wp bp group member", 73 | "wp bp group invite", 74 | "wp bp message", 75 | "wp bp email", 76 | "wp bp component", 77 | "wp bp member", 78 | "wp bp notification", 79 | "wp bp tool", 80 | "wp bp signup", 81 | "wp bp xprofile", 82 | "wp bp notice", 83 | "wp bp xprofile field", 84 | "wp bp xprofile group", 85 | "wp bp xprofile data", 86 | "wp bp scaffold" 87 | ] 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /features/activity-favorite.feature: -------------------------------------------------------------------------------- 1 | Feature: Manage BuddyPress Activity Favorites 2 | 3 | Background: 4 | Given a WP install 5 | And these installed and active plugins: 6 | """ 7 | https://github.com/buddypress/BuddyPress/archive/master.zip 8 | """ 9 | And I run `wp bp component activate activity` 10 | 11 | Scenario: Activity Favorite CRUD 12 | 13 | When I run `wp user create testuser1 testuser1@example.com --first_name=testuser1 --last_name=user --role=subscriber --porcelain` 14 | Then STDOUT should be a number 15 | And save STDOUT as {MEMBER_ID} 16 | 17 | When I run `wp bp activity create --user-id={MEMBER_ID} --porcelain` 18 | Then STDOUT should be a number 19 | And save STDOUT as {ACTIVITY_ID} 20 | 21 | When I run `wp bp activity favorite create {ACTIVITY_ID} {MEMBER_ID}` 22 | Then STDOUT should contain: 23 | """ 24 | Success: Activity item added as a favorite for the user. 25 | """ 26 | 27 | When I run `wp bp activity favorite remove {ACTIVITY_ID} {MEMBER_ID} --yes` 28 | Then STDOUT should contain: 29 | """ 30 | Success: Activity item removed as a favorite for the user. 31 | """ 32 | -------------------------------------------------------------------------------- /features/activity-meta.feature: -------------------------------------------------------------------------------- 1 | Feature: Manage BuddyPress Activity custom fields 2 | 3 | Background: 4 | Given a WP install 5 | And these installed and active plugins: 6 | """ 7 | https://github.com/buddypress/BuddyPress/archive/master.zip 8 | """ 9 | And I run `wp bp component activate activity` 10 | 11 | Scenario: Activity Meta CRUD 12 | 13 | When I run `wp user create testuser2 testuser2@example.com --first_name=test --last_name=user --role=subscriber --porcelain` 14 | Then STDOUT should be a number 15 | And save STDOUT as {MEMBER_ID} 16 | 17 | When I run `wp bp activity create --porcelain` 18 | Then STDOUT should be a number 19 | And save STDOUT as {ACTIVITY_ID} 20 | 21 | When I run `wp bp activity meta add {ACTIVITY_ID} foo 'bar'` 22 | Then STDOUT should not be empty 23 | 24 | When I run `wp bp activity meta get {ACTIVITY_ID} foo` 25 | Then STDOUT should be: 26 | """ 27 | bar 28 | """ 29 | 30 | When I try `wp bp activity meta get 999999 foo` 31 | Then the return code should be 1 32 | Then STDERR should be: 33 | """ 34 | Error: Could not find the activity with ID 999999. 35 | """ 36 | 37 | When I run `wp bp activity meta set {ACTIVITY_ID} foo '[ "1", "2" ]' --format=json` 38 | Then STDOUT should not be empty 39 | 40 | When I run `wp bp activity meta get {ACTIVITY_ID} foo --format=json` 41 | Then STDOUT should be: 42 | """ 43 | ["1","2"] 44 | """ 45 | 46 | When I run `wp bp activity meta delete {ACTIVITY_ID} foo` 47 | Then STDOUT should not be empty 48 | 49 | When I try `wp bp activity meta get {ACTIVITY_ID} foo` 50 | Then the return code should be 1 51 | 52 | Scenario: Add activity meta with JSON serialization 53 | 54 | When I run `wp user create testuser2 testuser2@example.com --first_name=test --last_name=user --role=subscriber --porcelain` 55 | Then STDOUT should be a number 56 | And save STDOUT as {MEMBER_ID} 57 | 58 | When I run `wp bp activity create --porcelain` 59 | Then STDOUT should be a number 60 | And save STDOUT as {ACTIVITY_ID} 61 | 62 | When I run `wp bp activity meta add {ACTIVITY_ID} foo '"-- hi"' --format=json` 63 | Then STDOUT should contain: 64 | """ 65 | Success: 66 | """ 67 | 68 | When I run `wp bp activity meta get {ACTIVITY_ID} foo` 69 | Then STDOUT should be: 70 | """ 71 | -- hi 72 | """ 73 | 74 | Scenario: List activity meta 75 | 76 | When I run `wp user create testuser2 testuser2@example.com --first_name=test --last_name=user --role=subscriber --porcelain` 77 | Then STDOUT should be a number 78 | And save STDOUT as {MEMBER_ID} 79 | 80 | When I run `wp bp activity create --porcelain` 81 | Then STDOUT should be a number 82 | And save STDOUT as {ACTIVITY_ID} 83 | 84 | When I run `wp bp activity meta add {ACTIVITY_ID} apple banana` 85 | And I run `wp bp activity meta add {ACTIVITY_ID} apple banana` 86 | Then STDOUT should not be empty 87 | 88 | When I run `wp bp activity meta set {ACTIVITY_ID} banana '["apple", "apple"]' --format=json` 89 | Then STDOUT should not be empty 90 | 91 | When I run `wp bp activity meta list {ACTIVITY_ID}` 92 | Then STDOUT should be a table containing rows: 93 | | activity_id | meta_key | meta_value | 94 | | 1 | apple | banana | 95 | | 1 | apple | banana | 96 | | 1 | banana | a:2:{i:0;s:5:"apple";i:1;s:5:"apple";} | 97 | 98 | When I run `wp bp activity meta list 1 --unserialize` 99 | Then STDOUT should be a table containing rows: 100 | | activity_id | meta_key | meta_value | 101 | | 1 | apple | banana | 102 | | 1 | apple | banana | 103 | | 1 | banana | ["apple","apple"] | 104 | -------------------------------------------------------------------------------- /features/activity.feature: -------------------------------------------------------------------------------- 1 | Feature: Manage BuddyPress Activities 2 | 3 | Background: 4 | Given a WP install 5 | And these installed and active plugins: 6 | """ 7 | https://github.com/buddypress/BuddyPress/archive/master.zip 8 | """ 9 | And I run `wp bp component activate activity` 10 | 11 | Scenario: Activity CRUD 12 | 13 | When I run `wp user create testuser2 testuser2@example.com --first_name=test --last_name=user --role=subscriber --porcelain` 14 | Then STDOUT should be a number 15 | And save STDOUT as {MEMBER_ID} 16 | 17 | When I run `wp bp activity create --component=activity --porcelain` 18 | Then STDOUT should be a number 19 | And save STDOUT as {ACTIVITY_ID} 20 | 21 | When I run `wp bp activity get {ACTIVITY_ID} --fields=id,component` 22 | Then STDOUT should be a table containing rows: 23 | | Field | Value | 24 | | id | {ACTIVITY_ID} | 25 | | component | activity | 26 | 27 | When I run `wp bp activity spam {ACTIVITY_ID}` 28 | Then STDOUT should contain: 29 | """ 30 | Success: Activity marked as spam. 31 | """ 32 | 33 | When I run `wp bp activity get {ACTIVITY_ID} --fields=id,is_spam` 34 | Then STDOUT should be a table containing rows: 35 | | Field | Value | 36 | | id | {ACTIVITY_ID} | 37 | | is_spam | 1 | 38 | 39 | When I run `wp bp activity ham {ACTIVITY_ID}` 40 | Then STDOUT should contain: 41 | """ 42 | Success: Activity marked as ham. 43 | """ 44 | 45 | When I run `wp bp activity get {ACTIVITY_ID} --fields=id,is_spam` 46 | Then STDOUT should be a table containing rows: 47 | | Field | Value | 48 | | id | {ACTIVITY_ID} | 49 | | is_spam | 0 | 50 | 51 | When I run `wp bp activity delete {ACTIVITY_ID} --yes` 52 | Then STDOUT should contain: 53 | """ 54 | Success: Deleted activity {ACTIVITY_ID}. 55 | """ 56 | 57 | When I try `wp bp activity get {ACTIVITY_ID}` 58 | Then the return code should be 1 59 | 60 | Scenario: Activity Comment 61 | 62 | When I run `wp user create testuser2 testuser2@example.com --first_name=test --last_name=user --role=subscriber --porcelain` 63 | Then STDOUT should be a number 64 | And save STDOUT as {MEMBER_ID} 65 | 66 | When I run `wp bp activity post-update --user-id={MEMBER_ID} --content="Random Content" --porcelain` 67 | Then STDOUT should be a number 68 | And save STDOUT as {ACTIVITY_ID} 69 | 70 | When I run `wp bp activity list --fields=id,user_id,component` 71 | Then STDOUT should be a table containing rows: 72 | | id | user_id | component | 73 | | {ACTIVITY_ID} | {MEMBER_ID} | activity | 74 | 75 | When I run `wp bp activity list --format=count` 76 | Then STDOUT should be: 77 | """ 78 | 1 79 | """ 80 | 81 | When I run `wp bp activity list --format=ids` 82 | Then STDOUT should be: 83 | """ 84 | {ACTIVITY_ID} 85 | """ 86 | 87 | When I run `wp bp activity comment {ACTIVITY_ID} --user-id={MEMBER_ID} --content="Activity Comment" --skip-notification --porcelain` 88 | Then STDOUT should be a number 89 | And save STDOUT as {COMMENT_ID} 90 | 91 | When I run `wp bp activity get {COMMENT_ID} --fields=id,type` 92 | Then STDOUT should be a table containing rows: 93 | | Field | Value | 94 | | id | {COMMENT_ID} | 95 | | type | activity_comment | 96 | 97 | When I run `wp bp activity delete_comment {ACTIVITY_ID} --comment-id={COMMENT_ID} --yes` 98 | Then STDOUT should contain: 99 | """ 100 | Success: Activity comment deleted. 101 | """ 102 | 103 | When I try `wp bp activity get {COMMENT_ID} --fields=id,type` 104 | Then the return code should be 1 105 | -------------------------------------------------------------------------------- /features/component.feature: -------------------------------------------------------------------------------- 1 | Feature: Manage BuddyPress Components 2 | 3 | Background: 4 | Given a WP install 5 | And these installed and active plugins: 6 | """ 7 | https://github.com/buddypress/BuddyPress/archive/master.zip 8 | """ 9 | 10 | Scenario: Component CRUD Operations 11 | 12 | When I run `wp bp component list --format=count` 13 | Then STDOUT should be: 14 | """ 15 | 10 16 | """ 17 | 18 | When I run `wp bp component list --type=required --format=count` 19 | Then STDOUT should be: 20 | """ 21 | 2 22 | """ 23 | 24 | When I run `wp bp component list --type=required` 25 | Then STDOUT should be a table containing rows: 26 | | number | id | status | title | description | 27 | | 1 | core | active | BuddyPress Core | It‘s what makes time travel BuddyPress possible! | 28 | | 2 | members | active | Community Members | Everything in a BuddyPress community revolves around its members. | 29 | 30 | When I run `wp bp component list --fields=id --type=required` 31 | Then STDOUT should be a table containing rows: 32 | | id | 33 | | core | 34 | | members | 35 | 36 | When I run `wp bp component list --fields=id --type=optional` 37 | Then STDOUT should be a table containing rows: 38 | | id | 39 | | xprofile | 40 | | settings | 41 | | friends | 42 | | messages | 43 | | activity | 44 | | notifications | 45 | | groups | 46 | | blogs | 47 | 48 | When I run `wp bp component list --fields=id --status=active` 49 | Then STDOUT should be a table containing rows: 50 | | id | 51 | | core | 52 | 53 | When I try `wp bp component list --type=retired` 54 | Then the return code should be 1 55 | Then STDERR should be: 56 | """ 57 | Error: There is no component available. 58 | """ 59 | 60 | When I run `wp bp component activate groups` 61 | Then STDOUT should contain: 62 | """ 63 | Success: The Groups component has been activated. 64 | """ 65 | 66 | When I run `wp bp component list --fields=id --status=active` 67 | Then STDOUT should be a table containing rows: 68 | | id | 69 | | groups | 70 | | core | 71 | 72 | When I run `wp bp component list --fields=id` 73 | Then STDOUT should be a table containing rows: 74 | | id | 75 | | core | 76 | | members | 77 | | groups | 78 | 79 | When I run `wp bp component deactivate groups` 80 | Then STDOUT should contain: 81 | """ 82 | Success: The Groups component has been deactivated. 83 | """ 84 | 85 | When I run `wp bp component list --fields=id` 86 | Then STDOUT should be a table containing rows: 87 | | id | 88 | | core | 89 | | members | 90 | -------------------------------------------------------------------------------- /features/friend.feature: -------------------------------------------------------------------------------- 1 | Feature: Manage BuddyPress Friends 2 | 3 | Background: 4 | Given a WP install 5 | And these installed and active plugins: 6 | """ 7 | https://github.com/buddypress/BuddyPress/archive/master.zip 8 | """ 9 | And I run `wp bp component activate friends` 10 | 11 | Scenario: Friends CRUD 12 | 13 | When I try `wp user get bogus-user` 14 | Then the return code should be 1 15 | And STDOUT should be empty 16 | 17 | When I run `wp user create testuser1 testuser1@example.com --porcelain` 18 | Then STDOUT should be a number 19 | And save STDOUT as {BOB_ID} 20 | 21 | When I run `wp user create testuser2 testuser2@example.com --porcelain` 22 | Then STDOUT should be a number 23 | And save STDOUT as {SALLY_ID} 24 | 25 | When I run `wp user create testuser3 testuser3@example.com --porcelain` 26 | Then STDOUT should be a number 27 | And save STDOUT as {JOHN_ID} 28 | 29 | When I run `wp bp friend create {BOB_ID} {SALLY_ID} --force-accept` 30 | Then STDOUT should contain: 31 | """ 32 | Success: Friendship successfully created. 33 | """ 34 | 35 | When I run `wp bp friend check {BOB_ID} {SALLY_ID}` 36 | Then STDOUT should contain: 37 | """ 38 | Success: Yes, they are friends. 39 | """ 40 | 41 | When I run `wp bp friend create {BOB_ID} {JOHN_ID} --force-accept` 42 | Then STDOUT should contain: 43 | """ 44 | Success: Friendship successfully created. 45 | """ 46 | 47 | When I run `wp bp friend list {BOB_ID} --fields=friend_user_id,is_confirmed` 48 | Then STDOUT should be a table containing rows: 49 | | friend_user_id | is_confirmed | 50 | | {SALLY_ID} | 1 | 51 | | {JOHN_ID} | 1 | 52 | 53 | When I run `wp bp friend remove {BOB_ID} {SALLY_ID}` 54 | Then STDOUT should contain: 55 | """ 56 | Success: Friendship successfully removed. 57 | """ 58 | 59 | When I run `wp bp friend remove {BOB_ID} {JOHN_ID}` 60 | Then STDOUT should contain: 61 | """ 62 | Success: Friendship successfully removed. 63 | """ 64 | -------------------------------------------------------------------------------- /features/group-invite.feature: -------------------------------------------------------------------------------- 1 | Feature: Manage BuddyPress Group Invites 2 | 3 | Background: 4 | Given a WP install 5 | And these installed and active plugins: 6 | """ 7 | https://github.com/buddypress/BuddyPress/archive/master.zip 8 | """ 9 | And I run `wp bp component activate groups` 10 | 11 | Scenario: Group Invite CRUD 12 | 13 | When I run `wp user create testuser1 testuser1@example.com --porcelain` 14 | Then STDOUT should be a number 15 | And save STDOUT as {MEMBER_ID} 16 | 17 | When I run `wp user create testuser2 testuser2@example.com --porcelain` 18 | Then STDOUT should be a number 19 | And save STDOUT as {INVITER_ID} 20 | 21 | When I run `wp bp group create --name="Cool Group" --creator-id={MEMBER_ID} --porcelain` 22 | Then STDOUT should be a number 23 | And save STDOUT as {GROUP_ID} 24 | 25 | When I run `wp bp group invite create --group-id={GROUP_ID} --user-id={INVITER_ID} --inviter-id={MEMBER_ID}` 26 | Then STDOUT should contain: 27 | """ 28 | Success: Member invited to the group. 29 | """ 30 | 31 | When I run `wp bp group invite uninvite --group-id={GROUP_ID} --user-id={INVITER_ID}` 32 | Then STDOUT should contain: 33 | """ 34 | Success: User uninvited from the group. 35 | """ 36 | 37 | Scenario: Group Invite list 38 | 39 | When I run `wp user create testuser1 testuser1@example.com --porcelain` 40 | Then STDOUT should be a number 41 | And save STDOUT as {MEMBER_ONE_ID} 42 | 43 | When I run `wp user create testuser2 testuser2@example.com --porcelain` 44 | Then STDOUT should be a number 45 | And save STDOUT as {MEMBER_TWO_ID} 46 | 47 | When I run `wp bp group create --name="Group 1" --slug=group1 --creator-id={MEMBER_ONE_ID} --porcelain` 48 | Then STDOUT should be a number 49 | And save STDOUT as {GROUP_ONE_ID} 50 | 51 | When I run `wp bp group create --name="Group 2" --slug=group2 --creator-id={MEMBER_TWO_ID} --porcelain` 52 | Then STDOUT should be a number 53 | And save STDOUT as {GROUP_TWO_ID} 54 | 55 | When I run `wp bp group invite add --group-id={GROUP_ONE_ID} --user-id={MEMBER_TWO_ID} --inviter-id={MEMBER_ONE_ID} --silent` 56 | Then the return code should be 0 57 | 58 | When I run `wp bp group invite add --group-id={GROUP_TWO_ID} --user-id={MEMBER_ONE_ID} --inviter-id={MEMBER_TWO_ID} --silent` 59 | Then the return code should be 0 60 | 61 | When I try `wp bp group invite list` 62 | Then the return code should be 1 63 | 64 | Scenario: Group Invite Error 65 | 66 | When I run `wp user create testuser1 testuser1@example.com --porcelain` 67 | Then STDOUT should be a number 68 | And save STDOUT as {MEMBER_ID} 69 | 70 | When I run `wp bp group create --name="Group 1" --slug=group1 --creator-id={MEMBER_ID} --porcelain` 71 | Then STDOUT should be a number 72 | And save STDOUT as {GROUP_ONE_ID} 73 | 74 | When I run `wp bp group invite add --group-id={GROUP_ONE_ID} --user-id={MEMBER_ID} --inviter-id={MEMBER_ID}` 75 | Then the return code should be 0 76 | -------------------------------------------------------------------------------- /features/group-member.feature: -------------------------------------------------------------------------------- 1 | Feature: Manage BuddyPress Group Members 2 | 3 | Background: 4 | Given a WP install 5 | And these installed and active plugins: 6 | """ 7 | https://github.com/buddypress/BuddyPress/archive/master.zip 8 | """ 9 | And I run `wp bp component activate groups` 10 | 11 | Scenario: Group Member CRUD 12 | 13 | When I run `wp user create testuser1 testuser1@example.com --porcelain` 14 | Then STDOUT should be a number 15 | And save STDOUT as {CREATOR_ID} 16 | 17 | When I run `wp user create mod mod@example.com --porcelain` 18 | Then STDOUT should be a number 19 | And save STDOUT as {MEMBER_ID} 20 | 21 | When I run `wp user create randon randon@example.com --porcelain` 22 | Then STDOUT should be a number 23 | And save STDOUT as {RANDON_MEMBER_ID} 24 | 25 | When I run `wp user create anothermod anothermod@example.com --porcelain` 26 | Then STDOUT should be a number 27 | And save STDOUT as {ANOTHER_MEMBER_ID} 28 | 29 | When I run `wp bp group create --name="Totally Cool Group" --creator-id={CREATOR_ID} --porcelain` 30 | Then STDOUT should be a number 31 | And save STDOUT as {GROUP_ID} 32 | 33 | When I run `wp bp group meta add {GROUP_ID} invite_status 'public'` 34 | Then STDOUT should not be empty 35 | 36 | When I run `wp bp group member add --group-id={GROUP_ID} --user-id={MEMBER_ID}` 37 | Then STDOUT should contain: 38 | """ 39 | Success: Added user #{MEMBER_ID} to group #{GROUP_ID} as member. 40 | """ 41 | 42 | When I run `wp bp group member create --group-id={GROUP_ID} --user-id={ANOTHER_MEMBER_ID}` 43 | Then STDOUT should contain: 44 | """ 45 | Success: Added user #{ANOTHER_MEMBER_ID} to group #{GROUP_ID} as member. 46 | """ 47 | 48 | When I run `wp bp group member list {GROUP_ID} --fields=id` 49 | Then STDOUT should be a table containing rows: 50 | | id | 51 | | {CREATOR_ID} | 52 | | {MEMBER_ID} | 53 | | {ANOTHER_MEMBER_ID} | 54 | 55 | When I run `wp bp group member promote --group-id={GROUP_ID} --user-id={MEMBER_ID} --role=mod` 56 | Then STDOUT should contain: 57 | """ 58 | Success: Member promoted to new role successfully. 59 | """ 60 | 61 | When I run `wp bp group member list {GROUP_ID} --fields=id --role=mod` 62 | Then STDOUT should be a table containing rows: 63 | | id | 64 | | {MEMBER_ID} | 65 | 66 | When I try `wp bp group member demote --group-id={GROUP_ID} --user-id={RANDON_MEMBER_ID}` 67 | Then the return code should be 1 68 | Then STDERR should be: 69 | """ 70 | Error: User is not a member of the group. 71 | """ 72 | 73 | When I run `wp bp group member demote --group-id={GROUP_ID} --user-id={MEMBER_ID}` 74 | Then STDOUT should contain: 75 | """ 76 | Success: User demoted to the "member" status. 77 | """ 78 | 79 | When I try `wp bp group member list {GROUP_ID} --fields=user_id --role=mod` 80 | Then the return code should be 1 81 | 82 | When I run `wp bp group member promote --group-id={GROUP_ID} --user-id={MEMBER_ID} --role=admin` 83 | Then STDOUT should contain: 84 | """ 85 | Success: Member promoted to new role successfully. 86 | """ 87 | 88 | When I run `wp bp group member promote --group-id={GROUP_ID} --user-id={ANOTHER_MEMBER_ID} --role=admin` 89 | Then STDOUT should contain: 90 | """ 91 | Success: Member promoted to new role successfully. 92 | """ 93 | 94 | When I run `wp bp group member demote --group-id={GROUP_ID} --user-id={ANOTHER_MEMBER_ID}` 95 | Then STDOUT should contain: 96 | """ 97 | Success: User demoted to the "member" status. 98 | """ 99 | 100 | When I run `wp bp group member ban --group-id={GROUP_ID} --user-id={ANOTHER_MEMBER_ID}` 101 | Then STDOUT should contain: 102 | """ 103 | Success: Member banned from the group. 104 | """ 105 | 106 | When I run `wp bp group member list {GROUP_ID} --fields=user_id --role=banned` 107 | Then STDOUT should be a table containing rows: 108 | | user_id | 109 | | {ANOTHER_MEMBER_ID} | 110 | 111 | When I run `wp bp group member unban --group-id={GROUP_ID} --user-id={ANOTHER_MEMBER_ID}` 112 | Then STDOUT should contain: 113 | """ 114 | Success: Member unbanned from the group. 115 | """ 116 | 117 | When I try `wp bp group member list {GROUP_ID} --fields=user_id --role=banned` 118 | Then the return code should be 1 119 | 120 | When I run `wp bp group member remove --group-id={GROUP_ID} --user-id={ANOTHER_MEMBER_ID}` 121 | Then STDOUT should contain: 122 | """ 123 | Success: Member #{ANOTHER_MEMBER_ID} removed from the group #{GROUP_ID}. 124 | """ 125 | -------------------------------------------------------------------------------- /features/group-meta.feature: -------------------------------------------------------------------------------- 1 | Feature: Manage BuddyPress Group custom fields 2 | 3 | Background: 4 | Given a WP install 5 | And these installed and active plugins: 6 | """ 7 | https://github.com/buddypress/BuddyPress/archive/master.zip 8 | """ 9 | And I run `wp bp component activate groups` 10 | 11 | Scenario: Group Meta CRUD 12 | 13 | When I run `wp bp group create --name="Totally Cool Group" --slug=totally-cool-group --porcelain` 14 | Then STDOUT should be a number 15 | And save STDOUT as {GROUP_ID} 16 | 17 | When I run `wp bp group meta add {GROUP_ID} foo 'bar'` 18 | Then STDOUT should not be empty 19 | 20 | When I run `wp bp group meta get {GROUP_ID} foo` 21 | Then STDOUT should be: 22 | """ 23 | bar 24 | """ 25 | 26 | When I try `wp bp group meta get 999999 foo` 27 | Then the return code should be 1 28 | Then STDERR should be: 29 | """ 30 | Error: Could not find the group with ID 999999. 31 | """ 32 | 33 | When I run `wp bp group meta set {GROUP_ID} foo '[ "1", "2" ]' --format=json` 34 | Then STDOUT should not be empty 35 | 36 | When I run `wp bp group meta get {GROUP_ID} foo --format=json` 37 | Then STDOUT should be: 38 | """ 39 | ["1","2"] 40 | """ 41 | 42 | When I run `wp bp group meta delete {GROUP_ID} foo` 43 | Then STDOUT should not be empty 44 | 45 | When I try `wp bp group meta get {GROUP_ID} foo` 46 | Then the return code should be 1 47 | 48 | Scenario: Add group meta with JSON serialization 49 | 50 | When I run `wp bp group create --name="Totally Cool Group" --slug=totally-cool-group --porcelain` 51 | Then STDOUT should be a number 52 | And save STDOUT as {GROUP_ID} 53 | 54 | When I run `wp bp group meta add {GROUP_ID} foo '"-- hi"' --format=json` 55 | Then STDOUT should contain: 56 | """ 57 | Success: 58 | """ 59 | 60 | When I run `wp bp group meta get {GROUP_ID} foo` 61 | Then STDOUT should be: 62 | """ 63 | -- hi 64 | """ 65 | 66 | Scenario: List group meta 67 | 68 | When I run `wp bp group create --name="Totally Cool Group" --slug=totally-cool-group --porcelain` 69 | Then STDOUT should be a number 70 | And save STDOUT as {GROUP_ID} 71 | 72 | When I run `wp bp group meta add {GROUP_ID} apple banana` 73 | And I run `wp bp group meta add {GROUP_ID} apple banana` 74 | Then STDOUT should not be empty 75 | 76 | When I run `wp bp group meta set {GROUP_ID} banana '["apple", "apple"]' --format=json` 77 | Then STDOUT should not be empty 78 | 79 | When I run `wp bp group meta list {GROUP_ID}` 80 | Then STDOUT should be a table containing rows: 81 | | group_id | meta_key | meta_value | 82 | | 1 | apple | banana | 83 | | 1 | apple | banana | 84 | | 1 | banana | a:2:{i:0;s:5:"apple";i:1;s:5:"apple";} | 85 | 86 | When I run `wp bp group meta list 1 --unserialize` 87 | Then STDOUT should be a table containing rows: 88 | | group_id | meta_key | meta_value | 89 | | 1 | apple | banana | 90 | | 1 | apple | banana | 91 | | 1 | banana | ["apple","apple"] | 92 | -------------------------------------------------------------------------------- /features/group.feature: -------------------------------------------------------------------------------- 1 | Feature: Manage BuddyPress Groups 2 | 3 | Background: 4 | Given a WP install 5 | And these installed and active plugins: 6 | """ 7 | https://github.com/buddypress/BuddyPress/archive/master.zip 8 | """ 9 | And I run `wp bp component activate groups` 10 | 11 | Scenario: Group CRUD 12 | 13 | When I run `wp bp group create --name="Totally Cool Group" --slug=totally-cool-group --porcelain` 14 | Then STDOUT should be a number 15 | And save STDOUT as {GROUP_ID} 16 | 17 | When I run `wp bp group get {GROUP_ID}` 18 | Then STDOUT should be a table containing rows: 19 | | Field | Value | 20 | | id | {GROUP_ID} | 21 | | name | Totally Cool Group | 22 | 23 | When I run `wp bp group get totally-cool-group` 24 | Then STDOUT should be a table containing rows: 25 | | Field | Value | 26 | | id | {GROUP_ID} | 27 | | name | Totally Cool Group | 28 | 29 | When I try `wp bp group get i-do-not-exist` 30 | Then the return code should be 1 31 | Then STDERR should be: 32 | """ 33 | Error: No group found by that slug or ID. 34 | """ 35 | 36 | When I run `wp bp group update {GROUP_ID} --description=foo` 37 | Then STDOUT should not be empty 38 | 39 | When I run `wp bp group get {GROUP_ID}` 40 | Then STDOUT should be a table containing rows: 41 | | Field | Value | 42 | | id | {GROUP_ID} | 43 | | name | Totally Cool Group | 44 | 45 | When I run `wp bp group delete {GROUP_ID} --yes` 46 | Then STDOUT should contain: 47 | """ 48 | Success: Deleted group {GROUP_ID}. 49 | """ 50 | 51 | When I try `wp bp group get {GROUP_ID}` 52 | Then the return code should be 1 53 | Then STDERR should be: 54 | """ 55 | Error: No group found by that slug or ID. 56 | """ 57 | 58 | Scenario: Group list 59 | 60 | When I run `wp bp group create --name="ZZZ Group 1" --slug=group1 --porcelain` 61 | Then STDOUT should be a number 62 | And save STDOUT as {GROUP_ONE_ID} 63 | 64 | When I run `wp bp group meta add {GROUP_ONE_ID} invite_status 'public'` 65 | Then STDOUT should not be empty 66 | 67 | When I run `wp bp group create --name="AAA Group 2" --slug=group2 --porcelain` 68 | Then STDOUT should be a number 69 | And save STDOUT as {GROUP_TWO_ID} 70 | 71 | When I run `wp bp group meta add {GROUP_TWO_ID} invite_status 'public'` 72 | Then STDOUT should not be empty 73 | 74 | When I run `wp bp group list --fields=id,name,slug` 75 | Then STDOUT should be a table containing rows: 76 | | id | name | slug | 77 | | {GROUP_ONE_ID} | ZZZ Group 1 | group1 | 78 | | {GROUP_TWO_ID} | AAA Group 2 | group2 | 79 | 80 | When I run `wp bp group list --fields=id,name,slug --orderby=name` 81 | Then STDOUT should be a table containing rows: 82 | | id | name | slug | 83 | | {GROUP_TWO_ID} | AAA Group 2 | group2 | 84 | | {GROUP_ONE_ID} | ZZZ Group 1 | group1 | 85 | 86 | When I run `wp bp group list --fields=id,name,slug --orderby=name --order=DESC` 87 | Then STDOUT should be a table containing rows: 88 | | id | name | slug | 89 | | {GROUP_ONE_ID} | ZZZ Group 1 | group1 | 90 | | {GROUP_TWO_ID} | AAA Group 2 | group2 | 91 | 92 | When I run `wp user create testuser1 testuser1@example.com --porcelain` 93 | Then STDOUT should be a number 94 | And save STDOUT as {MEMBER_ID} 95 | 96 | When I try `wp bp group list --fields=id --user-id={MEMBER_ID}` 97 | Then the return code should be 1 98 | 99 | When I run `wp bp group member add --group-id={GROUP_ONE_ID} --user-id={MEMBER_ID}` 100 | Then the return code should be 0 101 | 102 | When I run `wp bp group list --fields=id --user-id={MEMBER_ID}` 103 | Then STDOUT should be a table containing rows: 104 | | id | 105 | | {GROUP_ONE_ID} | 106 | -------------------------------------------------------------------------------- /features/message.feature: -------------------------------------------------------------------------------- 1 | Feature: Manage BuddyPress Messages 2 | 3 | Background: 4 | Given a WP install 5 | And these installed and active plugins: 6 | """ 7 | https://github.com/buddypress/BuddyPress/archive/master.zip 8 | """ 9 | And I run `wp bp component activate messages` 10 | 11 | Scenario: Message CRUD 12 | 13 | When I run `wp user create testuser1 testuser1@example.com --porcelain` 14 | Then STDOUT should be a number 15 | And save STDOUT as {BOB_ID} 16 | 17 | When I run `wp user create testuser2 testuser2@example.com --porcelain` 18 | Then STDOUT should be a number 19 | And save STDOUT as {SALLY_ID} 20 | 21 | When I run `wp bp message send-notice --subject="Important Notice" --content="Notice Message"` 22 | Then STDOUT should contain: 23 | """ 24 | Success: Notice was successfully sent. 25 | """ 26 | 27 | When I run `wp bp message create --from={BOB_ID} --to={SALLY_ID} --subject="Message" --content="Message Content" --porcelain` 28 | Then STDOUT should be a number 29 | And save STDOUT as {THREAD_ID} 30 | 31 | When I run `wp bp message star-thread {THREAD_ID} --user-id={SALLY_ID}` 32 | Then STDOUT should contain: 33 | """ 34 | Success: Thread was successfully starred. 35 | """ 36 | 37 | When I run `wp bp message unstar-thread {THREAD_ID} --user-id={SALLY_ID}` 38 | Then STDOUT should contain: 39 | """ 40 | Success: Thread was successfully unstarred. 41 | """ 42 | 43 | When I run `wp bp message delete-thread {THREAD_ID} --user-id={SALLY_ID} --yes` 44 | Then STDOUT should contain: 45 | """ 46 | Success: Thread successfully deleted. 47 | """ 48 | 49 | Scenario: Message list 50 | 51 | When I run `wp user create testuser2 testuser2@example.com --porcelain` 52 | And save STDOUT as {BOB_ID} 53 | 54 | When I run `wp user create testuser3 testuser3@example.com --porcelain` 55 | And save STDOUT as {SALLY_ID} 56 | 57 | When I try `wp bp message list --user-id={BOB_ID} --fields=id` 58 | Then the return code should be 1 59 | 60 | When I try `wp bp message list --user-id={SALLY_ID} --fields=id` 61 | Then the return code should be 1 62 | 63 | When I run `wp bp message create --from={BOB_ID} --to={SALLY_ID} --subject="Test Thread" --content="Message one" --porcelain` 64 | Then STDOUT should be a number 65 | And save STDOUT as {THREAD_ID} 66 | 67 | When I run `wp bp message create --from={SALLY_ID} --thread-id={THREAD_ID} --subject="Test Answer" --content="Message two"` 68 | Then STDOUT should contain: 69 | """ 70 | Success: Message successfully created. 71 | """ 72 | 73 | When I run `wp bp message create --from={BOB_ID} --thread-id={THREAD_ID} --subject="Another Answer" --content="Message three"` 74 | Then STDOUT should contain: 75 | """ 76 | Success: Message successfully created. 77 | """ 78 | 79 | When I run `wp bp message list --user-id={BOB_ID} --fields=sender_id` 80 | Then STDOUT should be a table containing rows: 81 | | sender_id | 82 | | {BOB_ID} | 83 | | {SALLY_ID} | 84 | | {BOB_ID} | 85 | 86 | When I run `wp bp message list --user-id={SALLY_ID} --fields=thread_id,sender_id,subject,message` 87 | Then STDOUT should be a table containing rows: 88 | | thread_id | sender_id | subject | message | 89 | | {THREAD_ID} | {BOB_ID} | Test Thread | Message one | 90 | | {THREAD_ID} | {SALLY_ID} | Test Answer | Message two | 91 | | {THREAD_ID} | {BOB_ID} | Another Answer | Message three | 92 | 93 | When I run `wp user create testuser4 testuser4@example.com --porcelain` 94 | And save STDOUT as {JOHN_ID} 95 | 96 | When I try `wp bp message list --user-id={JOHN_ID} --fields=id` 97 | Then the return code should be 1 98 | 99 | When I run `wp bp message create --from={JOHN_ID} --to={SALLY_ID} --subject="Second Thread" --content="Message four" --porcelain` 100 | Then STDOUT should be a number 101 | And save STDOUT as {ANOTHER_THREAD_ID} 102 | 103 | When I run `wp bp message create --from={SALLY_ID} --thread-id={ANOTHER_THREAD_ID} --subject="Final Message" --content="Final Message"` 104 | Then STDOUT should contain: 105 | """ 106 | Success: Message successfully created. 107 | """ 108 | 109 | When I run `wp bp message list --user-id={JOHN_ID} --fields=thread_id,sender_id,subject,message` 110 | Then STDOUT should be a table containing rows: 111 | | thread_id | sender_id | subject | message | 112 | | {ANOTHER_THREAD_ID} | {JOHN_ID} | Second Thread | Message four | 113 | -------------------------------------------------------------------------------- /features/notification.feature: -------------------------------------------------------------------------------- 1 | Feature: Manage BuddyPress Notifications 2 | 3 | Background: 4 | Given a WP install 5 | And these installed and active plugins: 6 | """ 7 | https://github.com/buddypress/BuddyPress/archive/master.zip 8 | """ 9 | And I run `wp bp component activate notifications` 10 | 11 | Scenario: Notifications CRUD 12 | 13 | When I run `wp user create testuser2 testuser2@example.com --first_name=test --last_name=user --role=subscriber --porcelain` 14 | Then STDOUT should be a number 15 | And save STDOUT as {MEMBER_ID} 16 | 17 | When I run `wp bp notification create --component=activity --action=comment_reply --user-id={MEMBER_ID} --porcelain` 18 | Then STDOUT should be a number 19 | And save STDOUT as {NOTIFICATION_ID} 20 | 21 | When I run `wp bp notification get {NOTIFICATION_ID} --fields=user_id,component_name,component_action` 22 | Then STDOUT should be a table containing rows: 23 | | Field | Value | 24 | | user_id | {MEMBER_ID} | 25 | | component_name | activity | 26 | | component_action | comment_reply | 27 | 28 | When I run `wp bp notification delete {NOTIFICATION_ID} --yes` 29 | Then STDOUT should contain: 30 | """ 31 | Success: Deleted notification {NOTIFICATION_ID}. 32 | """ 33 | 34 | Scenario: Notification list 35 | 36 | When I run `wp user create testuser1 testuser1@example.com --first_name=test --last_name=user --role=subscriber --porcelain` 37 | Then STDOUT should be a number 38 | And save STDOUT as {MEMBER_ONE_ID} 39 | 40 | When I run `wp user create testuser2 testuser2@example.com --first_name=test --last_name=user --role=subscriber --porcelain` 41 | Then STDOUT should be a number 42 | And save STDOUT as {MEMBER_TWO_ID} 43 | 44 | When I run `wp bp notification create --component=groups --user-id={MEMBER_ONE_ID} --porcelain` 45 | Then STDOUT should be a number 46 | And save STDOUT as {NOTIFICATION_ONE_ID} 47 | 48 | When I run `wp bp notification create --component=activity --user-id={MEMBER_TWO_ID} --porcelain` 49 | Then STDOUT should be a number 50 | And save STDOUT as {NOTIFICATION_TWO_ID} 51 | 52 | When I run `wp bp notification delete {NOTIFICATION_ONE_ID} {NOTIFICATION_TWO_ID} --yes` 53 | Then STDOUT should contain: 54 | """ 55 | Success: Deleted notification {NOTIFICATION_ONE_ID}. 56 | Success: Deleted notification {NOTIFICATION_TWO_ID}. 57 | """ 58 | -------------------------------------------------------------------------------- /features/scaffold.feature: -------------------------------------------------------------------------------- 1 | Feature: Scaffold BuddyPress tests 2 | 3 | Background: 4 | Given a WP install 5 | And these installed and active plugins: 6 | """ 7 | https://github.com/buddypress/BuddyPress/archive/master.zip 8 | """ 9 | 10 | Scenario: Scaffold plugin tests 11 | When I run `wp plugin path` 12 | Then save STDOUT as {PLUGIN_DIR} 13 | 14 | When I run `wp scaffold plugin hello-world` 15 | Then STDOUT should not be empty 16 | And the {PLUGIN_DIR}/hello-world/hello-world.php file should exist 17 | And the {PLUGIN_DIR}/hello-world/tests directory should exist 18 | 19 | When I run `wp bp scaffold tests hello-world` 20 | Then STDOUT should not be empty 21 | And the {PLUGIN_DIR}/hello-world/tests directory should contain: 22 | """ 23 | bootstrap.php 24 | """ 25 | And the {PLUGIN_DIR}/hello-world/tests directory should contain: 26 | """ 27 | bootstrap-buddypress.php 28 | """ 29 | And the {PLUGIN_DIR}/hello-world/tests/bootstrap-buddypress.php file should contain: 30 | """ 31 | require_once getenv( 'BP_TESTS_DIR' ) . '/includes/loader.php'; 32 | """ 33 | And the {PLUGIN_DIR}/hello-world/bin directory should contain: 34 | """ 35 | install-bp-tests.sh 36 | """ 37 | When I run `wp eval "if ( is_executable( '{PLUGIN_DIR}/hello-world/bin/install-bp-tests.sh' ) ) { echo 'executable'; } else { exit( 1 ); }"` 38 | Then STDOUT should be: 39 | """ 40 | executable 41 | """ 42 | -------------------------------------------------------------------------------- /features/signup.feature: -------------------------------------------------------------------------------- 1 | Feature: Manage BuddyPress Signups 2 | 3 | Background: 4 | Given a WP install 5 | And these installed and active plugins: 6 | """ 7 | https://github.com/buddypress/BuddyPress/archive/master.zip 8 | """ 9 | And I run `wp bp tool signup 1` 10 | 11 | Scenario: Signups CRUD 12 | 13 | When I run `wp bp signup add --user-login=test_user --user-email=test@example.com --porcelain` 14 | Then STDOUT should be a number 15 | And save STDOUT as {SIGNUP_ID} 16 | 17 | When I run `wp bp signup list --fields=signup_id,user_login,user_email` 18 | Then STDOUT should be a table containing rows: 19 | | signup_id | user_login | user_email | 20 | | {SIGNUP_ID} | test_user | test@example.com | 21 | 22 | When I run `wp bp signup delete {SIGNUP_ID} --yes` 23 | Then STDOUT should contain: 24 | """ 25 | Success: Signup deleted {SIGNUP_ID}. 26 | """ 27 | 28 | Scenario: Signup fetching by identifier 29 | 30 | When I run `wp bp signup add --user-login=signup1 --user-email=signup1@example.com --porcelain` 31 | Then STDOUT should be a number 32 | And save STDOUT as {SIGNUP_ONE_ID} 33 | 34 | When I run `wp bp signup get {SIGNUP_ONE_ID} --fields=signup_id,user_login,user_email` 35 | Then STDOUT should be a table containing rows: 36 | | Field | Value | 37 | | signup_id | {SIGNUP_ONE_ID} | 38 | | user_login | signup1 | 39 | | user_email | signup1@example.com | 40 | 41 | When I run `wp bp signup add --user-login={SIGNUP_ONE_ID} --user-email=signup2@example.com --porcelain` 42 | Then STDOUT should be a number 43 | And save STDOUT as {SIGNUP_TWO_ID} 44 | 45 | When I run `wp bp signup get {SIGNUP_ONE_ID} --fields=signup_id,user_login,user_email` 46 | Then STDOUT should be a table containing rows: 47 | | Field | Value | 48 | | signup_id | {SIGNUP_ONE_ID} | 49 | | user_login | signup1 | 50 | | user_email | signup1@example.com | 51 | 52 | When I run `wp bp signup get {SIGNUP_ONE_ID} --fields=signup_id,user_login,user_email --match-field=user_login` 53 | Then STDOUT should be a table containing rows: 54 | | Field | Value | 55 | | signup_id | {SIGNUP_TWO_ID} | 56 | | user_login | {SIGNUP_ONE_ID} | 57 | | user_email | signup2@example.com | 58 | 59 | Scenario: Signup activation 60 | 61 | When I run `wp bp signup add --user-login=test_user --user-email=test@example.com --porcelain` 62 | Then STDOUT should be a number 63 | And save STDOUT as {SIGNUP_ID} 64 | 65 | When I run `wp bp signup activate {SIGNUP_ID}` 66 | Then STDOUT should contain: 67 | """ 68 | Signup activated 69 | """ 70 | 71 | When I run `wp user get test_user --field=user_email` 72 | Then STDOUT should contain: 73 | """ 74 | test@example.com 75 | """ 76 | 77 | Scenario: Signup resending 78 | 79 | When I run `wp bp signup add --user-login=test_user --user-email=test@example.com --porcelain` 80 | Then STDOUT should be a number 81 | And save STDOUT as {SIGNUP_ID} 82 | 83 | When I run `wp bp signup resend {SIGNUP_ID}` 84 | Then STDOUT should contain: 85 | """ 86 | success 87 | """ 88 | -------------------------------------------------------------------------------- /features/sitewide-notice.feature: -------------------------------------------------------------------------------- 1 | Feature: Manage BuddyPress Site Notices 2 | 3 | Background: 4 | Given a WP install 5 | And these installed and active plugins: 6 | """ 7 | https://github.com/buddypress/BuddyPress/archive/master.zip 8 | """ 9 | And I run `wp bp component activate messages` 10 | 11 | Scenario: Site Notices CRUD 12 | 13 | When I run `wp bp notice create --subject="Test" --message="Content" --porcelain` 14 | Then STDOUT should be a number 15 | And save STDOUT as {NOTICE_ID} 16 | 17 | When I run `wp bp notice deactivate {NOTICE_ID}` 18 | Then STDOUT should contain: 19 | """ 20 | Success: Sitewide notice has been deactivated. 21 | """ 22 | 23 | When I run `wp bp notice activate {NOTICE_ID}` 24 | Then STDOUT should contain: 25 | """ 26 | Success: Sitewide notice activated. 27 | """ 28 | 29 | When I run `wp bp notice get {NOTICE_ID} --fields=id,subject,message` 30 | Then STDOUT should be a table containing rows: 31 | | Field | Value | 32 | | id | {NOTICE_ID} | 33 | | subject | Test | 34 | | message | Content | 35 | 36 | When I run `wp bp notice delete {NOTICE_ID} --yes` 37 | Then STDOUT should contain: 38 | """ 39 | Success: Sitewide notice deleted {NOTICE_ID}. 40 | """ 41 | 42 | Scenario: Site Notices list 43 | 44 | When I run `wp bp notice create --subject="Test" --message="Content" --porcelain` 45 | Then STDOUT should be a number 46 | And save STDOUT as {NOTICE_ONE_ID} 47 | 48 | When I run `wp bp notice create --subject="Test 2" --message="Content 2" --porcelain` 49 | Then STDOUT should be a number 50 | And save STDOUT as {NOTICE_TWO_ID} 51 | 52 | When I run `wp bp notice list --fields=id,subject,message,is_active` 53 | Then STDOUT should be a table containing rows: 54 | | id | subject | message | is_active | 55 | | {NOTICE_ONE_ID} | Test | Content | 0 | 56 | | {NOTICE_TWO_ID} | Test 2 | Content 2 | 1 | 57 | 58 | When I try `wp bp notice activate 999999` 59 | Then the return code should be 1 60 | Then STDERR should be: 61 | """ 62 | Error: No sitewide notice found by that ID. 63 | """ 64 | 65 | When I run `wp bp notice activate {NOTICE_ONE_ID}` 66 | Then STDOUT should contain: 67 | """ 68 | Success: Sitewide notice activated. 69 | """ 70 | 71 | When I run `wp bp notice list --fields=id,subject,message,is_active` 72 | Then STDOUT should be a table containing rows: 73 | | id | subject | message | is_active | 74 | | {NOTICE_ONE_ID} | Test | Content | 1 | 75 | | {NOTICE_TWO_ID} | Test 2 | Content 2 | 0 | 76 | 77 | When I run `wp bp notice delete {NOTICE_ONE_ID} {NOTICE_TWO_ID} --yes` 78 | Then STDOUT should contain: 79 | """ 80 | Success: Sitewide notice deleted {NOTICE_ONE_ID}. 81 | Success: Sitewide notice deleted {NOTICE_TWO_ID}. 82 | """ 83 | 84 | When I try `wp bp notice deactivate 999999` 85 | Then the return code should be 1 86 | Then STDERR should be: 87 | """ 88 | Error: No sitewide notice found by that ID. 89 | """ 90 | -------------------------------------------------------------------------------- /features/tool.feature: -------------------------------------------------------------------------------- 1 | Feature: Manage BuddyPress Tools 2 | 3 | Background: 4 | Given a WP install 5 | And these installed and active plugins: 6 | """ 7 | https://github.com/buddypress/BuddyPress/archive/master.zip 8 | """ 9 | And I run `wp bp component activate friends` 10 | And I run `wp bp component activate groups` 11 | 12 | Scenario: BuddyPress tool 13 | 14 | When I run `wp bp tool repair friend-count` 15 | Then STDOUT should contain: 16 | """ 17 | Complete! 18 | """ 19 | 20 | When I run `wp bp tool repair group-count` 21 | Then STDOUT should contain: 22 | """ 23 | Complete! 24 | """ 25 | 26 | When I run `wp bp tool signup 1` 27 | Then STDOUT should contain: 28 | """ 29 | Success: Signup tool updated. 30 | """ 31 | -------------------------------------------------------------------------------- /features/xprofile-data.feature: -------------------------------------------------------------------------------- 1 | Feature: Manage BuddyPress XProfile Data 2 | 3 | Background: 4 | Given a WP install 5 | And these installed and active plugins: 6 | """ 7 | https://github.com/buddypress/BuddyPress/archive/master.zip 8 | """ 9 | And I run `wp bp component activate xprofile` 10 | 11 | Scenario: XProfile Data CRUD 12 | 13 | When I run `wp bp xprofile group create --name="Group Name" --description="Group Description" --porcelain` 14 | Then STDOUT should be a number 15 | And save STDOUT as {GROUP_ID} 16 | 17 | When I run `wp bp xprofile field create --field-group-id={GROUP_ID} --name="Field Name" --porcelain` 18 | Then STDOUT should be a number 19 | And save STDOUT as {FIELD_ID} 20 | 21 | When I run `wp user create testuser1 testuser1@example.com --porcelain` 22 | Then STDOUT should be a number 23 | And save STDOUT as {USER_ID} 24 | 25 | When I run `wp bp xprofile data set --field-id={FIELD_ID} --user-id={USER_ID} --value=foo` 26 | Then STDOUT should contain: 27 | """ 28 | Updated 29 | """ 30 | 31 | When I run `wp bp xprofile data get --user-id={USER_ID} --field-id={FIELD_ID}` 32 | Then STDOUT should be: 33 | """ 34 | foo 35 | """ 36 | 37 | When I run `wp bp xprofile data see --user-id={USER_ID}` 38 | Then STDOUT should be a table containing rows: 39 | | field_id | field_name | value | 40 | | {FIELD_ID} | Field Name | "foo" | 41 | 42 | When I try `wp bp xprofile data delete --user-id={USER_ID} --yes` 43 | Then the return code should be 1 44 | Then STDERR should be: 45 | """ 46 | Error: Either --field-id or --delete-all must be provided. 47 | """ 48 | 49 | When I run `wp bp xprofile data delete --user-id={USER_ID} --field-id={FIELD_ID} --yes` 50 | Then STDOUT should contain: 51 | """ 52 | XProfile data removed 53 | """ 54 | 55 | When I run `wp bp xprofile data get --user-id={USER_ID} --field-id={FIELD_ID}` 56 | Then STDOUT should not contain: 57 | """ 58 | foo 59 | """ 60 | -------------------------------------------------------------------------------- /features/xprofile-field.feature: -------------------------------------------------------------------------------- 1 | Feature: Manage BuddyPress XProfile Fields 2 | 3 | Background: 4 | Given a WP install 5 | And these installed and active plugins: 6 | """ 7 | https://github.com/buddypress/BuddyPress/archive/master.zip 8 | """ 9 | And I run `wp bp component activate xprofile` 10 | 11 | Scenario: XProfile Field CRUD 12 | 13 | When I run `wp bp xprofile group create --name="Group Name" --description="Group Description" --porcelain` 14 | Then STDOUT should be a number 15 | And save STDOUT as {GROUP_ID} 16 | 17 | When I run `wp bp xprofile field create --type=checkbox --field-group-id={GROUP_ID} --name="Field Name" --porcelain` 18 | Then STDOUT should be a number 19 | And save STDOUT as {FIELD_ID} 20 | 21 | When I run `wp bp xprofile field get {FIELD_ID}` 22 | Then STDOUT should be a table containing rows: 23 | | Field | Value | 24 | | id | {FIELD_ID} | 25 | | group_id | {GROUP_ID} | 26 | | name | Field Name | 27 | | type | checkbox | 28 | 29 | When I run `wp bp xprofile field see {FIELD_ID} --fields=id,type` 30 | Then STDOUT should be a table containing rows: 31 | | Field | Value | 32 | | id | {FIELD_ID} | 33 | | type | checkbox | 34 | 35 | When I run `wp bp xprofile field delete {FIELD_ID} --yes` 36 | Then STDOUT should contain: 37 | """ 38 | Deleted XProfile field 39 | """ 40 | 41 | When I try `wp bp xprofile field delete {FIELD_ID} --yes` 42 | Then the return code should be 1 43 | -------------------------------------------------------------------------------- /features/xprofile-group.feature: -------------------------------------------------------------------------------- 1 | Feature: Manage BuddyPress XProfile Groups 2 | 3 | Background: 4 | Given a WP install 5 | And these installed and active plugins: 6 | """ 7 | https://github.com/buddypress/BuddyPress/archive/master.zip 8 | """ 9 | And I run `wp bp component activate xprofile` 10 | 11 | Scenario: XProfile Group CRUD 12 | 13 | When I run `wp bp xprofile group create --name="Group Name" --description="Group Description" --porcelain` 14 | Then STDOUT should be a number 15 | And save STDOUT as {GROUP_ID} 16 | 17 | When I run `wp bp xprofile group get {GROUP_ID}` 18 | Then STDOUT should be a table containing rows: 19 | | Field | Value | 20 | | id | {GROUP_ID} | 21 | | name | Group Name | 22 | | description | Group Description | 23 | | can_delete | 1 | 24 | | group_order | 0 | 25 | 26 | When I run `wp bp xprofile group see {GROUP_ID} --fields=id` 27 | Then STDOUT should be a table containing rows: 28 | | Field | Value | 29 | | id | {GROUP_ID} | 30 | 31 | When I run `wp bp xprofile group delete {GROUP_ID} --yes` 32 | Then STDOUT should contain: 33 | """ 34 | Field group deleted {GROUP_ID}. 35 | """ 36 | 37 | When I try `wp bp xprofile group get {GROUP_ID}` 38 | Then the return code should be 1 39 | -------------------------------------------------------------------------------- /phpcs.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | src 9 | wp-cli-bp.php 10 | 11 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | */src/templates/bootstrap-buddypress.php 41 | 42 | 43 | 44 | */src/templates/bootstrap-buddypress.php 45 | 46 | 47 | 48 | 0 49 | 50 | 51 | 52 | 0 53 | 54 | 55 | 56 | 0 57 | 58 | 59 | 60 | 0 61 | 62 | 63 | 64 | 0 65 | 66 | 67 | 68 | 0 69 | 70 | 71 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # buddypress/wp-cli-buddypress 2 | 3 | Manage BuddyPress through the command-line. 4 | 5 | ## Installing 6 | 7 | The `wp-cli-buddypress` comes installed by default with BuddyPress. So if you need to use the latest version, run: 8 | 9 | ```bash 10 | wp package install git@github.com:buddypress/wp-cli-buddypress.git 11 | ``` 12 | 13 | In many cases the default memory limit will not be enough to run composer, so running the following instead is generally recommended: 14 | 15 | ```bash 16 | php -d memory_limit=512M "$(which wp)" package install git@github.com:buddypress/wp-cli-buddypress.git 17 | ``` 18 | 19 | ## Using 20 | 21 | This package adds commands to all core BuddyPress components. The component used **needs** to be activated for it to be used. Here are a few examples: 22 | 23 | ### wp bp 24 | 25 | Manage all BuddyPress commands. 26 | 27 | ```bash 28 | wp bp 29 | ``` 30 | 31 | ### wp bp activity 32 | 33 | Manage BuddyPress Activities. 34 | 35 | ```bash 36 | # Create Activity 37 | $ wp bp activity create 38 | Success: Successfully created new activity item (ID #5464). 39 | 40 | # Create Group Activity 41 | $ wp bp activity add --component=groups --item-id=2 --user-id=10 42 | Success: Successfully created new activity item (ID #48949) 43 | ``` 44 | 45 | ### wp bp group 46 | 47 | Manage BuddyPress Groups. 48 | 49 | ```bash 50 | # Create Group 51 | $ wp bp group create --name="Totally Cool Group" 52 | Success: Group (ID 5465) created: http://example.com/groups/totally-cool-group/ 53 | 54 | # Delete a Group 55 | $ wp bp group delete group-slug --yes 56 | Success: Group successfully deleted. 57 | ``` 58 | 59 | ### wp bp messages 60 | 61 | Manage BuddyPress Messages. 62 | 63 | ```bash 64 | # Create message 65 | wp bp message create --from=user1 --to=user2 --subject="Message Title" --content="We are ready" 66 | Success: Message successfully created. 67 | 68 | # Delete thread 69 | $ wp bp message delete-thread 456456 --user-id=user_logon --yes 70 | Success: Thread successfully deleted. 71 | ``` 72 | 73 | ### wp bp xprofile 74 | 75 | Manage BuddyPress XProfile. 76 | 77 | ```bash 78 | # Create a xprofile group. 79 | $ wp bp xprofile group create --name="Group Name" --description="Xprofile Group Description" 80 | Success: Created XProfile field group "Group Name" (ID 123). 81 | 82 | # List xprofile fields. 83 | $ wp bp xprofile field list 84 | 85 | # Save a xprofile data to a user with its field and value. 86 | $ wp bp xprofile data set --user-id=45 --field-id=120 --value=teste 87 | Success: Updated XProfile field "Field Name" (ID 120) with value "teste" for user user_login (ID 45). 88 | ``` 89 | 90 | ### wp bp notification 91 | 92 | Manage BuddyPress Notifications. 93 | 94 | ```bash 95 | # Create notification item. 96 | $ wp bp notification create 97 | Success: Successfully created new notification. (ID #5464) 98 | 99 | # Delete a notification item. 100 | $ wp bp notification delete 520 101 | Success: Notification deleted. 102 | ``` 103 | 104 | ### wp bp email 105 | 106 | Manage BuddyPress Emails 107 | 108 | ```bash 109 | # Create email 110 | $ wp bp email create --type=new-event --type-description="Send an email when a new event is created" --subject="[{{{site.name}}}] A new event was created" --content="A new event was created" --plain-text-content="A new event was created" 111 | Success: Email post created for type "new-event". 112 | 113 | # Create email with content from given file 114 | $ wp bp email create ./email-content.txt --type=new-event --type-description="Send an email when a new event is created" --subject="[{{{site.name}}}] A new event was created" --plain-text-content="A new event was created" 115 | Success: Email post created for type "new-event". 116 | ``` 117 | 118 | ### wp bp member 119 | 120 | Manage BuddyPress Members. 121 | 122 | ```bash 123 | # Generate BuddyPress members. 124 | $ wp bp member generate 125 | ``` 126 | 127 | ### wp bp signup 128 | 129 | Manage BuddyPress Signups 130 | 131 | ```bash 132 | # Create a signup 133 | $ wp bp signup create --user-login=test_user --user-email=teste@site.com 134 | Success: Successfully added new user signup (ID #345). 135 | 136 | # Activate a signup 137 | $ wp bp signup activate ee48ec319fef3nn4 138 | Success: Signup activated, new user (ID #545). 139 | ``` 140 | 141 | ### wp bp tool 142 | 143 | Manage BuddyPress repairs tools. 144 | 145 | ```bash 146 | # Repairing friend-count 147 | $ wp bp tool repair friend-count 148 | Success: Counting the number of friends for each user. Complete! 149 | 150 | # Activate signup 151 | $ wp bp tool signup 1 152 | Success: Signup tool updated. 153 | ``` 154 | 155 | ## Support 156 | 157 | Github issues aren't for general support questions, there are other venues you can try: 158 | -------------------------------------------------------------------------------- /src/activity-favorite.php: -------------------------------------------------------------------------------- 1 | 49 | * : ID of the activity. 50 | * 51 | * 52 | * : Identifier for the user. Accepts either a user_login or a numeric ID. 53 | * 54 | * ## EXAMPLES 55 | * 56 | * # Add an activity item as a favorite. 57 | * $ wp bp activity favorite add 100 500 58 | * Success: Activity item added as a favorite for the user. 59 | * 60 | * # Add an activity item as a favorite using a user_login identifier. 61 | * $ wp bp activity favorite create 100 user_test 62 | * Success: Activity item added as a favorite for the user. 63 | * 64 | * @alias add 65 | */ 66 | public function create( $args ) { 67 | $activity_id = $args[0]; 68 | 69 | if ( ! is_numeric( $activity_id ) ) { 70 | WP_CLI::error( 'Please provide a numeric activity ID.' ); 71 | } 72 | 73 | $activity = bp_activity_get_specific( 74 | [ 75 | 'activity_ids' => $activity_id, 76 | 'spam' => null, 77 | 'display_comments' => true, 78 | ] 79 | ); 80 | 81 | if ( ! isset( $activity['activities'][0] ) || ! is_object( $activity['activities'][0] ) ) { 82 | WP_CLI::error( 'No activity found.' ); 83 | } 84 | 85 | $activity = $activity['activities'][0]; 86 | $user = $this->get_user_id_from_identifier( $args[1] ); 87 | 88 | if ( bp_activity_add_user_favorite( $activity->id, $user->ID ) ) { 89 | WP_CLI::success( 'Activity item added as a favorite for the user.' ); 90 | } else { 91 | WP_CLI::error( 'Could not add the activity item.' ); 92 | } 93 | } 94 | 95 | /** 96 | * Remove an activity item as a favorite for a user. 97 | * 98 | * ## OPTIONS 99 | * 100 | * 101 | * : ID of the activity. 102 | * 103 | * 104 | * : Identifier for the user. Accepts either a user_login or a numeric ID. 105 | * 106 | * [--yes] 107 | * : Answer yes to the confirmation message. 108 | * 109 | * ## EXAMPLES 110 | * 111 | * # Remove an activity item as a favorite for a user. 112 | * $ wp bp activity favorite remove 100 500 113 | * Success: Activity item removed as a favorite for the user. 114 | * 115 | * # Remove an activity item as a favorite for a user. 116 | * $ wp bp activity favorite delete 100 user_test --yes 117 | * Success: Activity item removed as a favorite for the user. 118 | * 119 | * @alias remove 120 | * @alias trash 121 | */ 122 | public function delete( $args, $assoc_args ) { 123 | $activity_id = $args[0]; 124 | 125 | if ( ! is_numeric( $activity_id ) ) { 126 | WP_CLI::error( 'Please provide a numeric activity ID.' ); 127 | } 128 | 129 | $activity = bp_activity_get_specific( 130 | [ 131 | 'activity_ids' => $activity_id, 132 | 'spam' => null, 133 | 'display_comments' => true, 134 | ] 135 | ); 136 | 137 | if ( ! isset( $activity['activities'][0] ) || ! is_object( $activity['activities'][0] ) ) { 138 | WP_CLI::error( 'No activity found.' ); 139 | } 140 | 141 | $activity = $activity['activities'][0]; 142 | $user = $this->get_user_id_from_identifier( $args[1] ); 143 | 144 | WP_CLI::confirm( 'Are you sure you want to remove this activity item?', $assoc_args ); 145 | 146 | if ( bp_activity_remove_user_favorite( $activity->id, $user->ID ) ) { 147 | WP_CLI::success( 'Activity item removed as a favorite for the user.' ); 148 | } else { 149 | WP_CLI::error( 'Could not remove the activity item.' ); 150 | } 151 | } 152 | 153 | /** 154 | * Get a user's favorite activity items. 155 | * 156 | * ## OPTIONS 157 | * 158 | * 159 | * : Identifier for the user. Accepts either a user_login or a numeric ID. 160 | * 161 | * [--=] 162 | * : One or more parameters to pass to \BP_Activity_Activity::get() 163 | * 164 | * [--count=] 165 | * : How many activity favorites to list. 166 | * --- 167 | * default: 50 168 | * --- 169 | * 170 | * [--format=] 171 | * : Render output in a particular format. 172 | * --- 173 | * default: table 174 | * options: 175 | * - table 176 | * - csv 177 | * - ids 178 | * - json 179 | * - count 180 | * - yaml 181 | * --- 182 | * 183 | * ## EXAMPLE 184 | * 185 | * # Get a user's favorite activity items. 186 | * $ wp bp activity favorite list 315 187 | * 188 | * @subcommand list 189 | * @alias user-items 190 | */ 191 | public function list_( $args, $assoc_args ) { 192 | $user = $this->get_user_id_from_identifier( $args[0] ); 193 | $favorites = bp_activity_get_user_favorites( $user->ID ); 194 | 195 | if ( empty( $favorites ) ) { 196 | WP_CLI::error( 'No favorite found for this user.' ); 197 | } 198 | 199 | $activities = bp_activity_get_specific( 200 | [ 201 | 'activity_ids' => (array) $favorites, 202 | 'per_page' => $assoc_args['count'], 203 | ] 204 | ); 205 | 206 | // Sanity check. 207 | if ( empty( $activities['activities'] ) ) { 208 | WP_CLI::error( 'No favorite found for this user.' ); 209 | } 210 | 211 | $activities = $activities['activities']; 212 | $formatter = $this->get_formatter( $assoc_args ); 213 | $formatter->display_items( 'ids' === $formatter->format ? wp_list_pluck( $activities, 'id' ) : $activities ); 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /src/activity-fetcher.php: -------------------------------------------------------------------------------- 1 | id ) ) { 29 | return false; 30 | } 31 | 32 | return $activity; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/activity-meta.php: -------------------------------------------------------------------------------- 1 | get_check( $object_id ); 122 | 123 | return $activity->id; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/buddypress.php: -------------------------------------------------------------------------------- 1 | obj_fields ); 36 | } 37 | 38 | /** 39 | * Get a random user id. 40 | * 41 | * @global wpdb $wpdb WordPress database abstraction object. 42 | * 43 | * @since 1.1 44 | * 45 | * @return int 46 | */ 47 | protected function get_random_user_id() { 48 | global $wpdb; 49 | return (int) $wpdb->get_var( "SELECT ID FROM $wpdb->users ORDER BY RAND() LIMIT 1" ); 50 | } 51 | 52 | /** 53 | * Get an activity ID. 54 | * 55 | * @since 2.0 56 | * 57 | * @param int $activity_id Activity ID. 58 | * @param bool $activity_object Return BP_Activity_Activity object. 59 | * @return int|BP_Activity_Activity 60 | */ 61 | protected function get_activity_id_from_identifier( $activity_id, $activity_object = false ) { 62 | $fetcher = new Activity_Fetcher(); 63 | $activity = $fetcher->get_check( $activity_id ); 64 | 65 | if ( true === $activity_object ) { 66 | return $activity; 67 | } 68 | 69 | return $activity->id; 70 | } 71 | 72 | /** 73 | * Get a group ID from its identifier (ID or slug). 74 | * 75 | * @since 1.5.0 76 | * 77 | * @param int|string $group_id Group ID or slug. 78 | * @return int|bool 79 | */ 80 | protected function get_group_id_from_identifier( $group_id ) { 81 | // Group ID or slug. 82 | if ( ! is_numeric( $group_id ) ) { 83 | $group_id = groups_get_id( $group_id ); 84 | } 85 | 86 | // Get group object. 87 | $group_obj = groups_get_group( 88 | [ 'group_id' => $group_id ] 89 | ); 90 | 91 | if ( empty( $group_obj->id ) ) { 92 | WP_CLI::error( 'No group found by that slug or ID.' ); 93 | } 94 | 95 | return intval( $group_obj->id ); 96 | } 97 | 98 | /** 99 | * Verify a user ID by the passed identifier. 100 | * 101 | * @since 1.2.0 102 | * 103 | * @param mixed $identifier User ID, email, or login. 104 | * @return WP_User 105 | */ 106 | protected function get_user_id_from_identifier( $identifier ) { 107 | if ( is_numeric( $identifier ) ) { 108 | $user = get_user_by( 'id', $identifier ); 109 | } elseif ( is_email( $identifier ) ) { 110 | $user = get_user_by( 'email', $identifier ); 111 | } else { 112 | $user = get_user_by( 'login', $identifier ); 113 | } 114 | 115 | if ( ! $user ) { 116 | WP_CLI::error( sprintf( 'No user found by that username or ID (%s).', $identifier ) ); 117 | } 118 | 119 | return $user; 120 | } 121 | 122 | /** 123 | * Generate random text 124 | * 125 | * @since 1.1 126 | * 127 | * @return string 128 | */ 129 | protected function generate_random_text() { 130 | return 'Here is some random text'; 131 | } 132 | 133 | /** 134 | * Get field from an ID. 135 | * 136 | * @since 1.5.0 137 | * 138 | * @param int|string $field_id Field ID or Field name. 139 | * @return int Field ID. 140 | */ 141 | protected function get_field_id( $field_id ) { 142 | if ( ! is_numeric( $field_id ) ) { 143 | return xprofile_get_field_id_from_name( $field_id ); 144 | } 145 | 146 | return absint( $field_id ); 147 | } 148 | 149 | /** 150 | * String sanitization. 151 | * 152 | * @since 1.5.0 153 | * 154 | * @param string $type String to sanitize. 155 | * @return string Sanitized string. 156 | */ 157 | protected function sanitize_string( $type ) { 158 | return strtolower( str_replace( '-', '_', $type ) ); 159 | } 160 | 161 | /** 162 | * Pull up a random active component. 163 | * 164 | * @since 1.1 165 | * 166 | * @return string 167 | */ 168 | protected function get_random_component() { 169 | $c = buddypress()->active_components; 170 | $ca = $this->get_components_and_actions(); 171 | 172 | return array_rand( (array) array_flip( array_intersect( array_keys( $c ), array_keys( $ca ) ) ) ); 173 | } 174 | 175 | /** 176 | * Get a list of activity components and actions. 177 | * 178 | * @since 1.1 179 | * 180 | * @return array 181 | */ 182 | protected function get_components_and_actions() { 183 | return array_map( 184 | function ( $component ) { 185 | return array_keys( (array) $component ); 186 | }, 187 | (array) bp_activity_get_actions() 188 | ); 189 | } 190 | 191 | /** 192 | * Generate callback. 193 | * 194 | * @param string $message Message to display. 195 | * @param array $assoc_args Command arguments. 196 | * @param callable $callback Callback to execute. 197 | */ 198 | protected function generate_callback( $message, $assoc_args, $callback ) { 199 | $format = WP_CLI\Utils\get_flag_value( $assoc_args, 'format', 'progress' ); 200 | $limit = $assoc_args['count']; 201 | $notify = false; 202 | 203 | if ( 'progress' === $format ) { 204 | $notify = WP_CLI\Utils\make_progress_bar( $message, $limit ); 205 | } 206 | 207 | for ( $index = 0; $index < $limit; $index++ ) { 208 | $object_id = call_user_func( $callback, $assoc_args, $format ); 209 | 210 | if ( 'progress' === $format ) { 211 | $notify->tick(); 212 | } elseif ( 'ids' === $format ) { 213 | echo $object_id; 214 | if ( $index < $limit - 1 ) { 215 | echo ' '; 216 | } 217 | } 218 | } 219 | 220 | if ( 'progress' === $format ) { 221 | $notify->finish(); 222 | } 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /src/components.php: -------------------------------------------------------------------------------- 1 | time travel | 26 | * | | | | | BuddyPress possible! | 27 | * | 2 | members | Active | Community Members | Everything in a BuddyPress community | 28 | * | | | | | revolves around its members. | 29 | * +--------+---------+--------+------------------------------------------+--------------------------+ 30 | * 31 | * @since 1.6.0 32 | */ 33 | class Components extends BuddyPressCommand { 34 | 35 | /** 36 | * Object fields. 37 | * 38 | * @var array 39 | */ 40 | protected $obj_fields = [ 41 | 'number', 42 | 'id', 43 | 'status', 44 | 'title', 45 | 'description', 46 | ]; 47 | 48 | /** 49 | * Activate a component. 50 | * 51 | * ## OPTIONS 52 | * 53 | * 54 | * : Name of the component to activate. 55 | * 56 | * ## EXAMPLE 57 | * 58 | * # Activate a component. 59 | * $ wp bp component activate groups 60 | * Success: The Groups component has been activated. 61 | */ 62 | public function activate( $args ) { 63 | $component = $args[0]; 64 | 65 | if ( ! $this->component_exists( $component ) ) { 66 | WP_CLI::error( sprintf( '%s is not a valid component.', ucfirst( $component ) ) ); 67 | } 68 | 69 | if ( bp_is_active( $component ) ) { 70 | WP_CLI::error( sprintf( 'The %s component is already active.', ucfirst( $component ) ) ); 71 | } 72 | 73 | $active_components =& buddypress()->active_components; 74 | 75 | // Set for the rest of the page load. 76 | $active_components[ $component ] = 1; 77 | 78 | // Save in the db. 79 | bp_update_option( 'bp-active-components', $active_components ); 80 | 81 | // Ensure that dbDelta() is defined. 82 | if ( ! function_exists( 'dbDelta' ) ) { 83 | require_once ABSPATH . 'wp-admin/includes/upgrade.php'; 84 | } 85 | 86 | // Run the setup, in case tables have to be created. 87 | require_once buddypress()->plugin_dir . 'bp-core/admin/bp-core-admin-schema.php'; 88 | bp_core_install( $active_components ); 89 | bp_core_add_page_mappings( $active_components ); 90 | 91 | WP_CLI::success( sprintf( 'The %s component has been activated.', ucfirst( $component ) ) ); 92 | } 93 | 94 | /** 95 | * Deactivate a component. 96 | * 97 | * ## OPTIONS 98 | * 99 | * 100 | * : Name of the component to deactivate. 101 | * 102 | * ## EXAMPLE 103 | * 104 | * # Deactivate a component. 105 | * $ wp bp component deactivate groups 106 | * Success: The Groups component has been deactivated. 107 | */ 108 | public function deactivate( $args ) { 109 | $component = $args[0]; 110 | 111 | if ( ! $this->component_exists( $component ) ) { 112 | WP_CLI::error( sprintf( '%s is not a valid component.', ucfirst( $component ) ) ); 113 | } 114 | 115 | if ( ! bp_is_active( $component ) ) { 116 | WP_CLI::error( sprintf( 'The %s component is not active.', ucfirst( $component ) ) ); 117 | } 118 | 119 | if ( array_key_exists( $component, bp_core_get_components( 'required' ) ) ) { 120 | WP_CLI::error( 'You cannot deactivate a required component.' ); 121 | } 122 | 123 | $active_components =& buddypress()->active_components; 124 | 125 | // Set for the rest of the page load. 126 | unset( $active_components[ $component ] ); 127 | 128 | // Save in the db. 129 | bp_update_option( 'bp-active-components', $active_components ); 130 | 131 | WP_CLI::success( sprintf( 'The %s component has been deactivated.', ucfirst( $component ) ) ); 132 | } 133 | 134 | /** 135 | * Get a list of components. 136 | * 137 | * ## OPTIONS 138 | * 139 | * [--type=] 140 | * : Type of the component (all, optional, retired, required). 141 | * --- 142 | * default: all 143 | * options: 144 | * - all 145 | * - optional 146 | * - retired 147 | * - required 148 | * --- 149 | * 150 | * [--status=] 151 | * : Status of the component (all, active, inactive). 152 | * --- 153 | * default: all 154 | * options: 155 | * - all 156 | * - active 157 | * - inactive 158 | * --- 159 | * 160 | * [--fields=] 161 | * : Fields to display (id, title, description). 162 | * 163 | * [--format=] 164 | * : Render output in a particular format. 165 | * --- 166 | * default: table 167 | * options: 168 | * - table 169 | * - csv 170 | * - ids 171 | * - json 172 | * - count 173 | * - yaml 174 | * --- 175 | * 176 | * ## EXAMPLES 177 | * 178 | * # List components and get the count. 179 | * $ wp bp component list --format=count 180 | * 10 181 | * 182 | * # List components and get the ids. 183 | * $ wp bp component list --format=ids 184 | * core members xprofile settings friends messages activity notifications groups 185 | * 186 | * # List components. 187 | * $ wp bp component list 188 | * +--------+---------------+--------+--------------------+---------------------------------------------------------------------------------+ 189 | * | number | id | status | title | description | 190 | * +--------+---------------+--------+--------------------+---------------------------------------------------------------------------------+ 191 | * | 1 | core | active | BuddyPress Core | It‘s what makes time travel BuddyPress possible! | 192 | * | 2 | members | active | Community Members | Everything in a BuddyPress community revolves around its members. | 193 | * | 3 | xprofile | active | Extended Profiles | Customize your community with fully editable profile fields that allow your use | 194 | * | | | | | rs to describe themselves. | 195 | * | 4 | settings | active | Account Settings | Allow your users to modify their account and notification settings directly fro | 196 | * | | | | | m within their profiles. | 197 | * | 5 | friends | active | Friend Connections | Let your users make connections so they can track the activity of others and fo | 198 | * | | | | | cus on the people they care about the most. | 199 | * | 6 | messages | active | Private Messaging | Allow your users to talk to each other directly and in private. Not just limite | 200 | * | | | | | d to one-on-one discussions, messages can be sent between any number of members | 201 | * | | | | | . | 202 | * | 7 | activity | active | Activity Streams | Global, personal, and group activity streams with threaded commenting, direct p | 203 | * | | | | | osting, favoriting, and @mentions, all with full RSS feed and email notificatio | 204 | * | | | | | n support. | 205 | * | 8 | notifications | active | Notifications | Notify members of relevant activity with a toolbar bubble and/or via email, and | 206 | * | | | | | allow them to customize their notification settings. | 207 | * | 9 | groups | active | User Groups | Groups allow your users to organize themselves into specific public, private or | 208 | * | | | | | hidden sections with separate activity streams and member listings. | 209 | * | 10 | blogs | active | Site Tracking | Record activity for new sites, posts, and comments across your network. | 210 | * +--------+---------------+--------+--------------------+---------------------------------------------------------------------------------+ 211 | * 212 | * @subcommand list 213 | */ 214 | public function list_( $args, $assoc_args ) { 215 | $formatter = $this->get_formatter( $assoc_args ); 216 | 217 | // Get type. 218 | $type = $assoc_args['type']; 219 | 220 | // Get components. 221 | $components = (array) bp_core_get_components( $type ); 222 | 223 | // Active components. 224 | $active_components = apply_filters( 'bp_active_components', bp_get_option( 'bp-active-components', [] ) ); 225 | 226 | // Core component is always active. 227 | if ( 'optional' !== $type && isset( $components['core'] ) ) { 228 | if ( ! isset( $active_components['core'] ) ) { 229 | $active_components = array_merge( $active_components, [ 'core' => $components['core'] ] ); 230 | } 231 | } 232 | 233 | // Inactive components. 234 | $inactive_components = array_diff( array_keys( $components ), array_keys( $active_components ) ); 235 | 236 | $current_components = []; 237 | switch ( $assoc_args['status'] ) { 238 | case 'all': 239 | $index = 0; 240 | foreach ( $components as $component_key => $component ) { 241 | 242 | // Skip if the component is not available. 243 | if ( ! isset( $components[ $component_key ] ) ) { 244 | continue; 245 | } 246 | 247 | ++$index; 248 | $current_components[] = [ 249 | 'number' => $index, 250 | 'id' => $component_key, 251 | 'status' => $this->verify_component_status( $component_key ), 252 | 'title' => esc_html( $component['title'] ), 253 | 'description' => html_entity_decode( $component['description'], ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 ), 254 | ]; 255 | } 256 | break; 257 | 258 | case 'active': 259 | $index = 0; 260 | foreach ( array_keys( $active_components ) as $component_key ) { 261 | 262 | // Skip if the component is not available. 263 | if ( ! isset( $components[ $component_key ] ) ) { 264 | continue; 265 | } 266 | 267 | ++$index; 268 | $current_components[] = [ 269 | 'number' => $index, 270 | 'id' => $component_key, 271 | 'status' => $this->verify_component_status( $component_key ), 272 | 'title' => esc_html( $components[ $component_key ]['title'] ), 273 | 'description' => html_entity_decode( $components[ $component_key ]['description'], ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 ), 274 | ]; 275 | } 276 | break; 277 | 278 | case 'inactive': 279 | $index = 0; 280 | foreach ( $inactive_components as $component_key ) { 281 | 282 | // Skip if the component is not available. 283 | if ( ! isset( $components[ $component_key ] ) ) { 284 | continue; 285 | } 286 | 287 | ++$index; 288 | $current_components[] = [ 289 | 'number' => $index, 290 | 'id' => $component_key, 291 | 'status' => $this->verify_component_status( $component_key ), 292 | 'title' => esc_html( $components[ $component_key ]['title'] ), 293 | 'description' => html_entity_decode( $components[ $component_key ]['description'], ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 ), 294 | ]; 295 | } 296 | break; 297 | } 298 | 299 | // Bail early. 300 | if ( empty( $current_components ) ) { 301 | WP_CLI::error( 'There is no component available.' ); 302 | } 303 | 304 | $formatter->display_items( 'ids' === $formatter->format ? wp_list_pluck( $current_components, 'id' ) : $current_components ); 305 | } 306 | 307 | /** 308 | * Does the component exist? 309 | * 310 | * @param string $component_key Component key. 311 | * @return bool 312 | */ 313 | protected function component_exists( $component_key ) { 314 | return in_array( 315 | $component_key, 316 | array_keys( bp_core_get_components() ), 317 | true 318 | ); 319 | } 320 | 321 | /** 322 | * Verify Component Status. 323 | * 324 | * @since 1.7.0 325 | * 326 | * @param string $component_key Component key. 327 | * @return string 328 | */ 329 | protected function verify_component_status( $component_key ) { 330 | $active = 'active'; 331 | 332 | if ( 'core' === $component_key ) { 333 | return $active; 334 | } 335 | 336 | return bp_is_active( $component_key ) ? $active : 'inactive'; 337 | } 338 | } 339 | -------------------------------------------------------------------------------- /src/email.php: -------------------------------------------------------------------------------- 1 | A new event was created" --plain-text-content="A new event was created" 14 | * Success: Email post created for type "new-event". 15 | * 16 | * # Create email post with content from given file 17 | * $ wp bp email create ./email-content.txt --type=new-event --type-description="Send an email when a new event is created" --subject="[{{{site.name}}}] A new event was created" --plain-text-content="A new event was created" 18 | * Success: Email post created for type "new-event". 19 | * 20 | * @since 1.6.0 21 | */ 22 | class Email extends BuddyPressCommand { 23 | 24 | /** 25 | * Create a new email post connected to an email type. 26 | * 27 | * ## OPTIONS 28 | * 29 | * --type= 30 | * : Email type for the email (should be unique identifier, sanitized like a post slug). 31 | * 32 | * --type-description= 33 | * : Email type description. 34 | * 35 | * --subject= 36 | * : Email subject line. Email tokens allowed. View https://codex.buddypress.org/emails/email-tokens/ for more info. 37 | * 38 | * [--content=] 39 | * : Email content. Email tokens allowed. View https://codex.buddypress.org/emails/email-tokens/ for more info. 40 | * 41 | * [--plain-text-content=] 42 | * : Plain-text email content. Email tokens allowed. View https://codex.buddypress.org/emails/email-tokens/ for more info. 43 | * 44 | * [] 45 | * : Read content from . If this value is present, the 46 | * `--content` argument will be ignored. 47 | * 48 | * Passing `-` as the filename will cause post content to 49 | * be read from STDIN. 50 | * 51 | * [--edit] 52 | * : Immediately open system's editor to write or edit email content. 53 | * 54 | * If content is read from a file, from STDIN, or from the `--content` 55 | * argument, that text will be loaded into the editor. 56 | * 57 | * ## EXAMPLES 58 | * 59 | * # Create email post 60 | * $ wp bp email create --type=new-event --type-description="Send an email when a new event is created" --subject="[{{{site.name}}}] A new event was created" --content="A new event was created" --plain-text-content="A new event was created" 61 | * Success: Email post created for type "new-event". 62 | * 63 | * # Create email post with content from given file 64 | * $ wp bp email create ./email-content.txt --type=new-event --type-description="Send an email when a new event is created" --subject="[{{{site.name}}}] A new event was created" --plain-text-content="A new event was created" 65 | * Success: Email post created for type "new-event". 66 | * 67 | * @alias add 68 | */ 69 | public function create( $args, $assoc_args ) { 70 | $switched = false; 71 | 72 | if ( false === bp_is_root_blog() ) { 73 | $switched = true; 74 | switch_to_blog( bp_get_root_blog_id() ); 75 | } 76 | 77 | $term = term_exists( $assoc_args['type'], bp_get_email_tax_type() ); 78 | 79 | // Term already exists, so don't do anything. 80 | if ( 0 !== $term && null !== $term ) { 81 | if ( true === $switched ) { 82 | restore_current_blog(); 83 | } 84 | 85 | WP_CLI::error( sprintf( 'Email type %s already exists.', $assoc_args['type'] ) ); 86 | } 87 | 88 | if ( ! empty( $args[0] ) && \method_exists( $this, 'read_from_file_or_stdin' ) ) { 89 | $assoc_args['content'] = $this->read_from_file_or_stdin( $args[0] ); 90 | } 91 | 92 | if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'edit' ) ) { 93 | $input = \WP_CLI\Utils\get_flag_value( $assoc_args, 'content', '' ); 94 | $output = $this->edit_email( $input, 'WP-CLI: New BP Email Content' ); 95 | 96 | $assoc_args['content'] = ( $output ) ? $output : $input; 97 | } 98 | 99 | $defaults = [ 100 | 'post_status' => 'publish', 101 | 'post_type' => bp_get_email_post_type(), 102 | ]; 103 | 104 | $email = [ 105 | 'post_title' => $assoc_args['subject'], 106 | 'post_content' => $assoc_args['content'], 107 | 'post_excerpt' => ! empty( $assoc_args['plain-text-content'] ) ? $assoc_args['plain-text-content'] : '', 108 | ]; 109 | 110 | $id = $assoc_args['type']; 111 | 112 | // Email post content. 113 | $post_id = wp_insert_post( bp_parse_args( $email, $defaults, 'install_email_' . $id ), true ); 114 | 115 | // Save the situation. 116 | if ( ! is_wp_error( $post_id ) ) { 117 | $tt_ids = wp_set_object_terms( $post_id, $id, bp_get_email_tax_type() ); 118 | 119 | // Situation description. 120 | if ( ! is_wp_error( $tt_ids ) && ! empty( $assoc_args['type-description'] ) ) { 121 | $term = get_term_by( 'term_taxonomy_id', (int) $tt_ids[0], bp_get_email_tax_type() ); 122 | 123 | wp_update_term( 124 | (int) $term->term_id, 125 | bp_get_email_tax_type(), 126 | [ 127 | 'description' => $assoc_args['type-description'], 128 | ] 129 | ); 130 | } 131 | 132 | if ( true === $switched ) { 133 | restore_current_blog(); 134 | } 135 | 136 | WP_CLI::success( sprintf( 'Email post created for type %s.', $assoc_args['type'] ) ); 137 | } else { 138 | if ( true === $switched ) { 139 | restore_current_blog(); 140 | } 141 | 142 | WP_CLI::error( "There was a problem creating the email post for type '{$assoc_args['type']}' - " . $post_id->get_error_message() ); 143 | } 144 | } 145 | 146 | /** 147 | * Get details for a post connected to an email type. 148 | * 149 | * ## OPTIONS 150 | * 151 | * 152 | * : The email type to fetch the post details for. 153 | * 154 | * [--field=] 155 | * : Instead of returning the whole post, returns the value of a single field. 156 | * 157 | * [--fields=] 158 | * : Limit the output to specific fields. 159 | * 160 | * [--format=] 161 | * : Render output in a particular format. 162 | * --- 163 | * default: table 164 | * options: 165 | * - table 166 | * - csv 167 | * - json 168 | * - yaml 169 | * --- 170 | * 171 | * ## EXAMPLE 172 | * 173 | * # Output the post ID for the 'activity-at-message' email type 174 | * $ wp bp email get-post activity-at-message --fields=ID 175 | * 176 | * @alias get-post 177 | * @alias see 178 | */ 179 | public function get_post( $args, $assoc_args ) { 180 | $email = bp_get_email( $args[0] ); 181 | 182 | if ( is_wp_error( $email ) ) { 183 | WP_CLI::error( sprintf( 'Email post for type %s does not exist.', $args[0] ) ); 184 | } 185 | 186 | $post_arr = get_object_vars( $email->get_post_object() ); 187 | unset( $post_arr['filter'] ); 188 | if ( empty( $assoc_args['fields'] ) ) { 189 | $assoc_args['fields'] = array_keys( $post_arr ); 190 | } 191 | 192 | $this->get_formatter( $assoc_args )->display_item( $email->get_post_object() ); 193 | } 194 | 195 | /** 196 | * Reinstall BuddyPress default emails. 197 | * 198 | * ## OPTIONS 199 | * 200 | * [--yes] 201 | * : Answer yes to the confirmation message. 202 | * 203 | * ## EXAMPLE 204 | * 205 | * # Reinstall BuddyPress default emails. 206 | * $ wp bp email reinstall --yes 207 | * Success: Emails have been successfully reinstalled. 208 | */ 209 | public function reinstall( $args, $assoc_args ) { 210 | WP_CLI::confirm( 'Are you sure you want to reinstall BuddyPress emails?', $assoc_args ); 211 | 212 | require_once buddypress()->plugin_dir . 'bp-core/admin/bp-core-admin-tools.php'; 213 | 214 | $result = bp_admin_reinstall_emails(); 215 | 216 | if ( 0 === $result[0] ) { 217 | WP_CLI::success( $result[1] ); 218 | } else { 219 | WP_CLI::error( $result[1] ); 220 | } 221 | } 222 | 223 | /** 224 | * Helper method to use the '--edit' flag. 225 | * 226 | * Copied from Post_Command::_edit(). 227 | * 228 | * @param string $content Post content. 229 | * @param string $title Post title. 230 | * @return mixed 231 | */ 232 | protected function edit_email( $content, $title ) { 233 | $content = apply_filters( 'the_editor_content', $content ); 234 | $output = \WP_CLI\Utils\launch_editor_for_input( $content, $title ); 235 | 236 | return ( is_string( $output ) ) ? 237 | apply_filters( 'content_save_pre', $output ) 238 | : $output; 239 | } 240 | } 241 | -------------------------------------------------------------------------------- /src/friends.php: -------------------------------------------------------------------------------- 1 | 52 | * : ID of the user who is sending the friendship request. Accepts either a user_login or a numeric ID. 53 | * 54 | * 55 | * : ID of the user whose friendship is being requested. Accepts either a user_login or a numeric ID. 56 | * 57 | * [--force-accept] 58 | * : Whether to force acceptance. 59 | * 60 | * [--silent] 61 | * : Whether to silent the message creation. 62 | * 63 | * [--porcelain] 64 | * : Return only the friendship id. 65 | * 66 | * ## EXAMPLES 67 | * 68 | * # Create a new friendship. 69 | * $ wp bp friend create user1 another_use 70 | * Success: Friendship successfully created. 71 | * 72 | * # Create a new friendship, forcing acceptance. 73 | * $ wp bp friend create user1 another_use --force-accept 74 | * Success: Friendship successfully created. 75 | * 76 | * @alias add 77 | */ 78 | public function create( $args, $assoc_args ) { 79 | $initiator = $this->get_user_id_from_identifier( $args[0] ); 80 | $friend = $this->get_user_id_from_identifier( $args[1] ); 81 | 82 | // Silent it before it errors. 83 | if ( WP_CLI\Utils\get_flag_value( $assoc_args, 'silent' ) ) { 84 | return; 85 | } 86 | 87 | // Check if users are already friends, and bail if they do. 88 | if ( friends_check_friendship( $initiator->ID, $friend->ID ) ) { 89 | WP_CLI::error( 'These users are already friends.' ); 90 | } 91 | 92 | $force = (bool) WP_CLI\Utils\get_flag_value( $assoc_args, 'force-accept' ); 93 | 94 | if ( ! friends_add_friend( $initiator->ID, $friend->ID, $force ) ) { 95 | WP_CLI::error( 'There was a problem while creating the friendship.' ); 96 | } 97 | 98 | if ( WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ) ) { 99 | WP_CLI::log( \BP_Friends_Friendship::get_friendship_id( $initiator->ID, $friend->ID ) ); 100 | } elseif ( $force ) { 101 | WP_CLI::success( 'Friendship successfully created.' ); 102 | } else { 103 | WP_CLI::success( 'Friendship successfully created but not accepted.' ); 104 | } 105 | } 106 | 107 | /** 108 | * Remove a friendship. 109 | * 110 | * ## OPTIONS 111 | * 112 | * 113 | * : ID of the friendship initiator. Accepts either a user_login or a numeric ID. 114 | * 115 | * 116 | * : ID of the friend user. Accepts either a user_login or a numeric ID. 117 | * 118 | * ## EXAMPLE 119 | * 120 | * # Remove a friendship. 121 | * $ wp bp friend remove user_1 user_2 122 | * Success: Friendship successfully removed. 123 | * 124 | * @alias remove 125 | * @alias trash 126 | */ 127 | public function delete( $args ) { 128 | $initiator = $this->get_user_id_from_identifier( $args[0] ); 129 | $friend = $this->get_user_id_from_identifier( $args[1] ); 130 | 131 | // Check if users are already friends, if not, bail. 132 | if ( ! friends_check_friendship( $initiator->ID, $friend->ID ) ) { 133 | WP_CLI::error( 'These users are not friends.' ); 134 | } 135 | 136 | if ( friends_remove_friend( $initiator->ID, $friend->ID ) ) { 137 | WP_CLI::success( 'Friendship successfully removed.' ); 138 | } else { 139 | WP_CLI::error( 'There was a problem while removing the friendship.' ); 140 | } 141 | } 142 | 143 | /** 144 | * Mark a friendship request as accepted. 145 | * 146 | * ## OPTIONS 147 | * 148 | * ... 149 | * : ID(s) of the friendship(s). 150 | * 151 | * ## EXAMPLES 152 | * 153 | * $ wp bp friend accept-invitation 2161 154 | * Success: Friendship successfully accepted. 155 | * 156 | * $ wp bp friend accept 2161 157 | * Success: Friendship successfully accepted. 158 | * 159 | * @alias accept-invitation 160 | */ 161 | public function accept( $args, $assoc_args ) { 162 | parent::_update( 163 | wp_parse_id_list( $args ), 164 | $assoc_args, 165 | function ( $friendship_id ) { 166 | if ( friends_accept_friendship( $friendship_id ) ) { 167 | return [ 'success', 'Friendship successfully accepted.' ]; 168 | } 169 | 170 | return [ 'error', 'There was a problem accepting the friendship.' ]; 171 | } 172 | ); 173 | } 174 | 175 | /** 176 | * Mark a friendship request as rejected. 177 | * 178 | * ## OPTIONS 179 | * 180 | * ... 181 | * : ID(s) of the friendship(s). 182 | * 183 | * ## EXAMPLES 184 | * 185 | * $ wp bp friend reject-invitation 2161 186 | * Success: Friendship successfully accepted. 187 | * 188 | * $ wp bp friend reject 2161 151 2121 189 | * Success: Friendship successfully accepted. 190 | * 191 | * @alias reject-invitation 192 | */ 193 | public function reject( $args, $assoc_args ) { 194 | parent::_update( 195 | wp_parse_id_list( $args ), 196 | $assoc_args, 197 | function ( $friendship_id ) { 198 | if ( friends_reject_friendship( $friendship_id ) ) { 199 | return [ 'success', 'Friendship successfully rejected.' ]; 200 | } 201 | 202 | return [ 'error', 'There was a problem rejecting the friendship.' ]; 203 | } 204 | ); 205 | } 206 | 207 | /** 208 | * Check whether two users are friends. 209 | * 210 | * ## OPTIONS 211 | * 212 | * 213 | * : ID of the first user. Accepts either a user_login or a numeric ID. 214 | * 215 | * 216 | * : ID of the other user. Accepts either a user_login or a numeric ID. 217 | * 218 | * ## EXAMPLES 219 | * 220 | * $ wp bp friend check 2161 65465 221 | * Success: Yes, they are friends. 222 | * 223 | * $ wp bp friend see 2121 65456 224 | * Success: Yes, they are friends. 225 | * 226 | * @alias see 227 | */ 228 | public function check( $args ) { 229 | $user = $this->get_user_id_from_identifier( $args[0] ); 230 | $friend = $this->get_user_id_from_identifier( $args[1] ); 231 | 232 | if ( friends_check_friendship( $user->ID, $friend->ID ) ) { 233 | WP_CLI::success( 'Yes, they are friends.' ); 234 | } else { 235 | WP_CLI::error( 'No, they are not friends.' ); 236 | } 237 | } 238 | 239 | /** 240 | * Get a list of user's friends. 241 | * 242 | * ## OPTIONS 243 | * 244 | * 245 | * : ID of the user. Accepts either a user_login or a numeric ID. 246 | * 247 | * [--fields=] 248 | * : Fields to display. 249 | * 250 | * [--count=] 251 | * : How many user's friends to list. 252 | * --- 253 | * default: 50 254 | * --- 255 | * 256 | * [--format=] 257 | * : Render output in a particular format. 258 | * --- 259 | * default: table 260 | * options: 261 | * - table 262 | * - ids 263 | * - count 264 | * - csv 265 | * - json 266 | * - yaml 267 | * --- 268 | * 269 | * ## EXAMPLES 270 | * 271 | * # List a user's friends and get the count. 272 | * $ wp bp friend list 65465 --format=count 273 | * 100 274 | * 275 | * # List a user's friends and get the IDs. 276 | * $ wp bp friend list 2422 --format=ids 277 | * 70 71 72 73 74 278 | * 279 | * @subcommand list 280 | */ 281 | public function list_( $args, $assoc_args ) { 282 | $formatter = $this->get_formatter( $assoc_args ); 283 | $user = $this->get_user_id_from_identifier( $args[0] ); 284 | $friends = \BP_Friends_Friendship::get_friendships( 285 | $user->ID, 286 | [ 287 | 'page' => 1, 288 | 'per_page' => $assoc_args['count'], 289 | ] 290 | ); 291 | 292 | if ( empty( $friends ) ) { 293 | WP_CLI::error( 'This member has no friends.' ); 294 | } 295 | 296 | $formatter->display_items( 'ids' === $formatter->format ? wp_list_pluck( $friends, 'friend_user_id' ) : $friends ); 297 | } 298 | 299 | /** 300 | * Generate random friendships. 301 | * 302 | * ## OPTIONS 303 | * 304 | * [--initiator=] 305 | * : ID of the first user. Accepts either a user_login or a numeric ID. 306 | * 307 | * [--friend=] 308 | * : ID of the second user. Accepts either a user_login or a numeric ID. 309 | * 310 | * [--count=] 311 | * : How many friendships to generate. 312 | * --- 313 | * default: 100 314 | * --- 315 | * 316 | * [--format=] 317 | * : Render output in a particular format. 318 | * --- 319 | * default: progress 320 | * options: 321 | * - progress 322 | * - ids 323 | * --- 324 | * 325 | * ## EXAMPLES 326 | * 327 | * # Generate 50 random friendships. 328 | * $ wp bp friend generate --count=50 329 | * Generating friendships 100% [======================] 0:00 / 0:00 330 | * 331 | * # Generate 50 friendships with a specific user. 332 | * $ wp bp friend generate --initiator=121 --count=50 333 | * Generating friendships 100% [======================] 0:00 / 0:00 334 | * 335 | * # Generate 5 random friendships and output only the IDs. 336 | * $ wp bp friend generate --count=5 --format=ids 337 | * 70 71 72 73 74 338 | */ 339 | public function generate( $args, $assoc_args ) { 340 | $member_id = null; 341 | $friend_id = null; 342 | 343 | if ( isset( $assoc_args['initiator'] ) ) { 344 | $user = $this->get_user_id_from_identifier( $assoc_args['initiator'] ); 345 | $member_id = $user->ID; 346 | } 347 | 348 | if ( isset( $assoc_args['friend'] ) ) { 349 | $user_2 = $this->get_user_id_from_identifier( $assoc_args['friend'] ); 350 | $friend_id = $user_2->ID; 351 | } 352 | 353 | $this->generate_callback( 354 | 'Generating friendships', 355 | $assoc_args, 356 | function ( $assoc_args, $format ) use ( $member_id, $friend_id ) { 357 | if ( ! $member_id ) { 358 | $member_id = $this->get_random_user_id(); 359 | } 360 | 361 | if ( ! $friend_id ) { 362 | $friend_id = $this->get_random_user_id(); 363 | } 364 | 365 | $params = [ 'force-accept' => true ]; 366 | 367 | if ( 'ids' === $format ) { 368 | $params['porcelain'] = true; 369 | } else { 370 | $params['silent'] = true; 371 | } 372 | 373 | return $this->create( [ $member_id, $friend_id ], $params ); 374 | } 375 | ); 376 | } 377 | } 378 | -------------------------------------------------------------------------------- /src/group-fetcher.php: -------------------------------------------------------------------------------- 1 | $arg ] 33 | ); 34 | 35 | if ( empty( $group->id ) ) { 36 | return false; 37 | } 38 | 39 | return $group; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/group-invite.php: -------------------------------------------------------------------------------- 1 | 44 | * : Identifier for the group. Accepts either a slug or a numeric ID. 45 | * 46 | * --user-id= 47 | * : Identifier for the user. Accepts either a user_login or a numeric ID. 48 | * 49 | * --inviter-id= 50 | * : Identifier for the inviter. Accepts either a user_login or a numeric ID. 51 | * 52 | * [--message=] 53 | * : Message to send with the invitation. 54 | * 55 | * [--porcelain] 56 | * : Return only the invitation id. 57 | * 58 | * [--silent] 59 | * : Whether to silent the invite creation. 60 | * 61 | * ## EXAMPLES 62 | * 63 | * # Invite a member to a group. 64 | * $ wp bp group invite add --group-id=40 --user-id=10 --inviter-id=1331 65 | * Success: Member invited to the group. 66 | * 67 | * # Invite a member to a group. 68 | * $ wp bp group invite create --group-id=40 --user-id=user_slug --inviter-id=804 69 | * Success: Member invited to the group. 70 | * 71 | * @alias add 72 | */ 73 | public function create( $args, $assoc_args ) { 74 | 75 | // Bail early. 76 | if ( $assoc_args['user-id'] === $assoc_args['inviter-id'] ) { 77 | return; 78 | } 79 | 80 | $message = isset( $assoc_args['message'] ) ? $assoc_args['message'] : ''; 81 | $group_id = $this->get_group_id_from_identifier( $assoc_args['group-id'] ); 82 | $user = $this->get_user_id_from_identifier( $assoc_args['user-id'] ); 83 | $inviter = $this->get_user_id_from_identifier( $assoc_args['inviter-id'] ); 84 | $invite_id = groups_invite_user( 85 | [ 86 | 'user_id' => $user->ID, 87 | 'group_id' => $group_id, 88 | 'inviter_id' => $inviter->ID, 89 | 'content' => $message, 90 | ] 91 | ); 92 | 93 | if ( WP_CLI\Utils\get_flag_value( $assoc_args, 'silent' ) ) { 94 | return; 95 | } 96 | 97 | if ( ! $invite_id ) { 98 | WP_CLI::error( 'Could not invite the member.' ); 99 | } 100 | 101 | if ( WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ) ) { 102 | WP_CLI::log( $invite_id ); 103 | } else { 104 | WP_CLI::success( 'Member invited to the group.' ); 105 | } 106 | } 107 | 108 | /** 109 | * Uninvite a user from a group. 110 | * 111 | * ## OPTIONS 112 | * 113 | * --group-id= 114 | * : Identifier for the group. Accepts either a slug or a numeric ID. 115 | * 116 | * --user-id= 117 | * : Identifier for the user. Accepts either a user_login or a numeric ID. 118 | * 119 | * ## EXAMPLES 120 | * 121 | * # Uninvite a user from a group. 122 | * $ wp bp group invite uninvite --group-id=3 --user-id=10 123 | * Success: User uninvited from the group. 124 | * 125 | * # Uninvite a user from a group. 126 | * $ wp bp group invite uninvite --group-id=foo --user-id=admin 127 | * Success: User uninvited from the group. 128 | */ 129 | public function uninvite( $args, $assoc_args ) { 130 | $group_id = $this->get_group_id_from_identifier( $assoc_args['group-id'] ); 131 | $user = $this->get_user_id_from_identifier( $assoc_args['user-id'] ); 132 | 133 | if ( groups_uninvite_user( $user->ID, $group_id ) ) { 134 | WP_CLI::success( 'User uninvited from the group.' ); 135 | } else { 136 | WP_CLI::error( 'Could not remove the user.' ); 137 | } 138 | } 139 | 140 | /** 141 | * Get a list of invitations from a group. 142 | * 143 | * ## OPTIONS 144 | * 145 | * --group-id= 146 | * : Identifier for the group. Accepts either a slug or a numeric ID. 147 | * 148 | * --user-id= 149 | * : Identifier for the user. Accepts either a user_login or a numeric ID. 150 | * 151 | * [--count=] 152 | * : How many invitations to list. 153 | * --- 154 | * default: 50 155 | * --- 156 | * 157 | * [--format=] 158 | * : Render output in a particular format. 159 | * --- 160 | * default: table 161 | * options: 162 | * - table 163 | * - csv 164 | * - ids 165 | * - json 166 | * - count 167 | * - yaml 168 | * --- 169 | * 170 | * ## EXAMPLE 171 | * 172 | * # Get a list of invitations from a group. 173 | * $ wp bp group invite list --group-id=56 --user-id=30 174 | * 175 | * @subcommand list 176 | */ 177 | public function list_( $args, $assoc_args ) { 178 | $group_id = $this->get_group_id_from_identifier( $assoc_args['group-id'] ); 179 | $user = $this->get_user_id_from_identifier( $assoc_args['user-id'] ); 180 | $user_id = $user->ID; 181 | 182 | if ( $group_id ) { 183 | $invite_query = new \BP_Group_Member_Query( [ 184 | 'is_confirmed' => false, 185 | 'group_id' => $group_id, 186 | 'per_page' => $assoc_args['count'], 187 | ] ); 188 | 189 | $invites = $invite_query->results; 190 | 191 | // Manually filter out user ID - this is not supported by the API. 192 | if ( $user_id ) { 193 | $user_invites = []; 194 | 195 | foreach ( $invites as $invite ) { 196 | if ( $user_id === $invite->user_id ) { 197 | $user_invites[] = $invite; 198 | } 199 | } 200 | 201 | $invites = $user_invites; 202 | } 203 | 204 | if ( empty( $invites ) ) { 205 | WP_CLI::error( 'No invitations found.' ); 206 | } 207 | 208 | if ( empty( $assoc_args['fields'] ) ) { 209 | $fields = []; 210 | 211 | if ( ! $user_id ) { 212 | $fields[] = 'user_id'; 213 | } 214 | 215 | $fields[] = 'inviter_id'; 216 | $fields[] = 'invite_sent'; 217 | $fields[] = 'date_modified'; 218 | 219 | $assoc_args['fields'] = $fields; 220 | } 221 | } else { 222 | $invite_query = groups_get_invites_for_user( $user_id, $assoc_args['count'], 1 ); 223 | $invites = $invite_query['groups']; 224 | 225 | if ( empty( $assoc_args['fields'] ) ) { 226 | $assoc_args['fields'] = [ 'id', 'name', 'slug' ]; 227 | } 228 | } 229 | 230 | $formatter = $this->get_formatter( $assoc_args ); 231 | $formatter->display_items( 'ids' === $formatter->format ? wp_list_pluck( $invites, 'id' ) : $invites ); 232 | } 233 | 234 | /** 235 | * Generate group invitations. 236 | * 237 | * ## OPTIONS 238 | * 239 | * [--count=] 240 | * : How many group invitations to generate. 241 | * --- 242 | * default: 100 243 | * --- 244 | * 245 | * [--user-id=] 246 | * : ID of the first user. Accepts either a user_login or a numeric ID. 247 | * 248 | * [--inviter-id=] 249 | * : ID for the inviter. Accepts either a user_login or a numeric ID. 250 | * 251 | * [--format=] 252 | * : Render output in a particular format. 253 | * --- 254 | * default: progress 255 | * options: 256 | * - progress 257 | * - ids 258 | * --- 259 | * 260 | * ## EXAMPLES 261 | * 262 | * # Generate random group invitations. 263 | * $ wp bp group invite generate --count=50 264 | * Generating group invitations 100% [======================] 0:00 / 0:00 265 | * 266 | * # Generate random group invitations with a specific user. 267 | * $ wp bp group invite generate --inviter-id=121 --count=5 268 | * Generating group invitations 100% [======================] 0:00 / 0:00 269 | * 270 | * # Generate 5 random group invitations and output only the IDs. 271 | * $ wp bp group invite generate --count=5 --format=ids 272 | * 70 71 72 73 74 273 | */ 274 | public function generate( $args, $assoc_args ) { 275 | $user_id = null; 276 | $inviter_id = null; 277 | 278 | if ( isset( $assoc_args['user-id'] ) ) { 279 | $user = $this->get_user_id_from_identifier( $assoc_args['user-id'] ); 280 | $user_id = $user->ID; 281 | } 282 | 283 | if ( isset( $assoc_args['inviter-id'] ) ) { 284 | $user_2 = $this->get_user_id_from_identifier( $assoc_args['inviter-id'] ); 285 | $inviter_id = $user_2->ID; 286 | } 287 | 288 | $this->generate_callback( 289 | 'Generating group invitations', 290 | $assoc_args, 291 | function ( $assoc_args, $format ) use ( $user_id, $inviter_id ) { 292 | $random_group = \BP_Groups_Group::get_random( 1, 1 ); 293 | 294 | if ( ! $user_id ) { 295 | $user_id = $this->get_random_user_id(); 296 | } 297 | 298 | if ( ! $inviter_id ) { 299 | $inviter_id = $this->get_random_user_id(); 300 | } 301 | 302 | $params = [ 303 | 'user-id' => $user_id, 304 | 'group-id' => $random_group['groups'][0]->slug, 305 | 'inviter-id' => $inviter_id, 306 | ]; 307 | 308 | if ( 'ids' === $format ) { 309 | $params['porcelain'] = true; 310 | } else { 311 | $params['silent'] = true; 312 | } 313 | 314 | return $this->create( [], $params ); 315 | } 316 | ); 317 | } 318 | 319 | /** 320 | * Accept a group invitation. 321 | * 322 | * ## OPTIONS 323 | * 324 | * --group-id= 325 | * : Identifier for the group. Accepts either a slug or a numeric ID. 326 | * 327 | * --user-id= 328 | * : Identifier for the user. Accepts either a user_login or a numeric ID. 329 | * 330 | * ## EXAMPLES 331 | * 332 | * # Accept a group invitation. 333 | * $ wp bp group invite accept --group-id=3 --user-id=10 334 | * Success: User is now a "member" of the group. 335 | * 336 | * # Accept a group invitation. 337 | * $ wp bp group invite accept --group-id=foo --user-id=admin 338 | * Success: User is now a "member" of the group. 339 | */ 340 | public function accept( $args, $assoc_args ) { 341 | $group_id = $this->get_group_id_from_identifier( $assoc_args['group-id'] ); 342 | $user = $this->get_user_id_from_identifier( $assoc_args['user-id'] ); 343 | 344 | if ( groups_accept_invite( $user->ID, $group_id ) ) { 345 | WP_CLI::success( 'User is now a "member" of the group.' ); 346 | } else { 347 | WP_CLI::error( 'Could not accept user invitation to the group.' ); 348 | } 349 | } 350 | 351 | /** 352 | * Reject a group invitation. 353 | * 354 | * ## OPTIONS 355 | * 356 | * --group-id= 357 | * : Identifier for the group. Accepts either a slug or a numeric ID. 358 | * 359 | * --user-id= 360 | * : Identifier for the user. Accepts either a user_login or a numeric ID. 361 | * 362 | * ## EXAMPLES 363 | * 364 | * # Reject a group invitation. 365 | * $ wp bp group invite reject --group-id=3 --user-id=10 366 | * Success: Member invitation rejected. 367 | * 368 | * # Reject a group invitation. 369 | * $ wp bp group invite reject --group-id=foo --user-id=admin 370 | * Success: Member invitation rejected. 371 | */ 372 | public function reject( $args, $assoc_args ) { 373 | $group_id = $this->get_group_id_from_identifier( $assoc_args['group-id'] ); 374 | $user = $this->get_user_id_from_identifier( $assoc_args['user-id'] ); 375 | 376 | if ( groups_reject_invite( $user->ID, $group_id ) ) { 377 | WP_CLI::success( 'Member invitation rejected.' ); 378 | } else { 379 | WP_CLI::error( 'Could not reject member invitation.' ); 380 | } 381 | } 382 | 383 | /** 384 | * Delete a group invitation. 385 | * 386 | * ## OPTIONS 387 | * 388 | * --group-id= 389 | * : Identifier for the group. Accepts either a slug or a numeric ID. 390 | * 391 | * --user-id= 392 | * : Identifier for the user. Accepts either a user_login or a numeric ID. 393 | * 394 | * [--yes] 395 | * : Answer yes to the confirmation message. 396 | * 397 | * ## EXAMPLES 398 | * 399 | * # Delete a group invitation. 400 | * $ wp bp group invite delete --group-id=3 --user-id=10 --yes 401 | * Success: Group invitation deleted. 402 | * 403 | * # Delete a group invitation. 404 | * $ wp bp group invite delete --group-id=foo --user-id=admin --yes 405 | * Success: Group invitation deleted. 406 | * 407 | * @alias delete 408 | * @alias trash 409 | */ 410 | public function delete( $args, $assoc_args ) { 411 | WP_CLI::confirm( 'Are you sure you want to delete this group invitation?', $assoc_args ); 412 | 413 | $group_id = $this->get_group_id_from_identifier( $assoc_args['group-id'] ); 414 | $user = $this->get_user_id_from_identifier( $assoc_args['user-id'] ); 415 | 416 | if ( groups_delete_invite( $user->ID, $group_id ) ) { 417 | WP_CLI::success( 'Group invitation deleted.' ); 418 | } else { 419 | WP_CLI::error( 'Could not delete group invitation.' ); 420 | } 421 | } 422 | } 423 | -------------------------------------------------------------------------------- /src/group-member.php: -------------------------------------------------------------------------------- 1 | 44 | * : Identifier for the group. Accepts either a slug or a numeric ID. 45 | * 46 | * --user-id= 47 | * : Identifier for the user. Accepts either a user_login or a numeric ID. 48 | * 49 | * [--role=] 50 | * : Group member role (member, mod, admin). 51 | * --- 52 | * default: member 53 | * options: 54 | * - member 55 | * - mod 56 | * - admin 57 | * --- 58 | * 59 | * ## EXAMPLES 60 | * 61 | * # Add a user to a group as a member. 62 | * $ wp bp group member add --group-id=3 --user-id=10 63 | * Success: Added user #3 to group #3 as member. 64 | * 65 | * # Add a user to a group as a moderator. 66 | * $ wp bp group member create --group-id=bar --user-id=20 --role=mod 67 | * Success: Added user #20 to group #45 as mod. 68 | * 69 | * @alias add 70 | */ 71 | public function create( $args, $assoc_args ) { 72 | $group_id = $this->get_group_id_from_identifier( $assoc_args['group-id'] ); 73 | $user = $this->get_user_id_from_identifier( $assoc_args['user-id'] ); 74 | $role = $assoc_args['role']; 75 | $joined = groups_join_group( $group_id, $user->ID ); 76 | 77 | if ( ! $joined ) { 78 | WP_CLI::error( 'Could not add user to the group.' ); 79 | } 80 | 81 | if ( 'member' !== $role ) { 82 | $group_member = new \BP_Groups_Member( $user->ID, $group_id ); 83 | $group_member->promote( $role ); 84 | } 85 | 86 | WP_CLI::success( 87 | sprintf( 88 | 'Added user #%d to group #%d as %s.', 89 | $user->ID, 90 | $group_id, 91 | $role 92 | ) 93 | ); 94 | } 95 | 96 | /** 97 | * Remove a member from a group. 98 | * 99 | * ## OPTIONS 100 | * 101 | * --group-id= 102 | * : Identifier for the group. Accepts either a slug or a numeric ID. 103 | * 104 | * --user-id= 105 | * : Identifier for the user. Accepts either a user_login or a numeric ID. 106 | * 107 | * ## EXAMPLES 108 | * 109 | * # Remove a member from a group. 110 | * $ wp bp group member remove --group-id=3 --user-id=10 111 | * Success: Member #10 removed from the group #3. 112 | * 113 | * # Remove a member from a group. 114 | * $ wp bp group member delete --group-id=foo --user-id=admin 115 | * Success: Member #545 removed from the group #12. 116 | * 117 | * @alias remove 118 | * @alias trash 119 | */ 120 | public function delete( $args, $assoc_args ) { 121 | $group_id = $this->get_group_id_from_identifier( $assoc_args['group-id'] ); 122 | $user = $this->get_user_id_from_identifier( $assoc_args['user-id'] ); 123 | $group_member = new \BP_Groups_Member( $user->ID, $group_id ); 124 | 125 | // Check if the user is the only admin of the group. 126 | if ( (bool) $group_member->is_admin ) { 127 | $group_admins = groups_get_group_admins( $group_id ); 128 | if ( 1 === count( $group_admins ) ) { 129 | WP_CLI::error( 'Cannot remove the only admin of the group.' ); 130 | } 131 | } 132 | 133 | // True on success. 134 | if ( $group_member->remove() ) { 135 | WP_CLI::success( sprintf( 'Member #%d removed from the group #%d.', $user->ID, $group_id ) ); 136 | } else { 137 | WP_CLI::error( 'Could not remove member from the group.' ); 138 | } 139 | } 140 | 141 | /** 142 | * Get a list of group memberships. 143 | * 144 | * This command can be used to fetch a list of a user's groups (using the --user-id 145 | * parameter) or a group's members (using the --group-id flag). 146 | * 147 | * ## OPTIONS 148 | * 149 | * 150 | * : Identifier for the group. Can be a numeric ID or the group slug. 151 | * 152 | * [--fields=] 153 | * : Limit the output to specific signup fields. 154 | * 155 | * [--=] 156 | * : One or more parameters to pass. See groups_get_group_members() 157 | * 158 | * [--role=] 159 | * : Limit the output to members with a specific role. 160 | * --- 161 | * default: members 162 | * options: 163 | * - members 164 | * - mod 165 | * - admin 166 | * - banned 167 | * --- 168 | * 169 | * [--count=] 170 | * : How many members to list. 171 | * --- 172 | * default: 50 173 | * --- 174 | * 175 | * [--format=] 176 | * : Render output in a particular format. 177 | * --- 178 | * default: table 179 | * options: 180 | * - table 181 | * - csv 182 | * - ids 183 | * - json 184 | * - count 185 | * - yaml 186 | * --- 187 | * 188 | * ## AVAILABLE FIELDS 189 | * 190 | * These fields will be displayed by default for each group member: 191 | * 192 | * * id 193 | * * user_login 194 | * * fullname 195 | * * date_modified 196 | * * role 197 | * 198 | * ## EXAMPLE 199 | * 200 | * # Get a list of group members. 201 | * $ wp bp group member list 3 202 | * +---------+------------+----------+---------------------+-------+ 203 | * | id | user_login | fullname | date_modified | role | 204 | * +---------+------------+----------+---------------------+-------+ 205 | * | 1 | user | User | 2022-07-04 02:12:02 | admin | 206 | * +---------+------------+----------+---------------------+-------+ 207 | * 208 | * # Get a list of group members and get the count. 209 | * $ wp bp group member list 65465 --format=count 210 | * 100 211 | * 212 | * @subcommand list 213 | */ 214 | public function list_( $args, $assoc_args ) { 215 | $group_id = $this->get_group_id_from_identifier( $args[0] ); 216 | 217 | // Get our members. 218 | $members_query = groups_get_group_members( 219 | [ 220 | 'per_page' => $assoc_args['count'], 221 | 'group_id' => $group_id, 222 | 'exclude_admins_mods' => false, 223 | 'group_role' => [ $assoc_args['role'] ], 224 | ] 225 | ); 226 | 227 | $members = $members_query['members']; 228 | 229 | if ( empty( $members ) ) { 230 | WP_CLI::error( 'No group members found.' ); 231 | } 232 | 233 | // Make 'role' human-readable. 234 | foreach ( $members as &$member ) { 235 | $role = 'member'; 236 | if ( $member->is_mod ) { 237 | $role = 'mod'; 238 | } elseif ( $member->is_admin ) { 239 | $role = 'admin'; 240 | } 241 | 242 | $member->role = $role; 243 | } 244 | 245 | if ( empty( $assoc_args['fields'] ) ) { 246 | $assoc_args['fields'] = [ 247 | 'id', 248 | 'user_login', 249 | 'fullname', 250 | 'date_modified', 251 | 'role', 252 | ]; 253 | } 254 | 255 | $formatter = $this->get_formatter( $assoc_args ); 256 | $formatter->display_items( 'ids' === $formatter->format ? wp_list_pluck( $members, 'user_id' ) : $members ); 257 | } 258 | 259 | /** 260 | * Promote a member to a new status within a group. 261 | * 262 | * ## OPTIONS 263 | * 264 | * --group-id= 265 | * : Identifier for the group. Accepts either a slug or a numeric ID. 266 | * 267 | * --user-id= 268 | * : Identifier for the user. Accepts either a user_login or a numeric ID. 269 | * 270 | * --role= 271 | * : Group role to promote the member. 272 | * --- 273 | * options: 274 | * - mod 275 | * - admin 276 | * --- 277 | * 278 | * ## EXAMPLES 279 | * 280 | * # Promote a member to a new role. 281 | * $ wp bp group member promote --group-id=3 --user-id=10 --role=admin 282 | * Success: Member promoted to new role successfully. 283 | * 284 | * # Promote a member to a new role. 285 | * $ wp bp group member promote --group-id=foo --user-id=admin --role=mod 286 | * Success: Member promoted to new role successfully. 287 | */ 288 | public function promote( $args, $assoc_args ) { 289 | $group_id = $this->get_group_id_from_identifier( $assoc_args['group-id'] ); 290 | $user = $this->get_user_id_from_identifier( $assoc_args['user-id'] ); 291 | $group_member = new \BP_Groups_Member( $user->ID, $group_id ); 292 | 293 | if ( $group_member->promote( $assoc_args['role'] ) ) { 294 | WP_CLI::success( 'Member promoted to new role successfully.' ); 295 | } else { 296 | WP_CLI::error( 'Could not promote the member.' ); 297 | } 298 | } 299 | 300 | /** 301 | * Demote user to the 'member' status. 302 | * 303 | * ## OPTIONS 304 | * 305 | * --group-id= 306 | * : Identifier for the group. Accepts either a slug or a numeric ID. 307 | * 308 | * --user-id= 309 | * : Identifier for the user. Accepts either a user_login or a numeric ID. 310 | * 311 | * ## EXAMPLES 312 | * 313 | * # Demote a user to the "member" status using numeric IDs. 314 | * $ wp bp group member demote --group-id=3 --user-id=10 315 | * Success: User demoted to the "member" status. 316 | * 317 | * # Demote a user to the "member" status using slugs. 318 | * $ wp bp group member demote --group-id=foo --user-id=admin 319 | * Success: User demoted to the "member" status. 320 | * 321 | * # Demote a user not part of the group. 322 | * $ wp bp group member demote --group-id=foo --user-id=admin 323 | * Error: User is not a member of the group. 324 | */ 325 | public function demote( $args, $assoc_args ) { 326 | $group_id = $this->get_group_id_from_identifier( $assoc_args['group-id'] ); 327 | $user = $this->get_user_id_from_identifier( $assoc_args['user-id'] ); 328 | 329 | // Check if the user is a member of the group. 330 | if ( ! groups_is_user_member( $user->ID, $group_id ) ) { 331 | WP_CLI::error( 'User is not a member of the group.' ); 332 | } 333 | 334 | $group_member = new \BP_Groups_Member( $user->ID, $group_id ); 335 | 336 | // Check if the user is the only admin of the group. 337 | if ( (bool) $group_member->is_admin ) { 338 | $group_admins = groups_get_group_admins( $group_id ); 339 | if ( 1 === count( $group_admins ) ) { 340 | WP_CLI::error( 'Cannot demote the only admin of the group.' ); 341 | } 342 | } 343 | 344 | if ( $group_member->demote() ) { 345 | WP_CLI::success( 'User demoted to the "member" status.' ); 346 | } else { 347 | WP_CLI::error( 'Could not demote the member.' ); 348 | } 349 | } 350 | 351 | /** 352 | * Ban a member from a group. 353 | * 354 | * ## OPTIONS 355 | * 356 | * --group-id= 357 | * : Identifier for the group. Accepts either a slug or a numeric ID. 358 | * 359 | * --user-id= 360 | * : Identifier for the user. Accepts either a user_login or a numeric ID. 361 | * 362 | * ## EXAMPLES 363 | * 364 | * # Ban a member from a group. 365 | * $ wp bp group member ban --group-id=3 --user-id=10 366 | * Success: Member banned from the group. 367 | * 368 | * # Ban a member from a group. 369 | * $ wp bp group member ban --group-id=foo --user-id=admin 370 | * Success: Member banned from the group. 371 | */ 372 | public function ban( $args, $assoc_args ) { 373 | $group_id = $this->get_group_id_from_identifier( $assoc_args['group-id'] ); 374 | $user = $this->get_user_id_from_identifier( $assoc_args['user-id'] ); 375 | 376 | // Check if the user is a member of the group. 377 | if ( ! groups_is_user_member( $user->ID, $group_id ) ) { 378 | WP_CLI::error( 'User is not a member of the group.' ); 379 | } 380 | 381 | $group_member = new \BP_Groups_Member( $user->ID, $group_id ); 382 | 383 | if ( $group_member->ban() ) { 384 | WP_CLI::success( 'Member banned from the group.' ); 385 | } else { 386 | WP_CLI::error( 'Could not ban the member.' ); 387 | } 388 | } 389 | 390 | /** 391 | * Unban a member from a group. 392 | * 393 | * ## OPTIONS 394 | * 395 | * --group-id= 396 | * : Identifier for the group. Accepts either a slug or a numeric ID. 397 | * 398 | * --user-id= 399 | * : Identifier for the user. Accepts either a user_login or a numeric ID. 400 | * 401 | * ## EXAMPLES 402 | * 403 | * # Unban a member from a group. 404 | * $ wp bp group member unban --group-id=3 --user-id=10 405 | * Success: Member unbanned from the group. 406 | * 407 | * # Unban a member from a group. 408 | * $ wp bp group member unban --group-id=foo --user-id=admin 409 | * Success: Member unbanned from the group. 410 | */ 411 | public function unban( $args, $assoc_args ) { 412 | $group_id = $this->get_group_id_from_identifier( $assoc_args['group-id'] ); 413 | $user = $this->get_user_id_from_identifier( $assoc_args['user-id'] ); 414 | $member = new \BP_Groups_Member( $user->ID, $group_id ); 415 | 416 | if ( $member->unban() ) { 417 | WP_CLI::success( 'Member unbanned from the group.' ); 418 | } else { 419 | WP_CLI::error( 'Could not unban the member.' ); 420 | } 421 | } 422 | } 423 | -------------------------------------------------------------------------------- /src/group-meta.php: -------------------------------------------------------------------------------- 1 | get_check( $object_id ); 119 | 120 | return $group->id; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/member.php: -------------------------------------------------------------------------------- 1 | ] 29 | * : How many members to generate. 30 | * --- 31 | * default: 100 32 | * --- 33 | * 34 | * [--role=] 35 | * : The role of the generated users. Defaults to role from WP. 36 | * 37 | * [--format=] 38 | * : Render output in a particular format. 39 | * --- 40 | * default: progress 41 | * options: 42 | * - progress 43 | * - ids 44 | * --- 45 | * 46 | * ## EXAMPLES 47 | * 48 | * # Generate 50 members. 49 | * $ wp bp member generate --count=50 50 | * Generating users 100% [======================] 0:00 / 0:00 51 | * 52 | * # Add meta to every generated users. 53 | * $ wp user generate --format=ids --count=3 | xargs -d ' ' -I % wp user meta add % foo bar 54 | * Success: Added custom field. 55 | * Success: Added custom field. 56 | * Success: Added custom field. 57 | */ 58 | public function generate( $args, $assoc_args ) { 59 | add_action( 'user_register', [ __CLASS__, 'update_user_last_activity_random' ] ); 60 | 61 | $command_class = new \User_Command(); 62 | $command_class->generate( $args, $assoc_args ); 63 | 64 | remove_action( 'user_register', [ __CLASS__, 'update_user_last_activity_random' ] ); 65 | } 66 | 67 | /** 68 | * Update the last user activity with a random date. 69 | * 70 | * @since 1.0 71 | * 72 | * @param int $user_id User ID. 73 | */ 74 | public static function update_user_last_activity_random( $user_id ) { 75 | bp_update_user_last_activity( 76 | $user_id, 77 | gmdate( 'Y-m-d H:i:s', wp_rand( 0, time() ) ) 78 | ); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/scaffold.php: -------------------------------------------------------------------------------- 1 | 36 | * : The slug of the BuddyPress plugin. 37 | * 38 | * [--force] 39 | * : Whether to overwrite files. 40 | * 41 | * ## EXAMPLES 42 | * 43 | * # Scaffold BuddyPress specific tests. 44 | * $ wp bp scaffold plugin sample-test 45 | * Success: Created BuddyPress test files. 46 | * 47 | * # Scaffold BuddyPress specific tests. 48 | * $ wp bp scaffold tests another-sample-test 49 | * Success: Created BuddyPress test files. 50 | * 51 | * @subcommand tests 52 | */ 53 | public function plugin( $args, $assoc_args ) { 54 | $wp_filesystem = $this->init_wp_filesystem(); 55 | $target_dir = WP_PLUGIN_DIR . "/{$args[0]}"; 56 | 57 | if ( ! is_dir( $target_dir ) ) { 58 | WP_CLI::error( "Invalid plugin slug specified. No such target directory '{$target_dir}'." ); 59 | } 60 | 61 | $error_msg = $this->check_target_directory( $target_dir ); 62 | if ( ! empty( $error_msg ) ) { 63 | WP_CLI::error( "Invalid plugin slug specified. {$error_msg}" ); 64 | } 65 | 66 | $to_copy = [ 67 | 'install-bp-tests.sh' => "{$target_dir}/bin", 68 | 'bootstrap-buddypress.php' => "{$target_dir}/tests", 69 | ]; 70 | 71 | foreach ( $to_copy as $file => $dir ) { 72 | $file_name = "$dir/$file"; 73 | 74 | $prompt = WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ); 75 | 76 | // Prompt it. 77 | $should_write_file = $this->prompt_if_files_will_be_overwritten( $file_name, $prompt ); 78 | 79 | if ( false === $should_write_file ) { 80 | continue; 81 | } 82 | 83 | $files_written[] = $file_name; 84 | 85 | $wp_filesystem->copy( self::get_template_path( $file ), $file_name, true ); 86 | 87 | if ( 'install-bp-tests.sh' === $file ) { 88 | if ( ! $wp_filesystem->chmod( "$dir/$file", 0755 ) ) { 89 | WP_CLI::warning( "Couldn't mark 'install-bp-tests.sh' as executable." ); 90 | } 91 | } 92 | } 93 | 94 | $this->log_whether_files_written( 95 | $files_written, 96 | 'All BuddyPress test files were skipped.', 97 | 'Created BuddyPress test files.' 98 | ); 99 | } 100 | 101 | /** 102 | * Checks that the `$target_dir` is a child directory of the WP themes or plugins directory, depending on `$type`. 103 | * 104 | * @param string $type "theme" or "plugin" 105 | * @param string $target_dir The theme/plugin directory to check. 106 | * @return null|string Returns null on success, error message on error. 107 | */ 108 | public function check_target_directory( $target_dir ) { 109 | $parent_dir = dirname( self::canonicalize_path( str_replace( '\\', '/', $target_dir ) ) ); 110 | 111 | if ( str_replace( '\\', '/', WP_PLUGIN_DIR ) !== $parent_dir ) { 112 | return sprintf( 'The target directory \'%1$s\' is not in \'%2$s\'.', $target_dir, WP_PLUGIN_DIR ); 113 | } 114 | 115 | // Success. 116 | return null; 117 | } 118 | 119 | /** 120 | * Canonicalizes a path. 121 | * 122 | * @param string $path Path. 123 | * @return string 124 | */ 125 | public static function canonicalize_path( $path ) { 126 | if ( '' === $path || '/' === $path ) { 127 | return $path; 128 | } 129 | 130 | if ( '.' === substr( $path, -1 ) ) { 131 | $path .= '/'; 132 | } 133 | 134 | $output = []; 135 | 136 | foreach ( explode( '/', $path ) as $segment ) { 137 | if ( '..' === $segment ) { 138 | array_pop( $output ); 139 | } elseif ( '.' !== $segment ) { 140 | $output[] = $segment; 141 | } 142 | } 143 | 144 | return implode( '/', $output ); 145 | } 146 | 147 | /** 148 | * Gets the template path based on installation type. 149 | * 150 | * @return string Template path. 151 | */ 152 | public static function get_template_path( $template ) { 153 | $command_root = WP_CLI\Utils\phar_safe_path( dirname( __DIR__ ) ); 154 | $template_path = "{$command_root}/src/templates/{$template}"; 155 | 156 | if ( ! file_exists( $template_path ) ) { 157 | WP_CLI::error( "Couldn't find {$template}" ); 158 | } 159 | 160 | return $template_path; 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /src/signup.php: -------------------------------------------------------------------------------- 1 | plugin_dir . 'bp-core/admin/bp-core-admin-schema.php'; 52 | require_once buddypress()->plugin_dir . 'bp-core/bp-core-update.php'; 53 | 54 | bp_core_maybe_install_signups(); 55 | } 56 | 57 | /** 58 | * Add a signup. 59 | * 60 | * ## OPTIONS 61 | * 62 | * [--user-login=] 63 | * : User login for the signup. 64 | * 65 | * [--user-email=] 66 | * : User email for the signup. 67 | * 68 | * [--activation-key=] 69 | * : Activation key for the signup. If none is provided, a random one will be used. 70 | * 71 | * [--silent] 72 | * : Whether to silent the signup creation. 73 | * 74 | * [--porcelain] 75 | * : Output only the new signup id. 76 | * 77 | * ## EXAMPLES 78 | * 79 | * # Add a signup. 80 | * $ wp bp signup create --user-login=test_user --user-email=teste@site.com 81 | * Success: Successfully added new user signup (ID #345). 82 | * 83 | * @alias add 84 | */ 85 | public function create( $args, $assoc_args ) { 86 | $r = wp_parse_args( 87 | $assoc_args, 88 | [ 89 | 'user-login' => '', 90 | 'user-email' => '', 91 | 'activation-key' => wp_generate_password( 32, false ), 92 | ] 93 | ); 94 | 95 | $signup_args = [ 'meta' => [] ]; 96 | 97 | $user_login = $r['user-login']; 98 | if ( ! empty( $user_login ) ) { 99 | $user_login = preg_replace( '/\s+/', '', sanitize_user( $user_login, true ) ); 100 | } 101 | 102 | $user_email = $r['user-email']; 103 | if ( ! empty( $user_email ) ) { 104 | $user_email = sanitize_email( $user_email ); 105 | } 106 | 107 | $signup_args['user_login'] = $user_login; 108 | $signup_args['user_email'] = $user_email; 109 | $signup_args['activation_key'] = $r['activation-key']; 110 | 111 | $signup_id = \BP_Signup::add( $signup_args ); 112 | 113 | // Silent it. 114 | if ( WP_CLI\Utils\get_flag_value( $assoc_args, 'silent' ) ) { 115 | return; 116 | } 117 | 118 | if ( ! $signup_id ) { 119 | WP_CLI::error( 'Could not add user signup.' ); 120 | } 121 | 122 | if ( WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ) ) { 123 | WP_CLI::log( $signup_id ); 124 | } else { 125 | WP_CLI::success( sprintf( 'Successfully added new user signup (ID #%d).', $signup_id ) ); 126 | } 127 | } 128 | 129 | /** 130 | * Get a signup. 131 | * 132 | * ## OPTIONS 133 | * 134 | * 135 | * : Identifier for the signup. Can be a signup ID, an email address, or a user_login. 136 | * 137 | * [--match-field=] 138 | * : Field to match the signup-id to. Use if there is ambiguity between, eg, signup ID and user_login. 139 | * --- 140 | * options: 141 | * - signup_id 142 | * - user_email 143 | * - user_login 144 | * --- 145 | * 146 | * [--fields=] 147 | * : Limit the output to specific signup fields. 148 | * 149 | * [--format=] 150 | * : Render output in a particular format. 151 | * --- 152 | * default: table 153 | * options: 154 | * - table 155 | * - json 156 | * - csv 157 | * - yaml 158 | * --- 159 | * 160 | * ## EXAMPLES 161 | * 162 | * # Get a signup. 163 | * $ wp bp signup get 35 --fields=id,user_login,user_name,count_sent 164 | * +------------+------------+ 165 | * | Field | Value | 166 | * +------------+------------+ 167 | * | id | 35 | 168 | * | user_login | user897616 | 169 | * | user_name | Test user | 170 | * | count_sent | 4 | 171 | * +------------+------------+ 172 | */ 173 | public function get( $args, $assoc_args ) { 174 | $signup = $this->get_signup_by_identifier( $args[0], $assoc_args ); 175 | 176 | $this->get_formatter( $assoc_args )->display_item( $signup ); 177 | } 178 | 179 | /** 180 | * Delete a signup. 181 | * 182 | * ## OPTIONS 183 | * 184 | * ... 185 | * : ID or IDs of signup to delete. 186 | * 187 | * [--yes] 188 | * : Answer yes to the confirmation message. 189 | * 190 | * ## EXAMPLES 191 | * 192 | * # Delete a signup. 193 | * $ wp bp signup delete 520 --yes 194 | * Success: Signup deleted 54565. 195 | * 196 | * # Delete multiple signups. 197 | * $ wp bp signup delete 55654 54565 --yes 198 | * Success: Signup deleted 55654. 199 | * Success: Signup deleted 54565. 200 | * 201 | * @alias remove 202 | * @alias trash 203 | */ 204 | public function delete( $args, $assoc_args ) { 205 | $signup_ids = wp_parse_id_list( $args ); 206 | 207 | if ( count( $signup_ids ) > 1 ) { 208 | WP_CLI::confirm( 'Are you sure you want to delete these signups?', $assoc_args ); 209 | } else { 210 | WP_CLI::confirm( 'Are you sure you want to delete this signup?', $assoc_args ); 211 | } 212 | 213 | parent::_delete( 214 | $signup_ids, 215 | $assoc_args, 216 | function ( $signup_id ) { 217 | if ( \BP_Signup::delete( [ $signup_id ] ) ) { 218 | return [ 'success', sprintf( 'Signup deleted %d.', $signup_id ) ]; 219 | } 220 | 221 | return [ 'error', sprintf( 'Could not delete signup %d.', $signup_id ) ]; 222 | } 223 | ); 224 | } 225 | 226 | /** 227 | * Activate a signup. 228 | * 229 | * ## OPTIONS 230 | * 231 | * 232 | * : Identifier for the signup. Can be a signup ID, an email address, or a user_login. 233 | * 234 | * ## EXAMPLES 235 | * 236 | * # Activate a signup. 237 | * $ wp bp signup activate ee48ec319fef3nn4 238 | * Success: Signup activated, new user (ID #545). 239 | */ 240 | public function activate( $args, $assoc_args ) { 241 | $signup = $this->get_signup_by_identifier( $args[0], $assoc_args ); 242 | $user_id = bp_core_activate_signup( $signup->activation_key ); 243 | 244 | if ( $user_id ) { 245 | WP_CLI::success( sprintf( 'Signup activated, new user (ID #%d).', $user_id ) ); 246 | } else { 247 | WP_CLI::error( 'Signup not activated.' ); 248 | } 249 | } 250 | 251 | /** 252 | * Generate random signups. 253 | * 254 | * ## OPTIONS 255 | * 256 | * [--count=] 257 | * : How many signups to generate. 258 | * --- 259 | * default: 100 260 | * --- 261 | * 262 | * [--format=] 263 | * : Render output in a particular format. 264 | * --- 265 | * default: progress 266 | * options: 267 | * - progress 268 | * - ids 269 | * --- 270 | * 271 | * ## EXAMPLES 272 | * 273 | * # Generate 50 random signups. 274 | * $ wp bp signup generate --count=50 275 | * Generating signups 100% [======================] 0:00 / 0:00 276 | * 277 | * # Generate 5 random signups and return their IDs. 278 | * $ wp bp signup generate --count=5 --format=ids 279 | * 70 71 72 73 74 280 | */ 281 | public function generate( $args, $assoc_args ) { 282 | // Use the email API to get a valid "from" domain. 283 | $email_domain = new \BP_Email( '' ); 284 | $email_domain = $email_domain->get_from()->get_address(); 285 | $random_login = wp_generate_password( 12, false ); // Generate random user login. 286 | 287 | $this->generate_callback( 288 | 'Generating signups', 289 | $assoc_args, 290 | function ( $assoc_args, $format ) use ( $random_login, $email_domain ) { 291 | $params = [ 292 | 'user-login' => $random_login, 293 | 'user-email' => $random_login . substr( $email_domain, strpos( $email_domain, '@' ) ), 294 | ]; 295 | 296 | if ( 'ids' === $format ) { 297 | $params['porcelain'] = true; 298 | } else { 299 | $params['silent'] = true; 300 | } 301 | 302 | return $this->create( [], $params ); 303 | } 304 | ); 305 | } 306 | 307 | /** 308 | * Resend activation e-mail to a newly registered user. 309 | * 310 | * ## OPTIONS 311 | * 312 | * 313 | * : Identifier for the signup. Can be a signup ID, an email address, or a user_login. 314 | * 315 | * ## EXAMPLES 316 | * 317 | * # Resend activation e-mail to a newly registered user. 318 | * $ wp bp signup resend test@example.com 319 | * Success: Email sent successfully. 320 | * 321 | * @alias send 322 | */ 323 | public function resend( $args, $assoc_args ) { 324 | $signup = $this->get_signup_by_identifier( $args[0], $assoc_args ); 325 | $send = \BP_Signup::resend( [ $signup->signup_id ] ); 326 | 327 | // Add feedback message. 328 | if ( empty( $send['errors'] ) ) { 329 | WP_CLI::success( 'Email sent successfully.' ); 330 | } else { 331 | WP_CLI::error( 'This account is already activated.' ); 332 | } 333 | } 334 | 335 | /** 336 | * Get a list of signups. 337 | * 338 | * ## OPTIONS 339 | * 340 | * [--=] 341 | * : One or more parameters to pass. See \BP_Signup::get() 342 | * 343 | * [--fields=] 344 | * : Fields to display. 345 | * 346 | * [--count=] 347 | * : How many signups to list. 348 | * --- 349 | * default: 50 350 | * --- 351 | * 352 | * [--format=] 353 | * : Render output in a particular format. 354 | * --- 355 | * default: table 356 | * options: 357 | * - table 358 | * - csv 359 | * - ids 360 | * - json 361 | * - count 362 | * - yaml 363 | * --- 364 | * 365 | * ## EXAMPLES 366 | * 367 | * # List signups and get the IDs. 368 | * $ wp bp signup list --format=ids 369 | * 70 71 72 73 74 370 | * 371 | * # List 100 signups and return the count. 372 | * $ wp bp signup list --count=100 --format=count 373 | * 100 374 | * 375 | * # List active signups. 376 | * $ wp bp signup list --active=1 --count=10 377 | * 50 378 | * 379 | * @subcommand list 380 | */ 381 | public function list_( $args, $assoc_args ) { 382 | $formatter = $this->get_formatter( $assoc_args ); 383 | 384 | $assoc_args['number'] = $assoc_args['count']; 385 | 386 | if ( in_array( $formatter->format, [ 'ids', 'count' ], true ) ) { 387 | $assoc_args['fields'] = 'ids'; 388 | } 389 | 390 | $signups = \BP_Signup::get( $assoc_args ); 391 | 392 | if ( empty( $signups['signups'] ) ) { 393 | WP_CLI::error( 'No signups found.' ); 394 | } 395 | 396 | $formatter->display_items( $signups['signups'] ); 397 | } 398 | 399 | /** 400 | * Look up a signup by the provided identifier. 401 | * 402 | * @since 1.5.0 403 | * 404 | * @return mixed 405 | */ 406 | protected function get_signup_by_identifier( $identifier, $assoc_args ) { 407 | if ( isset( $assoc_args['match-field'] ) ) { 408 | switch ( $assoc_args['match-field'] ) { 409 | case 'signup_id': 410 | $signup_args['include'] = [ $identifier ]; 411 | break; 412 | 413 | case 'user_login': 414 | $signup_args['user_login'] = $identifier; 415 | break; 416 | 417 | case 'user_email': 418 | default: 419 | $signup_args['usersearch'] = $identifier; 420 | break; 421 | } 422 | } elseif ( is_numeric( $identifier ) ) { 423 | $signup_args['include'] = [ intval( $identifier ) ]; 424 | } elseif ( is_email( $identifier ) ) { 425 | $signup_args['usersearch'] = $identifier; 426 | } else { 427 | $signup_args['user_login'] = $identifier; 428 | } 429 | 430 | $signups = \BP_Signup::get( $signup_args ); 431 | $signup = null; 432 | 433 | if ( ! empty( $signups['signups'] ) ) { 434 | $signup = reset( $signups['signups'] ); 435 | } 436 | 437 | if ( ! $signup ) { 438 | WP_CLI::error( 'No signup found by that identifier.' ); 439 | } 440 | 441 | return $signup; 442 | } 443 | } 444 | -------------------------------------------------------------------------------- /src/sitewide-notice.php: -------------------------------------------------------------------------------- 1 | 65 | * : Notice subject text. 66 | * 67 | * --message= 68 | * : Notice message text. 69 | * 70 | * [--silent] 71 | * : Whether to silent the notice creation. 72 | * 73 | * [--porcelain] 74 | * : Output the new notice id only. 75 | * 76 | * ## EXAMPLES 77 | * 78 | * # Create a sitewide notice. 79 | * $ wp bp notice create --subject=Hello --message=Folks! 80 | * Success: Successfully created new sitewide notice. (ID #5464) 81 | * 82 | * # Create a sitewide notice and return its ID. 83 | * $ wp bp notice create --subject=Hello --message=Folks! --porcelain 84 | * 36565 85 | * 86 | * @alias add 87 | */ 88 | public function create( $args, $assoc_args ) { 89 | $notice = new BP_Messages_Notice(); 90 | $notice->subject = $assoc_args['subject']; 91 | $notice->message = $assoc_args['message']; 92 | $notice->date_sent = bp_core_current_time(); 93 | $notice->is_active = 1; 94 | $retval = $notice->save(); // Create it. 95 | 96 | // Silent it before it errors. 97 | if ( WP_CLI\Utils\get_flag_value( $assoc_args, 'silent' ) ) { 98 | return; 99 | } 100 | 101 | if ( ! $retval ) { 102 | WP_CLI::error( 'Could not create sitewide notice.' ); 103 | } 104 | 105 | // The notice we just created is the active one. 106 | $active_notice = BP_Messages_Notice::get_active(); 107 | 108 | if ( WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ) ) { 109 | WP_CLI::log( $active_notice->id ); 110 | } else { 111 | WP_CLI::success( sprintf( 'Successfully created new sitewide notice (ID #%d)', $active_notice->id ) ); 112 | } 113 | } 114 | 115 | /** 116 | * Get specific sitewide notice. 117 | * 118 | * ## OPTIONS 119 | * 120 | * 121 | * : Identifier for the notice. 122 | * 123 | * [--fields=] 124 | * : Limit the output to specific fields. 125 | * 126 | * [--format=] 127 | * : Render output in a particular format. 128 | * --- 129 | * default: table 130 | * options: 131 | * - table 132 | * - json 133 | * - csv 134 | * - yaml 135 | * --- 136 | * 137 | * ## EXAMPLES 138 | * 139 | * # Get a sitewide notice. 140 | * $ wp bp notice get 500 141 | * +-----------+---------------------+ 142 | * | Field | Value | 143 | * +-----------+---------------------+ 144 | * | id | 4 | 145 | * | subject | Important message | 146 | * | message | Let's talk! | 147 | * | date_sent | 2023-01-11 12:47:00 | 148 | * | is_active | 1 | 149 | * +-----------+---------------------+ 150 | * 151 | * # Get a sitewide notice in JSON format. 152 | * $ wp bp notice get 56 --format=json 153 | * {"id":4,"subject":"Important message","message":"Let's talk!","date_sent":"2023-01-11 12:47:00","is_active":1} 154 | * 155 | * @alias see 156 | */ 157 | public function get( $args, $assoc_args ) { 158 | $notice_id = $args[0]; 159 | 160 | if ( ! is_numeric( $notice_id ) ) { 161 | WP_CLI::error( 'Please provide a numeric notice ID.' ); 162 | } 163 | 164 | $notice = new BP_Messages_Notice( $notice_id ); 165 | 166 | if ( ! $notice->date_sent ) { 167 | WP_CLI::error( 'No sitewide notice found.' ); 168 | } 169 | 170 | $notice_arr = get_object_vars( $notice ); 171 | 172 | if ( empty( $assoc_args['fields'] ) ) { 173 | $assoc_args['fields'] = array_keys( $notice_arr ); 174 | } 175 | 176 | $this->get_formatter( $assoc_args )->display_item( $notice_arr ); 177 | } 178 | 179 | /** 180 | * Delete sitewide notice(s). 181 | * 182 | * ## OPTIONS 183 | * 184 | * ... 185 | * : ID or IDs of sitewide notices to delete. 186 | * 187 | * [--yes] 188 | * : Answer yes to the confirmation message. 189 | * 190 | * ## EXAMPLES 191 | * 192 | * # Delete a sitewide notice. 193 | * $ wp bp notice delete 520 --yes 194 | * Success: Sitewide notice deleted 520. 195 | * 196 | * # Delete multiple sitewide notices. 197 | * $ wp bp notice delete 55654 54564 --yes 198 | * Success: Sitewide notice deleted 55654. 199 | * Success: Sitewide notice deleted 54564. 200 | * 201 | * @alias remove 202 | * @alias trash 203 | */ 204 | public function delete( $args, $assoc_args ) { 205 | $notice_ids = wp_parse_id_list( $args ); 206 | 207 | if ( count( $notice_ids ) > 1 ) { 208 | WP_CLI::confirm( 'Are you sure you want to delete these notices?', $assoc_args ); 209 | } else { 210 | WP_CLI::confirm( 'Are you sure you want to delete this notice?', $assoc_args ); 211 | } 212 | 213 | parent::_delete( 214 | $notice_ids, 215 | $assoc_args, 216 | function ( $notice_id ) { 217 | $notice = new BP_Messages_Notice( $notice_id ); 218 | 219 | if ( ! empty( $notice->date_sent ) && $notice->delete() ) { 220 | return [ 'success', sprintf( 'Sitewide notice deleted %d.', $notice_id ) ]; 221 | } 222 | 223 | return [ 'error', sprintf( 'Could not delete sitewide notice %d.', $notice_id ) ]; 224 | } 225 | ); 226 | } 227 | 228 | /** 229 | * Activate a sitewide notice. 230 | * 231 | * ## OPTIONS 232 | * 233 | * 234 | * : Identifier for the notice. 235 | * 236 | * ## EXAMPLE 237 | * 238 | * $ wp bp notice activate 123 239 | * Success: Sitewide notice activated. 240 | */ 241 | public function activate( $args ) { 242 | $notice = new BP_Messages_Notice( $args[0] ); 243 | 244 | if ( ! $notice->date_sent ) { 245 | WP_CLI::error( 'No sitewide notice found by that ID.' ); 246 | } 247 | 248 | $notice->is_active = 1; 249 | 250 | if ( ! $notice->save() ) { 251 | WP_CLI::error( 'Could not activate sitewide notice.' ); 252 | } 253 | 254 | WP_CLI::success( 'Sitewide notice activated.' ); 255 | } 256 | 257 | /** 258 | * Deactivate a sitewide notice. 259 | * 260 | * ## OPTIONS 261 | * 262 | * 263 | * : Identifier for the notice. 264 | * 265 | * ## EXAMPLE 266 | * 267 | * $ wp bp notice deactivate 123 268 | * Success: Sitewide notice has been deactivated. 269 | */ 270 | public function deactivate( $args ) { 271 | $notice = new BP_Messages_Notice( $args[0] ); 272 | 273 | if ( ! $notice->date_sent ) { 274 | WP_CLI::error( 'No sitewide notice found by that ID.' ); 275 | } 276 | 277 | $notice->is_active = 0; 278 | 279 | if ( ! $notice->save() ) { 280 | WP_CLI::error( 'Could not deactivate sitewide notice.' ); 281 | } 282 | 283 | WP_CLI::success( 'Sitewide notice has been deactivated.' ); 284 | } 285 | 286 | /** 287 | * Get a list of sitewide notices. 288 | * 289 | * ## OPTIONS 290 | * 291 | * [--fields=] 292 | * : Fields to display. 293 | * 294 | * [--count=] 295 | * : How many notices to list. 296 | * --- 297 | * default: 50 298 | * --- 299 | * 300 | * [--format=] 301 | * : Render output in a particular format. 302 | * --- 303 | * default: table 304 | * options: 305 | * - table 306 | * - ids 307 | * - count 308 | * - csv 309 | * - json 310 | * - yaml 311 | * --- 312 | 313 | * ## EXAMPLES 314 | * 315 | * # List all sitewide notices, and output only the IDs. 316 | * $ wp bp notice list --format=ids 317 | * 15 25 34 37 198 318 | * 319 | * # List all sitewide notices, and output the count. 320 | * $ wp bp notice list --format=count 321 | * 10 322 | * 323 | * # List all sitewide notices, and output the IDs. 324 | * $ wp bp notice list --fields=id 325 | * | id | 326 | * | 66546 | 327 | * | 54554 | 328 | * 329 | * @subcommand list 330 | */ 331 | public function list_( $args, $assoc_args ) { 332 | $formatter = $this->get_formatter( $assoc_args ); 333 | $query_args = [ 'pag_num' => (int) $assoc_args['count'] ]; 334 | 335 | $query_args = self::process_csv_arguments_to_arrays( $query_args ); 336 | $notices = BP_Messages_Notice::get_notices( $query_args ); 337 | 338 | if ( empty( $notices ) ) { 339 | WP_CLI::error( 'No sitewide notices found.' ); 340 | } 341 | 342 | $formatter->display_items( 'ids' === $formatter->format ? wp_list_pluck( $notices, 'id' ) : $notices ); 343 | } 344 | } 345 | -------------------------------------------------------------------------------- /src/templates/bootstrap-buddypress.php: -------------------------------------------------------------------------------- 1 | > tests/bootstrap.php 28 | -------------------------------------------------------------------------------- /src/tool.php: -------------------------------------------------------------------------------- 1 | plugin_dir . 'bp-core/admin/bp-core-admin-tools.php'; 35 | } 36 | 37 | /** 38 | * Repair. 39 | * 40 | * ## OPTIONS 41 | * 42 | * 43 | * : Name of the repair tool. 44 | * --- 45 | * options: 46 | * - friend-count 47 | * - group-count 48 | * - blog-records 49 | * - count-members 50 | * --- 51 | * 52 | * ## EXAMPLES 53 | * 54 | * # Repair the friend count. 55 | * $ wp bp tool repair friend-count 56 | * Success: Counting the number of friends for each user. Complete! 57 | * 58 | * @alias fix 59 | */ 60 | public function repair( $args ) { 61 | $repair = 'bp_admin_repair_' . $this->sanitize_string( $args[0] ); 62 | 63 | if ( ! function_exists( $repair ) ) { 64 | WP_CLI::error( 'There is no repair tool with that name.' ); 65 | } 66 | 67 | // Run the callable repair function. 68 | $result = $repair(); 69 | 70 | if ( empty( $repair ) ) { 71 | WP_CLI::error( 'The component of the tool is not active.' ); 72 | } 73 | 74 | if ( 0 === $result[0] ) { 75 | WP_CLI::success( $result[1] ); 76 | } else { 77 | WP_CLI::error( $result[1] ); 78 | } 79 | } 80 | 81 | /** 82 | * Display BuddyPress version currently installed. 83 | * 84 | * ## EXAMPLE 85 | * 86 | * # Display BuddyPress version. 87 | * $ wp bp tool version 88 | * BuddyPress: 6.0.0 89 | */ 90 | public function version() { 91 | WP_CLI::log( 'BuddyPress: ' . bp_get_version() ); 92 | } 93 | 94 | /** 95 | * (De)Activate the signup feature. 96 | * 97 | * 98 | * : Status of the feature. 99 | * 100 | * ## EXAMPLES 101 | * 102 | * # Activate the signup tool. 103 | * $ wp bp tool signup 1 104 | * Success: Signup tool updated. 105 | * 106 | * # Deactivate the signup tool. 107 | * $ wp bp tool signup 0 108 | * Success: Signup tool updated. 109 | */ 110 | public function signup( $args ) { 111 | $status = wp_validate_boolean( $args[0] ); 112 | 113 | if ( is_multisite() ) { 114 | $retval = get_site_option( 'registration' ); 115 | 116 | if ( 'all' === $retval && $status ) { 117 | WP_CLI::error( 'Both sites and user accounts registration is already allowed.' ); 118 | } 119 | 120 | $current = $status ? 'all' : 'none'; 121 | update_site_option( 'registration', $current ); 122 | } else { 123 | if ( bp_get_signup_allowed() && $status ) { 124 | WP_CLI::error( 'The BuddyPress signup feature is already allowed.' ); 125 | } 126 | 127 | bp_update_option( 'users_can_register', $status ); 128 | } 129 | 130 | WP_CLI::success( 'Signup tool updated.' ); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/xprofile-data.php: -------------------------------------------------------------------------------- 1 | 33 | * : Identifier for the user. Accepts either a user_login or a numeric ID. 34 | * 35 | * --field-id= 36 | * : Identifier for the field. Accepts either the name of the field or a numeric ID. 37 | * 38 | * --value= 39 | * : Value to set. 40 | * 41 | * [--silent] 42 | * : Whether to silent the success message. 43 | * 44 | * ## EXAMPLE 45 | * 46 | * # Set profile data for a user. 47 | * $ wp bp xprofile data set --user-id=45 --field-id=120 --value=test 48 | * Success: Updated XProfile field "Field Name" (ID 120) with value "test" for user user_login (ID 45). 49 | * 50 | * @alias set 51 | * @alias add 52 | * @alias update 53 | */ 54 | public function create( $args, $assoc_args ) { 55 | $user = $this->get_user_id_from_identifier( $assoc_args['user-id'] ); 56 | $field_id = $this->get_field_id( $assoc_args['field-id'] ); 57 | $field = new \BP_XProfile_Field( $field_id ); 58 | 59 | if ( empty( $field->name ) ) { 60 | WP_CLI::error( 'XProfile field not found.' ); 61 | } 62 | 63 | $value = $assoc_args['value']; 64 | 65 | if ( 'checkbox' === $field->type ) { 66 | $value = explode( ',', $assoc_args['value'] ); 67 | } 68 | 69 | $updated = xprofile_set_field_data( $field->id, $user->ID, $value ); 70 | 71 | // Silent it before it errors. 72 | if ( WP_CLI\Utils\get_flag_value( $assoc_args, 'silent' ) ) { 73 | return; 74 | } 75 | 76 | if ( ! $updated ) { 77 | WP_CLI::error( 'Could not set profile data.' ); 78 | } 79 | 80 | WP_CLI::success( 81 | sprintf( 82 | 'Updated XProfile field "%s" (ID %d) with value "%s" for user %s (ID %d).', 83 | $field->name, 84 | $field->id, 85 | $assoc_args['value'], 86 | $user->user_nicename, 87 | $user->ID 88 | ) 89 | ); 90 | } 91 | 92 | /** 93 | * Get profile data for a user. 94 | * 95 | * ## OPTIONS 96 | * 97 | * --user-id= 98 | * : Identifier for the user. Accepts either a user_login or a numeric ID. 99 | * 100 | * [--field-id=] 101 | * : Identifier for the field. Accepts either the name of the field or a numeric ID. 102 | * 103 | * [--format=] 104 | * : Render output in a particular format. 105 | * --- 106 | * default: table 107 | * options: 108 | * - table 109 | * - json 110 | * - csv 111 | * - yaml 112 | * --- 113 | * 114 | * [--multi-format=] 115 | * : The format for the array data. 116 | * --- 117 | * default: array 118 | * options: 119 | * - array 120 | * - comma 121 | * --- 122 | * 123 | * ## EXAMPLES 124 | * 125 | * # Get profile data for a user. 126 | * $ wp bp xprofile data get --user-id=45 --field-id=120 127 | * 128 | * # Get profile data for a user, formatting the data. 129 | * $ wp bp xprofile data see --user-id=user_test --field-id=Hometown --multi-format=comma 130 | * 131 | * @alias see 132 | */ 133 | public function get( $args, $assoc_args ) { 134 | $user = $this->get_user_id_from_identifier( $assoc_args['user-id'] ); 135 | 136 | if ( isset( $assoc_args['field-id'] ) ) { 137 | $data = xprofile_get_field_data( $assoc_args['field-id'], $user->ID, $assoc_args['multi-format'] ); 138 | WP_CLI::print_value( $data, $assoc_args ); 139 | } else { 140 | $data = \BP_XProfile_ProfileData::get_all_for_user( $user->ID ); 141 | $formatted_data = []; 142 | 143 | foreach ( $data as $field_name => $field_data ) { 144 | // Omit WP core fields. 145 | if ( ! is_array( $field_data ) ) { 146 | continue; 147 | } 148 | 149 | $formatted_data[] = [ 150 | 'field_id' => $field_data['field_id'], 151 | 'field_name' => $field_name, 152 | 'value' => wp_json_encode( maybe_unserialize( $field_data['field_data'] ) ), 153 | ]; 154 | } 155 | 156 | $format_args = $assoc_args; 157 | $format_args['fields'] = [ 158 | 'field_id', 159 | 'field_name', 160 | 'value', 161 | ]; 162 | 163 | $this->get_formatter( $format_args )->display_items( $formatted_data ); 164 | } 165 | } 166 | 167 | /** 168 | * Delete XProfile data for a user. 169 | * 170 | * ## OPTIONS 171 | * 172 | * --user-id= 173 | * : Identifier for the user. Accepts either a user_login or a numeric ID. 174 | * 175 | * [--field-id=] 176 | * : Identifier for the field. Accepts either the name of the field or a numeric ID. 177 | * 178 | * [--delete-all] 179 | * : Delete all data for the user. 180 | * 181 | * [--yes] 182 | * : Answer yes to the confirmation message. 183 | * 184 | * ## EXAMPLES 185 | * 186 | * # Delete a specific XProfile field data. 187 | * $ wp bp xprofile data delete --user-id=45 --field-id=120 --yes 188 | * Success: XProfile data removed. 189 | * 190 | * # Delete all XProfile data for a user. 191 | * $ wp bp xprofile data remove --user-id=user_test --delete-all --yes 192 | * Success: XProfile data removed. 193 | * 194 | * @alias remove 195 | * @alias trash 196 | */ 197 | public function delete( $args, $assoc_args ) { 198 | $user = $this->get_user_id_from_identifier( $assoc_args['user-id'] ); 199 | 200 | if ( ! isset( $assoc_args['field-id'] ) && ! isset( $assoc_args['delete-all'] ) ) { 201 | WP_CLI::error( 'Either --field-id or --delete-all must be provided.' ); 202 | } 203 | 204 | if ( isset( $assoc_args['delete-all'] ) ) { 205 | WP_CLI::confirm( sprintf( 'Are you sure you want to delete all XProfile data for the user %s (#%d)?', $user->user_login, $user->ID ), $assoc_args ); 206 | 207 | xprofile_remove_data( $user->ID ); 208 | WP_CLI::success( 'XProfile data removed.' ); 209 | } else { 210 | WP_CLI::confirm( 'Are you sure you want to delete that?', $assoc_args ); 211 | 212 | if ( xprofile_delete_field_data( $assoc_args['field-id'], $user->ID ) ) { 213 | WP_CLI::success( 'XProfile data removed.' ); 214 | } else { 215 | WP_CLI::error( 'Could not delete XProfile data.' ); 216 | } 217 | } 218 | } 219 | } 220 | -------------------------------------------------------------------------------- /src/xprofile-field.php: -------------------------------------------------------------------------------- 1 | =] 34 | * : One or more parameters to pass. See bp_xprofile_get_groups() 35 | * 36 | * [--format=] 37 | * : Render output in a particular format. 38 | * --- 39 | * default: table 40 | * options: 41 | * - table 42 | * - csv 43 | * - ids 44 | * - json 45 | * - count 46 | * - yaml 47 | * --- 48 | * 49 | * * ## AVAILABLE FIELDS 50 | * 51 | * These fields will be displayed by default for each field: 52 | * 53 | * * id 54 | * * name 55 | * * description 56 | * * type 57 | * * group_id 58 | * * is_required 59 | * 60 | * ## EXAMPLE 61 | * 62 | * # List XProfile fields. 63 | * $ wp bp xprofile field list 64 | * +----+------+-------------+---------+----------+-------------+ 65 | * | id | name | description | type | group_id | is_required | 66 | * +----+------+-------------+---------+----------+-------------+ 67 | * | 1 | Name | | textbox | 1 | 1 | 68 | * +----+------+-------------+---------+----------+-------------+ 69 | * 70 | * @subcommand list 71 | */ 72 | public function list_( $args, $assoc_args ) { 73 | $args = array_merge( 74 | $assoc_args, 75 | [ 76 | 'fields' => 'id,name', 77 | 'fetch_fields' => true, 78 | ] 79 | ); 80 | 81 | $fields = []; 82 | $groups = bp_xprofile_get_groups( $args ); 83 | 84 | // Reformat so that field_group_id is a property of fields. 85 | foreach ( $groups as $group ) { 86 | foreach ( $group->fields as $field ) { 87 | $fields[ $field->id ] = $field; 88 | } 89 | } 90 | 91 | $formatter = $this->get_formatter( $assoc_args ); 92 | $formatter->display_items( 'ids' === $formatter->format ? wp_list_pluck( $fields, 'id' ) : $fields ); 93 | } 94 | 95 | /** 96 | * Create a XProfile field. 97 | * 98 | * ## OPTIONS 99 | * 100 | * --field-group-id= 101 | * : ID of the field group where the new field will be created. 102 | * 103 | * --name= 104 | * : Name of the new field. 105 | * 106 | * [--type=] 107 | * : Field type. 108 | * --- 109 | * default: textbox 110 | * --- 111 | * 112 | * [--silent] 113 | * : Whether to silent the XProfile field creation. 114 | * 115 | * [--porcelain] 116 | * : Output just the new field id. 117 | * 118 | * ## EXAMPLES 119 | * 120 | * # Create a XProfile field. 121 | * $ wp bp xprofile field create --type=checkbox --field-group-id=508 --name="Field Name" 122 | * Success: Created XProfile field "Field Name" (ID 24564). 123 | * 124 | * # Create a XProfile field. 125 | * $ wp bp xprofile field add --field-group-id=165 --name="Another Field" 126 | * Success: Created XProfile field "Another Field" (ID 5465). 127 | * 128 | * @alias add 129 | */ 130 | public function create( $args, $assoc_args ) { 131 | // Check this is a non-empty, valid field type. 132 | if ( ! in_array( $assoc_args['type'], (array) buddypress()->profile->field_types, true ) ) { 133 | WP_CLI::error( 'Not a valid field type.' ); 134 | } 135 | 136 | $xprofile_field_id = xprofile_insert_field( 137 | [ 138 | 'type' => $assoc_args['type'], 139 | 'name' => $assoc_args['name'], 140 | 'field_group_id' => $assoc_args['field-group-id'], 141 | ] 142 | ); 143 | 144 | // Silent it before it errors. 145 | if ( WP_CLI\Utils\get_flag_value( $assoc_args, 'silent' ) ) { 146 | return; 147 | } 148 | 149 | if ( ! $xprofile_field_id ) { 150 | WP_CLI::error( 'Could not create XProfile field.' ); 151 | } 152 | 153 | if ( WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ) ) { 154 | WP_CLI::log( $xprofile_field_id ); 155 | } else { 156 | $field = new \BP_XProfile_Field( $xprofile_field_id ); 157 | 158 | WP_CLI::success( 159 | sprintf( 160 | 'Created XProfile field "%s" (ID %d).', 161 | $field->name, 162 | $field->id 163 | ) 164 | ); 165 | } 166 | } 167 | 168 | /** 169 | * Get an XProfile field. 170 | * 171 | * ## OPTIONS 172 | * 173 | * 174 | * : Identifier for the field. Accepts either the name of the field or a numeric ID. 175 | * 176 | * [--fields=] 177 | * : Limit the output to specific fields. 178 | * 179 | * [--format=] 180 | * : Render output in a particular format. 181 | * --- 182 | * default: table 183 | * options: 184 | * - table 185 | * - json 186 | * - csv 187 | * - yaml 188 | * --- 189 | * 190 | * ## EXAMPLES 191 | * 192 | * # Get a xprofile field. 193 | * $ wp bp xprofile field get 500 194 | * 195 | * # Get a xprofile field in JSON format. 196 | * $ wp bp xprofile field see 56 --format=json 197 | * 198 | * @alias see 199 | */ 200 | public function get( $args, $assoc_args ) { 201 | $field_id = $this->get_field_id( $args[0] ); 202 | $object = xprofile_get_field( $field_id ); 203 | 204 | if ( empty( $object->id ) && ! is_object( $object ) ) { 205 | WP_CLI::error( 'No XProfile field found.' ); 206 | } 207 | 208 | $object_arr = get_object_vars( $object ); 209 | 210 | if ( empty( $assoc_args['fields'] ) ) { 211 | $assoc_args['fields'] = array_keys( $object_arr ); 212 | } 213 | 214 | $this->get_formatter( $assoc_args )->display_item( $object_arr ); 215 | } 216 | 217 | /** 218 | * Delete an XProfile field. 219 | * 220 | * ## OPTIONS 221 | * 222 | * ... 223 | * : ID or IDs for the field. Accepts either the name of the field or a numeric ID. 224 | * 225 | * [--delete-data] 226 | * : Delete user data for the field as well. 227 | * 228 | * [--yes] 229 | * : Answer yes to the confirmation message. 230 | * 231 | * ## EXAMPLES 232 | * 233 | * # Delete a field. 234 | * $ wp bp xprofile field delete 500 --yes 235 | * Success: Deleted XProfile field "Field Name" (ID 500). 236 | * 237 | * # Delete a field and its data. 238 | * $ wp bp xprofile field remove 458 --delete-data --yes 239 | * Success: Deleted XProfile field "Another Field Name" (ID 458). 240 | * 241 | * @alias remove 242 | * @alias trash 243 | */ 244 | public function delete( $args, $assoc_args ) { 245 | $delete_data = (bool) WP_CLI\Utils\get_flag_value( $assoc_args, 'delete-data' ); 246 | $field_ids = wp_parse_id_list( $args ); 247 | 248 | if ( count( $field_ids ) > 1 ) { 249 | WP_CLI::confirm( 'Are you sure you want to delete these fields?', $assoc_args ); 250 | } else { 251 | WP_CLI::confirm( 'Are you sure you want to delete this field?', $assoc_args ); 252 | } 253 | 254 | parent::_delete( 255 | $field_ids, 256 | $assoc_args, 257 | function ( $field_id ) use ( $delete_data ) { 258 | $field = new \BP_XProfile_Field( $field_id ); 259 | $name = $field->name; 260 | $id = $field->id; 261 | 262 | if ( $field->delete( $delete_data ) ) { 263 | return [ 'success', sprintf( 'Deleted XProfile field "%s" (ID %d).', $name, $id ) ]; 264 | } 265 | 266 | return [ 'error', sprintf( 'Failed deleting XProfile field "%s" (ID %d).', $name, $id ) ]; 267 | } 268 | ); 269 | } 270 | } 271 | -------------------------------------------------------------------------------- /src/xprofile-group.php: -------------------------------------------------------------------------------- 1 | 40 | * : The name for this field group. 41 | * 42 | * [--description=] 43 | * : The description for this field group. 44 | * 45 | * [--can-delete=] 46 | * : Whether the group can be deleted. 47 | * --- 48 | * default: 1 49 | * --- 50 | * 51 | * [--silent] 52 | * : Whether to silent the XProfile group creation. 53 | * 54 | * [--porcelain] 55 | * : Output just the new group id. 56 | * 57 | * ## EXAMPLES 58 | * 59 | * # Create XProfile field group. 60 | * $ wp bp xprofile group create --name="Group Name" --description="Xprofile Group Description" 61 | * Success: Created XProfile field group "Group Name" (ID 123). 62 | * 63 | * # Create XProfile field group that can't be deleted. 64 | * $ wp bp xprofile group add --name="Another Group" --can-delete=false 65 | * Success: Created XProfile field group "Another Group" (ID 21212). 66 | * 67 | * @alias add 68 | */ 69 | public function create( $args, $assoc_args ) { 70 | $r = wp_parse_args( 71 | $assoc_args, 72 | [ 73 | 'name' => '', 74 | 'description' => '', 75 | ] 76 | ); 77 | 78 | $xprofile_group_id = xprofile_insert_field_group( $r ); 79 | 80 | // Silent it before it errors. 81 | if ( WP_CLI\Utils\get_flag_value( $assoc_args, 'silent' ) ) { 82 | return; 83 | } 84 | 85 | if ( ! $xprofile_group_id ) { 86 | WP_CLI::error( 'Could not create field group.' ); 87 | } 88 | 89 | if ( WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ) ) { 90 | WP_CLI::log( $xprofile_group_id ); 91 | } else { 92 | $group = new \BP_XProfile_Group( $xprofile_group_id ); 93 | 94 | WP_CLI::success( 95 | sprintf( 96 | 'Created XProfile field group "%s" (ID %d).', 97 | $group->name, 98 | $group->id 99 | ) 100 | ); 101 | } 102 | } 103 | 104 | /** 105 | * Fetch specific XProfile field group. 106 | * 107 | * ## OPTIONS 108 | * 109 | * 110 | * : Identifier for the field group. 111 | * 112 | * [--fields=] 113 | * : Limit the output to specific fields. 114 | * 115 | * [--format=] 116 | * : Render output in a particular format. 117 | * --- 118 | * default: table 119 | * options: 120 | * - table 121 | * - json 122 | * - csv 123 | * - yaml 124 | * --- 125 | * 126 | * ## EXAMPLES 127 | * 128 | * # Get a specific field group. 129 | * $ wp bp xprofile group get 500 130 | * +-------------+---------------+ 131 | * | Field | Value | 132 | * +-------------+---------------+ 133 | * | id | 2 | 134 | * | name | Group | 135 | * | description | | 136 | * | can_delete | 1 | 137 | * | group_order | 0 | 138 | * | fields | null | 139 | * +-------------+---------------+ 140 | * 141 | * # Get a specific field group in JSON format. 142 | * $ wp bp xprofile group see 56 --format=json 143 | * {"id":2,"name":"Group","description":"","can_delete":1,"group_order":0,"fields":null} 144 | * 145 | * @alias see 146 | */ 147 | public function get( $args, $assoc_args ) { 148 | $field_group_id = $args[0]; 149 | 150 | if ( ! is_numeric( $field_group_id ) ) { 151 | WP_CLI::error( 'Please provide a numeric field group ID.' ); 152 | } 153 | 154 | $object = xprofile_get_field_group( $field_group_id ); 155 | 156 | if ( empty( $object->id ) && ! is_object( $object ) ) { 157 | WP_CLI::error( 'No XProfile field group found.' ); 158 | } 159 | 160 | $object_arr = get_object_vars( $object ); 161 | 162 | if ( empty( $assoc_args['fields'] ) ) { 163 | $assoc_args['fields'] = array_keys( $object_arr ); 164 | } 165 | 166 | $this->get_formatter( $assoc_args )->display_item( $object_arr ); 167 | } 168 | 169 | /** 170 | * Delete specific XProfile field group(s). 171 | * 172 | * ## OPTIONS 173 | * 174 | * ... 175 | * : ID or IDs of field groups to delete. 176 | * 177 | * [--yes] 178 | * : Answer yes to the confirmation message. 179 | * 180 | * ## EXAMPLES 181 | * 182 | * # Delete a specific field group. 183 | * $ wp bp xprofile group delete 500 --yes 184 | * Success: Field group deleted 500. 185 | * 186 | * $ wp bp xprofile group delete 55654 54564 --yes 187 | * Success: Field group deleted 55654. 188 | * Success: Field group deleted 54564. 189 | * 190 | * @alias remove 191 | * @alias trash 192 | */ 193 | public function delete( $args, $assoc_args ) { 194 | $field_groups_ids = wp_parse_id_list( $args ); 195 | 196 | if ( count( $field_groups_ids ) > 1 ) { 197 | WP_CLI::confirm( 'Are you sure you want to delete these field groups?', $assoc_args ); 198 | } else { 199 | WP_CLI::confirm( 'Are you sure you want to delete this field group?', $assoc_args ); 200 | } 201 | 202 | parent::_delete( 203 | $field_groups_ids, 204 | $assoc_args, 205 | function ( $field_group_id ) { 206 | if ( xprofile_delete_field_group( $field_group_id ) ) { 207 | return [ 'success', sprintf( 'Field group deleted %d.', $field_group_id ) ]; 208 | } 209 | 210 | return [ 'error', sprintf( 'Could not delete the field group %d.', $field_group_id ) ]; 211 | } 212 | ); 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /src/xprofile.php: -------------------------------------------------------------------------------- 1 | __NAMESPACE__ . '\\Command\\Scaffold::check_dependencies' ] 48 | ); 49 | } 50 | 51 | WP_CLI::add_command( 52 | 'bp', 53 | __NAMESPACE__ . '\\Command\\BuddyPress', 54 | [ 'before_invoke' => __NAMESPACE__ . '\\Command\\BuddyPress::check_dependencies' ] 55 | ); 56 | 57 | WP_CLI::add_command( 58 | 'bp signup', 59 | __NAMESPACE__ . '\\Command\\Signup', 60 | [ 'before_invoke' => __NAMESPACE__ . '\\Command\\Signup::check_dependencies' ] 61 | ); 62 | 63 | WP_CLI::add_command( 64 | 'bp tool', 65 | __NAMESPACE__ . '\\Command\\Tool', 66 | [ 'before_invoke' => __NAMESPACE__ . '\\Command\\Tool::check_dependencies' ] 67 | ); 68 | 69 | WP_CLI::add_command( 70 | 'bp notification', 71 | __NAMESPACE__ . '\\Command\\Notification', 72 | [ 'before_invoke' => __NAMESPACE__ . '\\Command\\Notification::check_dependencies' ] 73 | ); 74 | 75 | WP_CLI::add_command( 76 | 'bp email', 77 | __NAMESPACE__ . '\\Command\\Email', 78 | [ 'before_invoke' => __NAMESPACE__ . '\\Command\\Email::check_dependencies' ] 79 | ); 80 | 81 | WP_CLI::add_command( 82 | 'bp member', 83 | __NAMESPACE__ . '\\Command\\Member', 84 | [ 'before_invoke' => __NAMESPACE__ . '\\Command\\Member::check_dependencies' ] 85 | ); 86 | 87 | WP_CLI::add_command( 88 | 'bp message', 89 | __NAMESPACE__ . '\\Command\\Messages', 90 | [ 'before_invoke' => __NAMESPACE__ . '\\Command\\Messages::check_dependencies' ] 91 | ); 92 | 93 | WP_CLI::add_command( 94 | 'bp component', 95 | __NAMESPACE__ . '\\Command\\Components', 96 | [ 'before_invoke' => __NAMESPACE__ . '\\Command\\Components::check_dependencies' ] 97 | ); 98 | 99 | WP_CLI::add_command( 100 | 'bp friend', 101 | __NAMESPACE__ . '\\Command\\Friends', 102 | [ 'before_invoke' => __NAMESPACE__ . '\\Command\\Friends::check_dependencies' ] 103 | ); 104 | 105 | WP_CLI::add_command( 106 | 'bp activity', 107 | __NAMESPACE__ . '\\Command\\Activity', 108 | [ 'before_invoke' => __NAMESPACE__ . '\\Command\\Activity::check_dependencies' ] 109 | ); 110 | 111 | WP_CLI::add_command( 112 | 'bp activity favorite', 113 | __NAMESPACE__ . '\\Command\\Activity_Favorite', 114 | [ 'before_invoke' => __NAMESPACE__ . '\\Command\\Activity::check_dependencies' ] 115 | ); 116 | 117 | WP_CLI::add_command( 118 | 'bp activity meta', 119 | __NAMESPACE__ . '\\Command\\Activity_Meta', 120 | [ 'before_invoke' => __NAMESPACE__ . '\\Command\\Activity::check_dependencies' ] 121 | ); 122 | 123 | WP_CLI::add_command( 124 | 'bp group', 125 | __NAMESPACE__ . '\\Command\\Group', 126 | [ 'before_invoke' => __NAMESPACE__ . '\\Command\\Group::check_dependencies' ] 127 | ); 128 | 129 | WP_CLI::add_command( 130 | 'bp group member', 131 | __NAMESPACE__ . '\\Command\\Group_Member', 132 | [ 'before_invoke' => __NAMESPACE__ . '\\Command\\Group::check_dependencies' ] 133 | ); 134 | 135 | WP_CLI::add_command( 136 | 'bp group meta', 137 | __NAMESPACE__ . '\\Command\\Group_Meta', 138 | [ 'before_invoke' => __NAMESPACE__ . '\\Command\\Group::check_dependencies' ] 139 | ); 140 | 141 | WP_CLI::add_command( 142 | 'bp group invite', 143 | __NAMESPACE__ . '\\Command\\Group_Invite', 144 | [ 'before_invoke' => __NAMESPACE__ . '\\Command\\Group::check_dependencies' ] 145 | ); 146 | 147 | WP_CLI::add_command( 148 | 'bp notice', 149 | __NAMESPACE__ . '\\Command\\Sitewide_Notice', 150 | [ 'before_invoke' => __NAMESPACE__ . '\\Command\\Sitewide_Notice::check_dependencies' ] 151 | ); 152 | 153 | WP_CLI::add_command( 154 | 'bp xprofile', 155 | __NAMESPACE__ . '\\Command\\XProfile', 156 | [ 'before_invoke' => __NAMESPACE__ . '\\Command\\XProfile::check_dependencies' ] 157 | ); 158 | 159 | WP_CLI::add_command( 160 | 'bp xprofile group', 161 | __NAMESPACE__ . '\\Command\\XProfile_Group', 162 | [ 'before_invoke' => __NAMESPACE__ . '\\Command\\XProfile::check_dependencies' ] 163 | ); 164 | 165 | WP_CLI::add_command( 166 | 'bp xprofile field', 167 | __NAMESPACE__ . '\\Command\\XProfile_Field', 168 | [ 'before_invoke' => __NAMESPACE__ . '\\Command\\XProfile::check_dependencies' ] 169 | ); 170 | 171 | WP_CLI::add_command( 172 | 'bp xprofile data', 173 | __NAMESPACE__ . '\\Command\\XProfile_Data', 174 | [ 'before_invoke' => __NAMESPACE__ . '\\Command\\XProfile::check_dependencies' ] 175 | ); 176 | } 177 | ); 178 | -------------------------------------------------------------------------------- /wp-cli.yml: -------------------------------------------------------------------------------- 1 | require: 2 | - wp-cli-bp.php 3 | --------------------------------------------------------------------------------