Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Admin settings #284

Merged
merged 12 commits into from
Sep 11, 2023
Merged
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ includes/vendor/bin
includes/vendor/dealerdirect
includes/vendor/squizlabs
includes/vendor/wp-coding-standards
admin/ui/node_modules
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ So, to use the **wp-api-jwt-auth** you need to install and activate [WP REST API

### PHP

**Minimum PHP version: 5.3.0**
**Minimum PHP version: 7.4.0**

### Enable PHP HTTP Authorization Header

Expand Down
172 changes: 172 additions & 0 deletions admin/class-jwt-auth-admin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
<?php

/**
* The admin-facing functionality of the plugin.
*
* Defines the plugin name, version
*
* @author Enrique Chavez <[email protected]>
* @since 1.3.4
*/
class Jwt_Auth_Admin {
/**
* The ID of this plugin.
*
* @since 1.3.4
*
* @var string The ID of this plugin.
*/
private string $plugin_name;

/**
* The version of this plugin.
*
* @since 1.3.4
*
* @var string The current version of this plugin.
*/
private string $version;

/**
* Initialize the class and set its properties.
*
* @param string $plugin_name The name of the plugin.
* @param string $version The version of this plugin.
*
* @since 1.3.4
*/
public function __construct( string $plugin_name, string $version ) {
$this->plugin_name = $plugin_name;
$this->version = $version;
}

/**
* Register a new settings page under Settings main menu
* .
* @return void
* @since 1.3.4
*/
public function register_menu_page() {
add_submenu_page(
'options-general.php',
__( 'JWT Authentication', 'jwt-auth' ),
__( 'JWT Authentication', 'jwt-auth' ),
'manage_options',
'jwt_authentication',
[ $this, 'render_admin_page' ]
);
}

/**
* Shows an admin notice on the admin dashboard to notify the new settings page.
* This is only shown once and the message is dismissed.
*
* @return void
* @since 1.3.4
*/
public function display_admin_notice() {
if ( ! get_option( 'jwt_auth_admin_notice' ) ) {
?>
<div class="notice notice-info is-dismissible">
<p>
<?php
printf(
/* translators: %s: Link to the JWT Authentication settings page */
__( 'Please visit the <a href="%s">JWT Authentication settings page</a> for an important message from the author.',
'jwt-auth' ),
admin_url( 'options-general.php?page=jwt_authentication' )
);
?>
</p>
</div>
<?php
update_option( 'jwt_auth_admin_notice', true );
}
}

/**
* Enqueue the plugin assets only on the plugin settings page.
*
* @param string $suffix
*
* @return void|null
* @since 1.3.4
*/
public function enqueue_plugin_assets( string $suffix ) {
if ( $suffix !== 'settings_page_jwt_authentication' ) {
return null;
}
// get full path to admin/ui/build/index.asset.php
$asset_file = plugin_dir_path( __FILE__ ) . 'ui/build/index.asset.php';

// If the asset file do not exist then just return false
if ( ! file_exists( $asset_file ) ) {
return null;
}

// Get the asset file
$asset = require_once $asset_file;
// Enqueue the script files based on the asset file
wp_enqueue_script(
$this->plugin_name . '-settings',
plugins_url( 'ui/build/index.js', __FILE__ ),
$asset['dependencies'],
$asset['version'],
[
'in_footer' => true,
]
);

// Enqueue the style file for the Gutenberg components
foreach ( $asset['dependencies'] as $style ) {
wp_enqueue_style( $style );
}

// Enqueue the style file
wp_enqueue_style(
$this->plugin_name . '-settings',
plugins_url( 'ui/build/index.css', __FILE__ ),
[],
$asset['version']
);
}

/**
* Register the plugin settings.
*
* @return void
* @since 1.3.4
*/
public function register_plugin_settings() {
register_setting( 'jwt_auth', 'jwt_auth_options', [
'type' => 'object',
'default' => [
'share_data' => false,
],
'show_in_rest' => [
'schema' => [
'type' => 'object',
'properties' => [
'share_data' => [
'type' => 'boolean',
'default' => false,
],
],
],
]
] );
}

/**
* Render the plugin settings page.
* This is a React application that will be rendered on the admin page.
*
* @return void
* @since 1.3.4
*/
public function render_admin_page() {
?>
<div id="jwt-auth-holder"></div>
<?php
}
}
94 changes: 94 additions & 0 deletions admin/class-jwt-auth-cron.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

/**
* Defines the CRON functionality of the plugin.
*
* @author Enrique Chavez <[email protected]>
* @since 1.3.4
*/
class Jwt_Auth_Cron {
public static string $remote_api_url = 'https://track.wpjwt.com';

/**
* If the user agrees to share data, then we will send some data.
*
* @return void|null
* @since 1.3.4
*/
static public function collect() {
// if the user doesn't agree to share data, then we don't do anything
if ( ! self::allow_shared_data() ) {
return null;
}

// get the PHP version
$php_version = phpversion();
// get the WP version
$wp_version = get_bloginfo( 'version' );
// get the list of activated plugins
$active_plugins = get_option( 'active_plugins' );
// get the number of activated plugins
$plugins_count = count( $active_plugins );
// is WooCommerce installed and activated?
$woocommerce_installed = in_array( 'woocommerce/woocommerce.php', $active_plugins );
// get the WooCommerce version
$woocommerce_version = $woocommerce_installed ? get_option( 'woocommerce_version' ) : null;
// get the site URL and hash it (we don't want to store the URL in plain text)
$site_url_hash = hash( 'sha256', get_site_url() );

$data = [
'php_version' => $php_version,
'wp_version' => $wp_version,
'plugins_count' => $plugins_count,
'woocommerce_version' => $woocommerce_version
];

// Wrap the request in a try/catch to avoid fatal errors
// and set the timeout to 5 seconds to avoid long delays
try {
$api_url = self::$remote_api_url . '/api/collect';
wp_remote_post( $api_url . '/' . $site_url_hash, [
'body' => $data,
'timeout' => 5,
] );
} catch ( Exception $e ) {
error_log( 'Error adding site to remote database' );
error_log( $e->getMessage() );
}
}

/**
* If the user agrees to share data, then we will remove the site from the remote database.
*
* @return void|null
* @since 1.3.4
*/
static public function remove() {
// First we remove the scheduled event
wp_clear_scheduled_hook( 'jwt_auth_share_data' );
// Then we remove the site from the remote database
$site_url_hash = hash( 'sha256', get_site_url() );
// Wrap the request in a try/catch to avoid fatal errors
// and set the timeout to 5 seconds to avoid long delays
try {
$api_url = self::$remote_api_url . '/api/destroy';
wp_remote_post( $api_url . '/' . $site_url_hash, [
'timeout' => 5,
] );
} catch ( Exception $e ) {
error_log( 'Error removing site from remote database' );
error_log( $e->getMessage() );
}
}

/**
* Check if the user agrees to share data.
* @return bool
* @since 1.3.4
*/
static public function allow_shared_data(): bool {
$jwt_auth_options = get_option( 'jwt_auth_options' );

return ( isset( $jwt_auth_options['share_data'] ) && $jwt_auth_options['share_data'] );
}
}
1 change: 1 addition & 0 deletions admin/ui/build/index.asset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<?php return array('dependencies' => array('wp-components', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n'), 'version' => '37282c45b1ae8f115602');
1 change: 1 addition & 0 deletions admin/ui/build/index.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions admin/ui/build/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions admin/ui/nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v18.16.1
28 changes: 28 additions & 0 deletions admin/ui/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "jwt-auth-admin-ui",
"version": "1.0.0",
"main": "build/index.js",
"license": "GPL-2.0-or-later",
"author": "Enrique Chavez",
"scripts": {
"build": "wp-scripts build",
"start": "wp-scripts start",
"format": "wp-scripts format",
"lint:js": "wp-scripts lint-js",
"lint:js:fix": "wp-scripts lint-js --fix",
"lint:css": "wp-scripts lint-css",
"lint:css:fix": "wp-scripts lint-css --fix",
"packages-update": "wp-scripts packages-update"
},
"devDependencies": {
"@wordpress/scripts": "^26.12.0"
},
"dependencies": {
"@wordpress/api-fetch": "^6.38.0",
"@wordpress/components": "^25.7.0",
"@wordpress/core-data": "^6.18.0",
"@wordpress/data": "^9.11.0",
"@wordpress/element": "^5.18.0",
"@wordpress/i18n": "^4.41.0"
}
}
52 changes: 52 additions & 0 deletions admin/ui/src/components/cta.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { __ } from '@wordpress/i18n';
import Newsletter from './newsletter';

const CTA = () => {
return (
<div className={ `jwt-auth-cta` }>
<div className={ `jwt-auth-box` }>
<h3>{ __( `Need Priority Support?`, 'jwt-auth' ) }</h3>
<p>
{ __( `Hello! I'm`, 'jwt-auth' ) }{ ' ' }
<a href="https://76.digital/" target="_blank">
Enrique Chavez
</a>
,{ ' ' }
{ __(
`a freelance WordPress developer. I've been working with WordPress for over 10 years.`,
'jwt-auth'
) }
</p>
<p>
{ __(
`If you need priority support, I'm available for hire. I can help you troubleshoot any issues you're having with the plugin, or even build a custom solution for your project.`,
'jwt-auth'
) }
</p>
<p>
{ __(
`Get in touch with me clicking the button below or you can hire me directly on`,
'jwt-auth'
) }{ ' ' }
<a href="https://76.digital/codeable" target="_blank">
Codeable.
</a>
</p>
<div className={ `jwt-auth-cta-wrapper` }>
<a
href="https://76.digital/contact/"
target="_blank"
className={ `jwt-auth-cta-button` }
>
{ __( `Get in touch`, 'jwt-auth' ) }
</a>
</div>
</div>
<div className={ `jwt-auth-box jwt-auth-newsletter` }>
<Newsletter />
</div>
</div>
);
};

export default CTA;
Loading