Skip to content

Commit

Permalink
Cleanup typo ; integrate Cloud Storage with templates ; test remote r…
Browse files Browse the repository at this point in the history
…epo service GH and GL ; missing BB
  • Loading branch information
froger-me committed Nov 9, 2023
1 parent fa698a6 commit 602954f
Show file tree
Hide file tree
Showing 15 changed files with 352 additions and 210 deletions.
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Developer documentation:
## General Description

WP Update Plugin Server allows developers to provide updates for plugins and themes packages not hosted on wordpress.org, and possibly control the updates with the application of a license on the client packages. It is also useful to provide updates for plugins or themes not compliant with the GPLv2 (or later).
Packages may be either uploaded directly, or hosted in a remote repository, public or private. It supports Bitbucket, Github and Gitlab, as well as self-hosted installations of Gitlab.
Packages may be either uploaded directly, or hosted in a Remote Repository, public or private. It supports Bitbucket, Github and Gitlab, as well as self-hosted installations of Gitlab.

To install, clone this repository and copy the "wp-plugin-update-server" directory into your plugin folder.

Expand All @@ -43,10 +43,10 @@ This plugin adds the following major features to WordPress:

* **WP Update Plugin Server admin page:** to manage the list of packages and configure the plugin.
* **Package management:** to manage update packages, showing a listing with Package Name, Version, Type, File Name, Size, Last Modified and License Status ; includes bulk operations to delete, download and change the license status, and the ability to delete all the packages.
* **Add Packages:** Upload update packages from your local machine to the server, or download them to the server from a remote repository.
* **Add Packages:** Upload update packages from your local machine to the server, or download them to the server from a Remote Repository.
* **General settings:** for archive files download size, cache, and logs, with force clean.
* **Packages licensing:** Prevent plugins and themes installed on remote WordPress installation from being updated without a valid license. Licenses are generated automatically by default and the values are unguessable (it is recommended to keep the default). When checking the validity of licenses an extra license signature is also checked to prevent the use of a license on more than the configured allowed domains.
* **Packages remote source:** host the packages on a remote repository. WP Plugin Update Server acts as a proxy and checks for packages updates regulary and downloads them automatically when a new version is available. Supports Bitbucket, Github and Gitlab, as well as self-hosted installations of Gitlab.
* **Packages remote source:** host the packages on a Remote Repository. WP Plugin Update Server acts as a proxy and checks for packages updates regulary and downloads them automatically when a new version is available. Supports Bitbucket, Github and Gitlab, as well as self-hosted installations of Gitlab.

To connect their plugins or themes and WP Plugin Update Server, developers can find integration examples in `wp-plugin-update-server/integration-examples`:
* **Dummy Plugin:** a folder `dummy-plugin` with a simple, empty plugin that includes the necessary code in the `dummy-plugin.php` main plugin file and the necessary libraries in a `lib` folder.
Expand Down Expand Up @@ -109,7 +109,7 @@ This tab allows administrators to:
- Toggle between "Require License" and "Do not Require License" for a package when "Enable Package Licenses" is checked under the "License" tab
- Delete a package
- Apply bulk actions on the list of packages (download, delete, change license status of the package if licenses are enabled)
- Add a package (either by uploading it directly, or by priming it by pulling it from a configured remote repository)
- Add a package (either by uploading it directly, or by priming it by pulling it from a configured Remote Repository)

In addition, the following settings are available:

Expand All @@ -130,12 +130,12 @@ In addition, the following settings are available:

Name | Type | Description
------------------------------------- |:---------:|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Use remote repository service | checkbox | Enables this server to download plugins and themes from a remote repository before delivering updates.<br/>Supports Bitbucket, Github and Gitlab.<br/>If left unchecked, zip packages need to be manually uploaded to `wp-content/plugins/wp-plugin-update-server/packages`.<br/>**It affects all the packages delivered by this installation of WP Plugin Update Server if they have a corresponding repository in the remote repository service.**<br/>**Settings of the "Packages remote source" section will be saved only if this option is checked.**
Remote repository service URL | text | The URL of the remote repository service where packages are hosted.<br/>Must follow the following pattern: `https://repository-service.tld/username` where `https://repository-service.tld` may be a self-hosted instance of Gitlab.<br/>Each package repository URL must follow the following pattern: `https://repository-service.tld/username/package-name/` ; the package files must be located at the root of the repository, and in the case of plugins the main plugin file must follow the pattern `package-name.php`.
Self-hosted remote repository service | checkbox | Check this only if the remote repository service is a self-hosted instance of Gitlab.
Packages branch name | text | The branch to download when getting remote packages from the remote repository service.
Remote repository service credentials | text | Credentials for non-publicly accessible repositories.<br/>In the case of Github and Gitlab, an access token (`token`).<br/>In the case of Bitbucket, the Consumer key and secret separated by a pipe (`consumer_key|consumer_secret`). IMPORTANT: when creating the consumer, "This is a private consumer" must be checked.
Remote update check frequency | select | How often WP Plugin Update Server will poll each remote repository for package updates - checking too often may slow down the server (recommended "Once Daily").
Use Remote Repository Service | checkbox | Enables this server to download plugins and themes from a Remote Repository before delivering updates.<br/>Supports Bitbucket, Github and Gitlab.<br/>If left unchecked, zip packages need to be manually uploaded to `wp-content/plugins/wp-plugin-update-server/packages`.<br/>**It affects all the packages delivered by this installation of WP Plugin Update Server if they have a corresponding repository in the Remote Repository Service.**<br/>**Settings of the "Packages remote source" section will be saved only if this option is checked.**
Remote Repository Service URL | text | The URL of the Remote Repository Service where packages are hosted.<br/>Must follow the following pattern: `https://repository-service.tld/username` where `https://repository-service.tld` may be a self-hosted instance of Gitlab.<br/>Each package repository URL must follow the following pattern: `https://repository-service.tld/username/package-name/` ; the package files must be located at the root of the repository, and in the case of plugins the main plugin file must follow the pattern `package-name.php`.
Self-hosted Remote Repository Service | checkbox | Check this only if the Remote Repository Service is a self-hosted instance of Gitlab.
Packages branch name | text | The branch to download when getting remote packages from the Remote Repository Service.
Remote Repository Service credentials | text | Credentials for non-publicly accessible repositories.<br/>In the case of Github and Gitlab, an access token (`token`).<br/>In the case of Bitbucket, the Consumer key and secret separated by a pipe (`consumer_key|consumer_secret`). IMPORTANT: when creating the consumer, "This is a private consumer" must be checked.
Remote update check frequency | select | How often WP Plugin Update Server will poll each Remote Repository for package updates - checking too often may slow down the server (recommended "Once Daily").

### Licenses Tab

Expand Down Expand Up @@ -286,7 +286,7 @@ To link your packages to WP Plugin Update Server, and maybe to prevent webmaster

See `wp-content/plugins/wp-plugin-update-server/integration-examples/dummy-plugin` for an example of plugin, and `wp-content/plugins/wp-plugin-update-server/integration-examples/dummy-theme` for an example of theme. They are fully functionnal and can be used to test all the features of the server with a test client installation of WordPress.

Unless "Use remote repository service" is checked in "Remote Sources", you need to manually upload the packages zip archives (and subsequent updates) in `wp-content/wppus/packages`. Packages need to be valid WordPress plugin or theme packages, and in the case of a plugin the main plugin file must have the same name as the zip archive. For example, the main plugin file in `package-name.zip` would be `package-name.php`.
Unless "Use Remote Repository Service" is checked in "Remote Sources", you need to manually upload the packages zip archives (and subsequent updates) in `wp-content/wppus/packages`. Packages need to be valid WordPress plugin or theme packages, and in the case of a plugin the main plugin file must have the same name as the zip archive. For example, the main plugin file in `package-name.zip` would be `package-name.php`.

### Requests optimisation

Expand Down
2 changes: 1 addition & 1 deletion inc/class-wp-plugin-update-server.php
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ public function admin_enqueue_scripts( $hook ) {
);

if ( get_option( 'wppus_use_remote_repository' ) ) {
$l10n['deletePackagesConfirm'] = __( "You are about to delete all the packages from this server.\nPackages with a remote repository will be added again automatically whenever a client asks for updates.\nAll packages manually uploaded without counterpart in a remote repository will be permanently deleted.\nLicense status will need to be re-applied manually for all packages.\n\nAre you sure you want to do this?", 'wppus' );
$l10n['deletePackagesConfirm'] = __( "You are about to delete all the packages from this server.\nPackages with a Remote Repository will be added again automatically whenever a client asks for updates.\nAll packages manually uploaded without counterpart in a Remote Repository will be permanently deleted.\nLicense status will need to be re-applied manually for all packages.\n\nAre you sure you want to do this?", 'wppus' );
} else {
$l10n['deletePackagesConfirm'] = __( "You are about to delete all the packages from this server.\nAll packages will be permanently deleted.\nLicense status will need to be re-applied manually for all packages.\n\nAre you sure you want to do this?", 'wppus' );
}
Expand Down
15 changes: 13 additions & 2 deletions inc/class-wppus-cloud-storage-manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public function __construct( $init_hooks = false ) {
add_filter( 'wppus_scheduler_get_package_slugs', array( $this, 'wppus_scheduler_get_package_slugs' ), 10, 4 );
add_filter( 'wppus_delete_package_result', array( $this, 'wppus_delete_package_result' ), 10, 3 );
add_filter( 'wppus_delete_packages_bulk_paths', array( $this, 'wppus_delete_packages_bulk_paths' ), 10, 1 );
add_filter( 'wppus_get_admin_template_args', array( $this, 'wppus_get_admin_template_args' ), 10, 2 );
}
}
}
Expand Down Expand Up @@ -249,6 +250,16 @@ public function wppus_delete_package_result( $result, $type, $slug ) {
return $result;
}

public function wppus_get_admin_template_args( $args, $template_name ) {
$template_names = array( 'plugin-main-page.php', 'plugin-help-page.php', 'plugin-remote-sources-page.php' );

if ( in_array( $template_name, $template_names, true ) ) {
$args['packages_dir'] = 'CloudStorageUnit://wppus-packages/';
}

return $args;
}

public function cloud_storage_test() {
$result = array();

Expand All @@ -275,7 +286,7 @@ public function cloud_storage_test() {
__( 'Error - Storage Unit not found', 'wppus' )
);
} else {
$result[] = __( 'Cloud Storage service was reached sucessfully.', 'wppus' );
$result[] = __( 'Cloud Storage Service was reached sucessfully.', 'wppus' );

if ( ! $this->virtual_folder_exists( 'wppus-packages' ) ) {
$created = $this->create_virtual_folder( 'wppus-packages' );
Expand Down Expand Up @@ -305,7 +316,7 @@ public function cloud_storage_test() {
);

$result->add( __METHOD__ . ' => LF', '' );
$result->add( __METHOD__, __( 'An error occured when attempting to communicate with the Cloud Storage service provider. Please check all the settings and try again.', 'wppus' ) );
$result->add( __METHOD__, __( 'An error occured when attempting to communicate with the Cloud Storage Service. Please check all the settings and try again.', 'wppus' ) );
}
} else {
$result = new WP_Error(
Expand Down
124 changes: 118 additions & 6 deletions inc/class-wppus-remote-sources-manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public function __construct( $init_hooks = false ) {

add_action( 'wp_ajax_wppus_force_clean', array( $this, 'force_clean' ), 10, 0 );
add_action( 'wp_ajax_wppus_force_register', array( $this, 'force_register' ), 10, 0 );
add_action( 'wp_ajax_wppus_remote_repository_test', array( $this, 'remote_repository_test' ), 10, 0 );
add_action( 'admin_menu', array( $this, 'plugin_options_menu' ), 11, 0 );
}
}
Expand Down Expand Up @@ -81,6 +82,7 @@ public function plugin_packages_remote_source_page() {
'wppus_use_recurring_schedule',
true
),
'packages_dir' => WPPUS_Data_Manager::get_data_dir( 'packages' ),
)
);
}
Expand Down Expand Up @@ -140,6 +142,116 @@ public function force_clean() {
}
}

public function remote_repository_test() {
$result = array();

if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], 'wppus_plugin_options' ) ) {
$data = filter_input( INPUT_POST, 'data', FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_REQUIRE_ARRAY );

if ( $data ) {
$url = $data['wppus_remote_repository_url'];
$self_hosted = $data['wppus_remote_repository_self_hosted'];
$credentials = $data['wppus_remote_repository_credentials'];
$options = array();
$service = false;
$host = wp_parse_url( $url, PHP_URL_HOST );
$path = wp_parse_url( $url, PHP_URL_PATH );
$user_name = false;

if ( 'true' === $self_hosted ) {
$service = 'GitLab';
} else {
$services = array(
'github.com' => 'GitHub',
'bitbucket.org' => 'BitBucket',
'gitlab.com' => 'GitLab',
);

if ( isset( $services[ $host ] ) ) {
$service = $services[ $host ];
}
}

if ( preg_match( '@^/?(?P<username>[^/]+?)/?$@', $path, $matches ) ) {
$user_name = $matches['username'];

if ( 'GitHub' === $service ) {
$url = 'https://api.github.com/user';
$options = array( 'timeout' => 3 );
$options['headers'] = array(
'Authorization' => 'Basic '
. base64_encode( $user_name . ':' . $credentials ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
);
}

if ( 'GitLab' === $service ) {
$options = array( 'timeout' => 3 );
$scheme = wp_parse_url( $url, PHP_URL_SCHEME );
$url = sprintf(
'%1$s://%2$s/api/v4/groups/%3$s/?private_token=%4$s',
$scheme,
$host,
$user_name,
$credentials
);
}
}

$response = wp_remote_get( $url, $options );

if ( is_wp_error( $response ) ) {
$result = $response;
} else {
$code = wp_remote_retrieve_response_code( $response );
$body = wp_remote_retrieve_body( $response );

if ( 200 === $code ) {
$condition = false;

if ( 'GitHub' === $service ) {
$body = json_decode( $body, true );
$condition = trailingslashit(
$data['wppus_remote_repository_url']
) === trailingslashit(
$body['html_url']
);
}

if ( 'GitLab' === $service ) {
$body = json_decode( $body, true );
$condition = $user_name === $body['path'];
}

if ( $condition ) {
$result[] = __( 'Remote Repository Service was reached sucessfully.', 'wppus' );
} else {
$result = new WP_Error(
__METHOD__,
__( 'Error - Please check the provided Remote Repository Service URL.', 'wppus' )
);
}
} else {
$result = new WP_Error(
__METHOD__,
__( 'Error - Please check the provided Remote Repository Service Credentials.', 'wppus' )
);
}
}
} else {
$result = new WP_Error(
__METHOD__,
__( 'Error - Received invalid data ; please reload the page and try again.', 'wppus' )
);
}
}

if ( ! is_wp_error( $result ) ) {
wp_send_json_success( $result );
} else {
wp_send_json_error( $result );
}
}

protected function plugin_options_handler() {
$errors = array();
$result = '';
Expand Down Expand Up @@ -291,34 +403,34 @@ protected function get_submitted_options() {
array(
'wppus_use_remote_repository' => array(
'value' => filter_input( INPUT_POST, 'wppus_use_remote_repository', FILTER_VALIDATE_BOOLEAN ),
'display_name' => __( 'Use remote repository service', 'wppus' ),
'display_name' => __( 'Use a Remote Repository Service', 'wppus' ),
'condition' => 'boolean',
),
'wppus_remote_repository_url' => array(
'value' => filter_input( INPUT_POST, 'wppus_remote_repository_url', FILTER_VALIDATE_URL ),
'display_name' => __( 'Remote repository service URL', 'wppus' ),
'display_name' => __( 'Remote Repository Service URL', 'wppus' ),
'failure_display_message' => __( 'Not a valid URL', 'wppus' ),
'dependency' => 'wppus_use_remote_repository',
'condition' => 'service_url',
),
'wppus_remote_repository_self_hosted' => array(
'value' => filter_input( INPUT_POST, 'wppus_remote_repository_self_hosted', FILTER_VALIDATE_BOOLEAN ),
'display_name' => __( 'Self-hosted remote repository service', 'wppus' ),
'display_name' => __( 'Self-hosted Remote Repository Service', 'wppus' ),
'condition' => 'boolean',
),
'wppus_remote_repository_branch' => array(
'value' => filter_input( INPUT_POST, 'wppus_remote_repository_branch', FILTER_SANITIZE_FULL_SPECIAL_CHARS ),
'display_name' => __( 'Packages branch name', 'wppus' ),
'display_name' => __( 'Packages Branch Name', 'wppus' ),
'failure_display_message' => __( 'Not a valid string', 'wppus' ),
),
'wppus_remote_repository_credentials' => array(
'value' => filter_input( INPUT_POST, 'wppus_remote_repository_credentials', FILTER_SANITIZE_FULL_SPECIAL_CHARS ),
'display_name' => __( 'Remote repository service credentials', 'wppus' ),
'display_name' => __( 'Remote Repository Service Credentials', 'wppus' ),
'failure_display_message' => __( 'Not a valid string', 'wppus' ),
),
'wppus_remote_repository_check_frequency' => array(
'value' => filter_input( INPUT_POST, 'wppus_remote_repository_check_frequency', FILTER_SANITIZE_FULL_SPECIAL_CHARS ),
'display_name' => __( 'Remote update check frequency', 'wppus' ),
'display_name' => __( 'Remote Update Check Frequency', 'wppus' ),
'failure_display_message' => __( 'Not a valid option', 'wppus' ),
'condition' => 'known frequency',
),
Expand Down
Loading

0 comments on commit 602954f

Please sign in to comment.