Update API
This commit is contained in:
272
inc/api/class-opalestate-admin-api-keys-table-list.php
Normal file
272
inc/api/class-opalestate-admin-api-keys-table-list.php
Normal file
@@ -0,0 +1,272 @@
|
||||
<?php
|
||||
/**
|
||||
* Opalestate API Keys Table List
|
||||
*
|
||||
* @package Opalestate\Admin
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'WP_List_Table' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* API Keys table list class.
|
||||
*/
|
||||
class Opalestate_Admin_API_Keys_Table_List extends WP_List_Table {
|
||||
|
||||
/**
|
||||
* Initialize the API key table list.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct(
|
||||
[
|
||||
'singular' => 'key',
|
||||
'plural' => 'keys',
|
||||
'ajax' => false,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* No items found text.
|
||||
*/
|
||||
public function no_items() {
|
||||
esc_html_e( 'No keys found.', 'opalestate-pro' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list columns.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_columns() {
|
||||
return [
|
||||
'cb' => '<input type="checkbox" />',
|
||||
'title' => __( 'Description', 'opalestate-pro' ),
|
||||
'truncated_key' => __( 'Consumer key ending in', 'opalestate-pro' ),
|
||||
'user' => __( 'User', 'opalestate-pro' ),
|
||||
'permissions' => __( 'Permissions', 'opalestate-pro' ),
|
||||
'last_access' => __( 'Last access', 'opalestate-pro' ),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Column cb.
|
||||
*
|
||||
* @param array $key Key data.
|
||||
* @return string
|
||||
*/
|
||||
public function column_cb( $key ) {
|
||||
return sprintf( '<input type="checkbox" name="key[]" value="%1$s" />', $key['key_id'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return title column.
|
||||
*
|
||||
* @param array $key Key data.
|
||||
* @return string
|
||||
*/
|
||||
public function column_title( $key ) {
|
||||
$url = admin_url( 'edit.php?post_type=opalestate_property&page=opalestate-settings&tab=api_keys&edit-key=' . $key['key_id'] );
|
||||
$user_id = absint( $key['user_id'] );
|
||||
|
||||
// Check if current user can edit other users or if it's the same user.
|
||||
$can_edit = current_user_can( 'edit_user', $user_id ) || get_current_user_id() === $user_id;
|
||||
|
||||
$output = '<strong>';
|
||||
if ( $can_edit ) {
|
||||
$output .= '<a href="' . esc_url( $url ) . '" class="row-title">';
|
||||
}
|
||||
if ( empty( $key['description'] ) ) {
|
||||
$output .= esc_html__( 'API key', 'opalestate-pro' );
|
||||
} else {
|
||||
$output .= esc_html( $key['description'] );
|
||||
}
|
||||
if ( $can_edit ) {
|
||||
$output .= '</a>';
|
||||
}
|
||||
$output .= '</strong>';
|
||||
|
||||
// Get actions.
|
||||
$actions = [
|
||||
/* translators: %s: API key ID. */
|
||||
'id' => sprintf( __( 'ID: %d', 'opalestate-pro' ), $key['key_id'] ),
|
||||
];
|
||||
|
||||
if ( $can_edit ) {
|
||||
$actions['edit'] = '<a href="' . esc_url( $url ) . '">' . __( 'View/Edit', 'opalestate-pro' ) . '</a>';
|
||||
$actions['trash'] = '<a class="submitdelete" aria-label="' . esc_attr__( 'Revoke API key', 'opalestate-pro' ) . '" href="' . esc_url(
|
||||
wp_nonce_url(
|
||||
add_query_arg(
|
||||
[
|
||||
'revoke-key' => $key['key_id'],
|
||||
], admin_url( 'edit.php?post_type=opalestate_property&page=opalestate-settings&tab=api_keys' )
|
||||
), 'revoke'
|
||||
)
|
||||
) . '">' . esc_html__( 'Revoke', 'opalestate-pro' ) . '</a>';
|
||||
}
|
||||
|
||||
$row_actions = [];
|
||||
|
||||
foreach ( $actions as $action => $link ) {
|
||||
$row_actions[] = '<span class="' . esc_attr( $action ) . '">' . $link . '</span>';
|
||||
}
|
||||
|
||||
$output .= '<div class="row-actions">' . implode( ' | ', $row_actions ) . '</div>';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return truncated consumer key column.
|
||||
*
|
||||
* @param array $key Key data.
|
||||
* @return string
|
||||
*/
|
||||
public function column_truncated_key( $key ) {
|
||||
return '<code>…' . esc_html( $key['truncated_key'] ) . '</code>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return user column.
|
||||
*
|
||||
* @param array $key Key data.
|
||||
* @return string
|
||||
*/
|
||||
public function column_user( $key ) {
|
||||
$user = get_user_by( 'id', $key['user_id'] );
|
||||
|
||||
if ( ! $user ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( current_user_can( 'edit_user', $user->ID ) ) {
|
||||
return '<a href="' . esc_url( add_query_arg( [ 'user_id' => $user->ID ], admin_url( 'user-edit.php' ) ) ) . '">' . esc_html( $user->display_name ) . '</a>';
|
||||
}
|
||||
|
||||
return esc_html( $user->display_name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return permissions column.
|
||||
*
|
||||
* @param array $key Key data.
|
||||
* @return string
|
||||
*/
|
||||
public function column_permissions( $key ) {
|
||||
$permission_key = $key['permissions'];
|
||||
$permissions = [
|
||||
'read' => __( 'Read', 'opalestate-pro' ),
|
||||
'write' => __( 'Write', 'opalestate-pro' ),
|
||||
'read_write' => __( 'Read/Write', 'opalestate-pro' ),
|
||||
];
|
||||
|
||||
if ( isset( $permissions[ $permission_key ] ) ) {
|
||||
return esc_html( $permissions[ $permission_key ] );
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return last access column.
|
||||
*
|
||||
* @param array $key Key data.
|
||||
* @return string
|
||||
*/
|
||||
public function column_last_access( $key ) {
|
||||
if ( ! empty( $key['last_access'] ) ) {
|
||||
/* translators: 1: last access date 2: last access time */
|
||||
$date = sprintf( __( '%1$s at %2$s', 'opalestate-pro' ), date_i18n( wc_date_format(), strtotime( $key['last_access'] ) ),
|
||||
date_i18n( get_option( 'time_format' ), strtotime( $key['last_access'] ) ) );
|
||||
|
||||
return apply_filters( 'opalestate_api_key_last_access_datetime', $date, $key['last_access'] );
|
||||
}
|
||||
|
||||
return __( 'Unknown', 'opalestate-pro' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get bulk actions.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_bulk_actions() {
|
||||
if ( ! current_user_can( 'remove_users' ) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
'revoke' => __( 'Revoke', 'opalestate-pro' ),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Search box.
|
||||
*
|
||||
* @param string $text Button text.
|
||||
* @param string $input_id Input ID.
|
||||
*/
|
||||
public function search_box( $text, $input_id ) {
|
||||
if ( empty( $_REQUEST['s'] ) && ! $this->has_items() ) { // WPCS: input var okay, CSRF ok.
|
||||
return;
|
||||
}
|
||||
|
||||
$input_id = $input_id . '-search-input';
|
||||
$search_query = isset( $_REQUEST['s'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['s'] ) ) : ''; // WPCS: input var okay, CSRF ok.
|
||||
|
||||
echo '<p class="search-box">';
|
||||
echo '<label class="screen-reader-text" for="' . esc_attr( $input_id ) . '">' . esc_html( $text ) . ':</label>';
|
||||
echo '<input type="search" id="' . esc_attr( $input_id ) . '" name="s" value="' . esc_attr( $search_query ) . '" />';
|
||||
submit_button(
|
||||
$text, '', '', false,
|
||||
[
|
||||
'id' => 'search-submit',
|
||||
]
|
||||
);
|
||||
echo '</p>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare table list items.
|
||||
*/
|
||||
public function prepare_items() {
|
||||
global $wpdb;
|
||||
|
||||
$per_page = $this->get_items_per_page( 'opalestate_keys_per_page' );
|
||||
$current_page = $this->get_pagenum();
|
||||
|
||||
if ( 1 < $current_page ) {
|
||||
$offset = $per_page * ( $current_page - 1 );
|
||||
} else {
|
||||
$offset = 0;
|
||||
}
|
||||
|
||||
$search = '';
|
||||
|
||||
if ( ! empty( $_REQUEST['s'] ) ) { // WPCS: input var okay, CSRF ok.
|
||||
$search = "AND description LIKE '%" . esc_sql( $wpdb->esc_like( opalestate_clean( wp_unslash( $_REQUEST['s'] ) ) ) ) . "%' "; // WPCS: input var okay, CSRF ok.
|
||||
}
|
||||
|
||||
// Get the API keys.
|
||||
$keys = $wpdb->get_results(
|
||||
"SELECT key_id, user_id, description, permissions, truncated_key, last_access FROM {$wpdb->prefix}opalestate_api_keys WHERE 1 = 1 {$search}" .
|
||||
$wpdb->prepare( 'ORDER BY key_id DESC LIMIT %d OFFSET %d;', $per_page, $offset ), ARRAY_A
|
||||
); // WPCS: unprepared SQL ok.
|
||||
|
||||
$count = $wpdb->get_var( "SELECT COUNT(key_id) FROM {$wpdb->prefix}opalestate_api_keys WHERE 1 = 1 {$search};" ); // WPCS: unprepared SQL ok.
|
||||
|
||||
$this->items = $keys;
|
||||
|
||||
// Set the pagination.
|
||||
$this->set_pagination_args(
|
||||
[
|
||||
'total_items' => $count,
|
||||
'per_page' => $per_page,
|
||||
'total_pages' => ceil( $count / $per_page ),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
290
inc/api/class-opalestate-admin-api-keys.php
Normal file
290
inc/api/class-opalestate-admin-api-keys.php
Normal file
@@ -0,0 +1,290 @@
|
||||
<?php
|
||||
/**
|
||||
* Opalestate Admin API Keys Class
|
||||
*
|
||||
* @package Opalestate\API
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Opalestate_Admin_API_Keys.
|
||||
*/
|
||||
class Opalestate_Admin_API_Keys {
|
||||
|
||||
/**
|
||||
* Initialize the API Keys admin actions.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'admin_init', [ $this, 'actions' ] );
|
||||
add_action( 'load-opalestate_property_page_opalestate-settings', [ $this, 'screen_option' ] );
|
||||
add_action( 'cmb2_render_api_keys', [ $this, 'page_output' ] );
|
||||
add_filter( 'opalestate_save_settings_advanced_keys', [ $this, 'allow_save_settings' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if should allow save settings.
|
||||
* This prevents "Your settings have been saved." notices on the table list.
|
||||
*
|
||||
* @param bool $allow If allow save settings.
|
||||
* @return bool
|
||||
*/
|
||||
public function allow_save_settings( $allow ) {
|
||||
if ( ! isset( $_GET['create-key'], $_GET['edit-key'] ) ) { // WPCS: input var okay, CSRF ok.
|
||||
return false;
|
||||
}
|
||||
|
||||
return $allow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if is API Keys settings page.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_api_keys_settings_page() {
|
||||
return isset( $_GET['page'], $_GET['tab'] ) && 'opalestate-settings' === $_GET['page'] && 'api_keys' === $_GET['tab']; // WPCS: input var okay, CSRF ok.
|
||||
}
|
||||
|
||||
/**
|
||||
* Page output.
|
||||
*/
|
||||
public static function page_output() {
|
||||
if ( isset( $_GET['create-key'] ) || isset( $_GET['edit-key'] ) ) {
|
||||
$key_id = isset( $_GET['edit-key'] ) ? absint( $_GET['edit-key'] ) : 0; // WPCS: input var okay, CSRF ok.
|
||||
$key_data = static::get_key_data( $key_id );
|
||||
$user_id = absint( $key_data['user_id'] );
|
||||
|
||||
if ( $key_id && $user_id && ! current_user_can( 'edit_user', $user_id ) ) {
|
||||
if ( get_current_user_id() !== $user_id ) {
|
||||
wp_die( esc_html__( 'You do not have permission to edit this API Key', 'opalestate-pro' ) );
|
||||
}
|
||||
}
|
||||
|
||||
include dirname( __FILE__ ) . '/html-keys-edit.php';
|
||||
} else {
|
||||
static::table_list_output();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add screen option.
|
||||
*/
|
||||
public function screen_option() {
|
||||
global $keys_table_list;
|
||||
|
||||
if ( ! isset( $_GET['create-key'] ) && ! isset( $_GET['edit-key'] ) && $this->is_api_keys_settings_page() ) { // WPCS: input var okay, CSRF ok.
|
||||
$keys_table_list = new Opalestate_Admin_API_Keys_Table_List();
|
||||
|
||||
// Add screen option.
|
||||
add_screen_option(
|
||||
'per_page', [
|
||||
'default' => 10,
|
||||
'option' => 'opalestate_keys_per_page',
|
||||
]
|
||||
);
|
||||
}
|
||||
?>
|
||||
<style>
|
||||
input[name="submit-cmb"] {
|
||||
display: none !important;
|
||||
}
|
||||
</style>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Table list output.
|
||||
*/
|
||||
private static function table_list_output() {
|
||||
global $wpdb, $keys_table_list;
|
||||
|
||||
echo '<h2>' . esc_html__( 'REST API',
|
||||
'opalestate-pro' ) . ' <a href="' . esc_url( admin_url( 'edit.php?post_type=opalestate_property&page=opalestate-settings&tab=api_keys&create-key=1' ) ) . '" class="add-new-h2">' .
|
||||
esc_html__( 'Add key', 'opalestate-pro' ) . '</a></h2>';
|
||||
|
||||
// Get the API keys count.
|
||||
$count = $wpdb->get_var( "SELECT COUNT(key_id) FROM {$wpdb->prefix}opalestate_api_keys WHERE 1 = 1;" );
|
||||
|
||||
if ( absint( $count ) && $count > 0 ) {
|
||||
$keys_table_list->prepare_items();
|
||||
|
||||
echo '<input type="hidden" name="page" value="wc-settings" />';
|
||||
echo '<input type="hidden" name="tab" value="advanced" />';
|
||||
echo '<input type="hidden" name="section" value="keys" />';
|
||||
|
||||
$keys_table_list->views();
|
||||
$keys_table_list->search_box( __( 'Search key', 'opalestate-pro' ), 'key' );
|
||||
$keys_table_list->display();
|
||||
} else {
|
||||
echo '<div class="opalestate-admin-api">';
|
||||
?>
|
||||
<h2 class="opalestate-admin-api-message">
|
||||
<?php printf(
|
||||
__( 'API keys allow users to use the <a href="%s">Opalestate REST API</a> to retrieve donation data in JSON or XML for external applications or devices, such as <a href="%s">Zapi_keyser</a>.',
|
||||
'opalestate-pro' ),
|
||||
'https://wpopal.com/opalestate/documentation/opalestate-api_keys-reference/',
|
||||
'https://wpopal.com/addons/opalestate/'
|
||||
); ?>
|
||||
</h2>
|
||||
|
||||
<a class="button-primary button" href="<?php echo esc_url( admin_url( 'edit.php?post_type=opalestate_property&page=opalestate-settings&tab=api_keys&create-key=1' ) ); ?>">
|
||||
<?php esc_html_e( 'Create an API key', 'opalestate-pro' ); ?>
|
||||
</a>
|
||||
<style type="text/css">#posts-filter .wp-list-table, #posts-filter .tablenav.top, .tablenav.bottom .actions {
|
||||
display: none;
|
||||
}</style>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get key data.
|
||||
*
|
||||
* @param int $key_id API Key ID.
|
||||
* @return array
|
||||
*/
|
||||
private static function get_key_data( $key_id ) {
|
||||
global $wpdb;
|
||||
|
||||
$empty = [
|
||||
'key_id' => 0,
|
||||
'user_id' => '',
|
||||
'description' => '',
|
||||
'permissions' => '',
|
||||
'truncated_key' => '',
|
||||
'last_access' => '',
|
||||
];
|
||||
|
||||
if ( 0 === $key_id ) {
|
||||
return $empty;
|
||||
}
|
||||
|
||||
$key = $wpdb->get_row(
|
||||
$wpdb->prepare(
|
||||
"SELECT key_id, user_id, description, permissions, truncated_key, last_access
|
||||
FROM {$wpdb->prefix}opalestate_api_keys
|
||||
WHERE key_id = %d",
|
||||
$key_id
|
||||
), ARRAY_A
|
||||
);
|
||||
|
||||
if ( is_null( $key ) ) {
|
||||
return $empty;
|
||||
}
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* API Keys admin actions.
|
||||
*/
|
||||
public function actions() {
|
||||
if ( $this->is_api_keys_settings_page() ) {
|
||||
// Revoke key.
|
||||
if ( isset( $_REQUEST['revoke-key'] ) ) { // WPCS: input var okay, CSRF ok.
|
||||
$this->revoke_key();
|
||||
}
|
||||
|
||||
// Bulk actions.
|
||||
if ( isset( $_REQUEST['action'] ) && isset( $_REQUEST['key'] ) ) { // WPCS: input var okay, CSRF ok.
|
||||
$this->bulk_actions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notices.
|
||||
*/
|
||||
public static function notices() {
|
||||
if ( isset( $_GET['revoked'] ) ) { // WPCS: input var okay, CSRF ok.
|
||||
$revoked = absint( $_GET['revoked'] ); // WPCS: input var okay, CSRF ok.
|
||||
|
||||
/* translators: %d: count */
|
||||
Opalestate_Admin_Settings::add_message( sprintf( _n( '%d API key permanently revoked.', '%d API keys permanently revoked.', $revoked, 'opalestate-pro' ), $revoked ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke key.
|
||||
*/
|
||||
private function revoke_key() {
|
||||
global $wpdb;
|
||||
|
||||
check_admin_referer( 'revoke' );
|
||||
|
||||
if ( isset( $_REQUEST['revoke-key'] ) ) { // WPCS: input var okay, CSRF ok.
|
||||
$key_id = absint( $_REQUEST['revoke-key'] ); // WPCS: input var okay, CSRF ok.
|
||||
$user_id = (int) $wpdb->get_var( $wpdb->prepare( "SELECT user_id FROM {$wpdb->prefix}opalestate_api_keys WHERE key_id = %d", $key_id ) );
|
||||
|
||||
if ( $key_id && $user_id && ( current_user_can( 'edit_user', $user_id ) || get_current_user_id() === $user_id ) ) {
|
||||
$this->remove_key( $key_id );
|
||||
} else {
|
||||
wp_die( esc_html__( 'You do not have permission to revoke this API Key', 'opalestate-pro' ) );
|
||||
}
|
||||
}
|
||||
|
||||
wp_safe_redirect( esc_url_raw( add_query_arg( [ 'revoked' => 1 ], admin_url( 'edit.php?post_type=opalestate_property&page=opalestate-settings&tab=api_keys' ) ) ) );
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk actions.
|
||||
*/
|
||||
private function bulk_actions() {
|
||||
check_admin_referer( 'opalestate-settings' );
|
||||
|
||||
if ( ! current_user_can( 'manage_opalestate' ) ) {
|
||||
wp_die( esc_html__( 'You do not have permission to edit API Keys', 'opalestate-pro' ) );
|
||||
}
|
||||
|
||||
if ( isset( $_REQUEST['action'] ) ) { // WPCS: input var okay, CSRF ok.
|
||||
$action = sanitize_text_field( wp_unslash( $_REQUEST['action'] ) ); // WPCS: input var okay, CSRF ok.
|
||||
$keys = isset( $_REQUEST['key'] ) ? array_map( 'absint', (array) $_REQUEST['key'] ) : []; // WPCS: input var okay, CSRF ok.
|
||||
|
||||
if ( 'revoke' === $action ) {
|
||||
$this->bulk_revoke_key( $keys );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk revoke key.
|
||||
*
|
||||
* @param array $keys API Keys.
|
||||
*/
|
||||
private function bulk_revoke_key( $keys ) {
|
||||
if ( ! current_user_can( 'remove_users' ) ) {
|
||||
wp_die( esc_html__( 'You do not have permission to revoke API Keys', 'opalestate-pro' ) );
|
||||
}
|
||||
|
||||
$qty = 0;
|
||||
foreach ( $keys as $key_id ) {
|
||||
$result = $this->remove_key( $key_id );
|
||||
|
||||
if ( $result ) {
|
||||
$qty++;
|
||||
}
|
||||
}
|
||||
|
||||
// Redirect to webhooks page.
|
||||
wp_safe_redirect( esc_url_raw( add_query_arg( [ 'revoked' => $qty ], admin_url( 'edit.php?post_type=opalestate_property&page=opalestate-settings&tab=api_keys' ) ) ) );
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove key.
|
||||
*
|
||||
* @param int $key_id API Key ID.
|
||||
* @return bool
|
||||
*/
|
||||
private function remove_key( $key_id ) {
|
||||
global $wpdb;
|
||||
|
||||
$delete = $wpdb->delete( $wpdb->prefix . 'opalestate_api_keys', [ 'key_id' => $key_id ], [ '%d' ] );
|
||||
|
||||
return $delete;
|
||||
}
|
||||
}
|
||||
|
||||
new Opalestate_Admin_API_Keys();
|
||||
@@ -40,6 +40,8 @@ class Opalestate_API {
|
||||
*/
|
||||
public function init() {
|
||||
$this->includes( [
|
||||
'class-opalestate-admin-api-keys.php',
|
||||
'class-opalestate-admin-api-keys-table-list.php',
|
||||
'class-opalestate-api-admin.php',
|
||||
'class-opalestate-base-api.php',
|
||||
'v1/property.php',
|
||||
@@ -102,4 +104,35 @@ class Opalestate_API {
|
||||
$api_class->register_routes();
|
||||
}
|
||||
}
|
||||
|
||||
public static function install() {
|
||||
try {
|
||||
if ( ! function_exists( 'dbDelta' ) ) {
|
||||
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$charset_collate = $wpdb->get_charset_collate();
|
||||
|
||||
$sql = 'CREATE TABLE IF NOT EXISTS ' . $wpdb->prefix . 'opalestate_api_keys' . ' (
|
||||
key_id BIGINT UNSIGNED NOT NULL auto_increment,
|
||||
user_id BIGINT UNSIGNED NOT NULL,
|
||||
description varchar(200) NULL,
|
||||
permissions varchar(10) NOT NULL,
|
||||
consumer_key char(64) NOT NULL,
|
||||
consumer_secret char(43) NOT NULL,
|
||||
nonces longtext NULL,
|
||||
truncated_key char(7) NOT NULL,
|
||||
last_access datetime NULL default null,
|
||||
PRIMARY KEY (key_id),
|
||||
KEY consumer_key (consumer_key),
|
||||
KEY consumer_secret (consumer_secret)
|
||||
) ' . $charset_collate;
|
||||
dbDelta( $sql );
|
||||
|
||||
} catch ( Exception $e ) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
152
inc/api/html-keys-edit.php
Normal file
152
inc/api/html-keys-edit.php
Normal file
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
/**
|
||||
* Admin view: Edit API keys
|
||||
*
|
||||
* @package Opalestate/API/Settings
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
?>
|
||||
|
||||
<div id="key-fields" class="settings-panel">
|
||||
<h2><?php esc_html_e( 'Key details', 'opalestate-pro' ); ?></h2>
|
||||
|
||||
<input type="hidden" id="key_id" value="<?php echo esc_attr( $key_id ); ?>" />
|
||||
|
||||
<table id="api-keys-options" class="form-table">
|
||||
<tbody>
|
||||
<tr valign="top">
|
||||
<th scope="row" class="titledesc">
|
||||
<label for="key_description">
|
||||
<?php esc_html_e( 'Description', 'opalestate-pro' ); ?>
|
||||
</label>
|
||||
</th>
|
||||
<td class="forminp">
|
||||
<input id="key_description" type="text" class="input-text regular-input" value="<?php echo esc_attr( $key_data['description'] ); ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row" class="titledesc">
|
||||
<label for="key_user">
|
||||
<?php esc_html_e( 'User', 'opalestate-pro' ); ?>
|
||||
</label>
|
||||
</th>
|
||||
<td class="forminp">
|
||||
<?php
|
||||
$curent_user_id = get_current_user_id();
|
||||
$user_id = ! empty( $key_data['user_id'] ) ? absint( $key_data['user_id'] ) : $curent_user_id;
|
||||
$user = get_user_by( 'id', $user_id );
|
||||
$user_string = sprintf(
|
||||
/* translators: 1: user display name 2: user ID 3: user email */
|
||||
esc_html__( '%1$s (#%2$s – %3$s)', 'opalestate-pro' ),
|
||||
$user->display_name,
|
||||
absint( $user->ID ),
|
||||
$user->user_email
|
||||
);
|
||||
?>
|
||||
<select class="opalestate-customer-search" id="key_user" data-placeholder="<?php esc_attr_e( 'Search for a user…', 'opalestate-pro' ); ?>" data-allow_clear="true">
|
||||
<option value="<?php echo esc_attr( $user_id ); ?>" selected="selected"><?php echo htmlspecialchars( wp_kses_post( $user_string ) ); // htmlspecialchars to prevent XSS when rendered by selectWoo. ?></option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row" class="titledesc">
|
||||
<label for="key_permissions">
|
||||
<?php esc_html_e( 'Permissions', 'opalestate-pro' ); ?>
|
||||
</label>
|
||||
</th>
|
||||
<td class="forminp">
|
||||
<select id="key_permissions" class="wc-enhanced-select">
|
||||
<?php
|
||||
$permissions = array(
|
||||
'read' => __( 'Read', 'opalestate-pro' ),
|
||||
'write' => __( 'Write', 'opalestate-pro' ),
|
||||
'read_write' => __( 'Read/Write', 'opalestate-pro' ),
|
||||
);
|
||||
|
||||
foreach ( $permissions as $permission_id => $permission_name ) :
|
||||
?>
|
||||
<option value="<?php echo esc_attr( $permission_id ); ?>" <?php selected( $key_data['permissions'], $permission_id, true ); ?>><?php echo esc_html( $permission_name ); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<?php if ( 0 !== $key_id ) : ?>
|
||||
<tr valign="top">
|
||||
<th scope="row" class="titledesc">
|
||||
<?php esc_html_e( 'Consumer key ending in', 'opalestate-pro' ); ?>
|
||||
</th>
|
||||
<td class="forminp">
|
||||
<code>…<?php echo esc_html( $key_data['truncated_key'] ); ?></code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row" class="titledesc">
|
||||
<?php esc_html_e( 'Last access', 'opalestate-pro' ); ?>
|
||||
</th>
|
||||
<td class="forminp">
|
||||
<span>
|
||||
<?php
|
||||
if ( ! empty( $key_data['last_access'] ) ) {
|
||||
/* translators: 1: last access date 2: last access time */
|
||||
$date = sprintf( __( '%1$s at %2$s', 'opalestate-pro' ), date_i18n( wc_date_format(), strtotime( $key_data['last_access'] ) ), date_i18n( wc_time_format(), strtotime(
|
||||
$key_data['last_access'] ) ) );
|
||||
|
||||
echo esc_html( apply_filters( 'opalestate_api_key_last_access_datetime', $date, $key_data['last_access'] ) );
|
||||
} else {
|
||||
esc_html_e( 'Unknown', 'opalestate-pro' );
|
||||
}
|
||||
?>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php do_action( 'opalestate_admin_key_fields', $key_data ); ?>
|
||||
|
||||
<?php
|
||||
if ( 0 === intval( $key_id ) ) {
|
||||
submit_button( __( 'Generate API key', 'opalestate-pro' ), 'primary', 'update_api_key' );
|
||||
} else {
|
||||
?>
|
||||
<p class="submit">
|
||||
<?php submit_button( __( 'Save changes', 'opalestate-pro' ), 'primary', 'update_api_key', false ); ?>
|
||||
<a style="color: #a00; text-decoration: none; margin-left: 10px;" href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'revoke-key' => $key_id ), admin_url( 'edit.php?post_type=opalestate_property&page=opalestate-settings&tab=api_keys' ) ), 'revoke' ) ); ?>">
|
||||
<?php esc_html_e( 'Revoke key', 'opalestate-pro' ); ?>
|
||||
</a>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
<script type="text/template" id="tmpl-api-keys-template">
|
||||
<p id="copy-error"></p>
|
||||
<table class="form-table">
|
||||
<tbody>
|
||||
<tr valign="top">
|
||||
<th scope="row" class="titledesc">
|
||||
<?php esc_html_e( 'Consumer key', 'opalestate-pro' ); ?>
|
||||
</th>
|
||||
<td class="forminp">
|
||||
<input id="key_consumer_key" type="text" value="{{ data.consumer_key }}" size="55" readonly="readonly"> <button type="button" class="button-secondary copy-key" data-tip="<?php
|
||||
esc_attr_e( 'Copied!', 'opalestate-pro' ); ?>"><?php esc_html_e( 'Copy', 'opalestate-pro' ); ?></button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row" class="titledesc">
|
||||
<?php esc_html_e( 'Consumer secret', 'opalestate-pro' ); ?>
|
||||
</th>
|
||||
<td class="forminp">
|
||||
<input id="key_consumer_secret" type="text" value="{{ data.consumer_secret }}" size="55" readonly="readonly">
|
||||
<button type="button" class="button-secondary copy-secret" data-tip="<?php esc_attr_e( 'Copied!', 'opalestate-pro' ); ?>">
|
||||
<?php esc_html_e( 'Copy', 'opalestate-pro' ); ?>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</script>
|
||||
Reference in New Issue
Block a user