我想知道是否以及如何嵌入/显示从wp-admin / profile.php到前端的某些选项。就是这种情况:
我安装了一个名为Woocommerce Appointments的插件,负责创建预订。员工可以设置自己的可用性,但是只能通过登录WordPress仪表板,尤其是Users->您的个人资料页面来实现。
如果我可以用可用性代码创建一个小部件,以便可以在前端的任何位置显示它,那将是完美的。
有可能吗? 以下是代码:
<?php
// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;
class WC_Appointments_Admin_Staff_Profile {
/**
* Constructor
*/
public function __construct() {
add_action( 'show_user_profile', array( $this, 'add_staff_meta_fields' ), 20 );
add_action( 'edit_user_profile', array( $this, 'add_staff_meta_fields' ), 20 );
add_action( 'personal_options_update', array( $this, 'save_staff_meta_fields' ) );
add_action( 'edit_user_profile_update', array( $this, 'save_staff_meta_fields' ) );
add_action( 'delete_user', array( $this, 'delete_staff' ), 11 );
}
/**
* Show meta box
*/
public function add_staff_meta_fields( $user ) {
if ( ! current_user_can( 'edit_user', $user->ID ) ) {
return;
}
wp_enqueue_script( 'wc_appointments_writepanel_js' );
?>
<style type="text/css">
#minor-publishing-actions, #visibility { display:none }
</style>
<h3 id="staff-gcal"><?php esc_html_e( '2-way Google Calendar Sync', 'woocommerce-appointments' ); ?></h3>
<table class="form-table">
<?php
// Calendar ID.
$calendar_id = get_user_meta( $user->ID, 'wc_appointments_gcal_calendar_id', true );
$calendar_id = $calendar_id ? $calendar_id : '';
// Run Gcal oauth redirect.
$gcal_integration_class = wc_appointments_integration_gcal();
$gcal_integration_class->set_user_id( $user->ID );
// Get access token.
$access_token = $gcal_integration_class->get_access_token();
$client_id = $gcal_integration_class->get_client_id();
$client_secret = $gcal_integration_class->get_client_secret();
$twoway = $gcal_integration_class->get_twoway();
// 2-way sync enabled?
$twoway_enabled = ( 'no' === $twoway ) ? false : true;
?>
<tr>
<th><label><?php esc_html_e( 'Authorization', 'woocommerce-appointments' ); ?></label></th>
<td>
<?php if ( ! $access_token && $client_id && $client_secret ) : ?>
<button type="button" class="button oauth_redirect" data-staff="<?php echo esc_attr( absint( $user->ID ) ); ?>" data-logout="0"><?php esc_html_e( 'Connect with Google', 'woocommerce-appointments' ); ?></button>
<?php elseif ( $access_token ) : ?>
<p><?php esc_html_e( 'Successfully authenticated.', 'woocommerce-appointments' ); ?></p>
<p class="submit">
<button type="button" class="button oauth_redirect" data-staff="<?php echo esc_attr( absint( $user->ID ) ); ?>" data-logout="1"><?php esc_html_e( 'Disconnect', 'woocommerce-appointments' ); ?></button>
</p>
<?php else : ?>
<p>
<?php
/* translators: 1: link to google calendar sync settings */
printf( __( 'Please configure <a href="%s">Google Calendar Sync settings</a> first.', 'woocommerce-appointments' ), esc_url( admin_url( 'admin.php?page=wc-settings&tab=appointments§ion=gcal' ) ) );
?>
</p>
<?php endif; ?>
</td>
</tr>
<?php if ( $access_token ) : ?>
<tr>
<th><label for="wc_appointments_gcal_calendar_id"><?php esc_html_e( 'Calendar ID', 'woocommerce-appointments' ); ?></label></th>
<td>
<?php $calendar_id = get_user_meta( $user->ID, 'wc_appointments_gcal_calendar_id', true ); ?>
<?php $calendar_id = $calendar_id ? $calendar_id : ''; ?>
<?php if ( $calendar_id ) : ?>
<input type="text" class="regular-text" name="wc_appointments_gcal_calendar_id" id="wc_appointments_gcal_calendar_id" value="<?php echo esc_attr( $calendar_id ); ?>">
<?php else : ?>
<select id="wc_appointments_gcal_calendar_id" name="wc_appointments_gcal_calendar_id" class="wc-enhanced-select" style="width:25em;">
<option value=""><?php esc_html_e( 'N/A', 'woocommerce-appointments' ); ?></option>
<?php
// Get all Google Calendars.
$get_user_calendars = $gcal_integration_class->get_user_calendars();
// Check if Authorized and calendars exist.
if ( $access_token && $get_user_calendars ) {
foreach ( $get_user_calendars as $cal_id => $cal_name ) {
?>
<option value="<?php echo esc_attr( $cal_id ); ?>" <?php selected( $calendar_id, $cal_id ); ?>><?php echo esc_attr( $cal_name ); ?></option>
<?php
}
}
?>
</select>
<?php endif; ?>
</td>
</tr>
<?php
if ( $calendar_id && $twoway_enabled ) :
?>
<tr>
<th><label><?php esc_html_e( 'Last Sync', 'woocommerce-appointments' ); ?></label></th>
<td>
<?php
#$rules = get_user_meta( $user->ID, 'wc_appointments_gcal_availability', true );
#print '<pre>'; print_r( $rules ); print '</pre>';
$last_synced = get_user_meta( $user->ID, 'wc_appointments_gcal_availability_last_synced', true );
$last_synced = $last_synced ? $last_synced : '';
if ( $last_synced ) {
$ls_timestamp = isset( $last_synced[0] ) && $last_synced[0] ? absint( $last_synced[0] ) : absint( current_time( 'timestamp' ) );
$ls_counter = isset( $last_synced[1] ) && $last_synced[1] ? absint( $last_synced[1] ) : 0;
/* translators: 1: event singular, 2: events plural */
$ls_message = sprintf( _n( '%s event.', '%s events.', $ls_counter, 'woocommerce-appointments' ), number_format_i18n( $ls_counter ) );
$ls_message .= ' ';
/* translators: 1: date format, 2: time format */
$ls_message .= sprintf( __( '%1$s, %2$s', 'woocommerce-appointments' ), date_i18n( wc_date_format(), $ls_timestamp ), date_i18n( wc_time_format(), $ls_timestamp ) );
?>
<p class="last_synced"><?php echo esc_attr( $ls_message ); ?></p>
<?php } else { ?>
<p class="last_synced"><?php esc_html_e( 'Not synced yet.', 'woocommerce-appointments' ); ?></p>
<?php } ?>
<p class="submit">
<button type="button" class="button manual_sync" data-staff="<?php echo esc_attr( absint( $user->ID ) ); ?>"><?php esc_html_e( 'Sync Manually', 'woocommerce-appointments' ); ?></button>
</p>
</td>
</tr>
<?php endif; ?>
<?php endif; ?>
</table>
<h3 id="staff-details"><?php esc_html_e( 'Staff details', 'woocommerce-appointments' ); ?></h3>
<table class="form-table">
<tr class="staff-availability">
<th><label><?php esc_html_e( 'Custom Availability', 'woocommerce-appointments' ); ?></label></th>
<td>
<div class="woocommerce">
<div class="panel-wrap" id="appointments_availability">
<div class="table_grid">
<table class="widefat">
<thead>
<tr>
<th class="sort" width="1%"> </th>
<th class="range_type"><?php esc_html_e( 'Type', 'woocommerce-appointments' ); ?></th>
<th class="range_name"><?php esc_html_e( 'Range', 'woocommerce-appointments' ); ?></th>
<th class="range_name2"></th>
<th class="range_priority"><?php esc_html_e( 'Priority', 'woocommerce-appointments' ); ?><?php echo wc_help_tip( __( 'Rules with lower priority numbers will override rules with a higher priority (e.g. 9 overrides 10 ). By using priority numbers you can execute rules in different orders for all three levels: Global, Product and Staff rules.', 'woocommerce-appointments' ) ); ?></th>
<th class="range_appointable"><?php esc_html_e( 'Available', 'woocommerce-appointments' ); ?><?php echo wc_help_tip( __( 'If not available, users won\'t be able to choose slots in this range for their appointment.', 'woocommerce-appointments' ) ); ?></th>
<th class="remove" width="1%"> </th>
</tr>
</thead>
<tbody id="availability_rows">
<?php
$staff = new WC_Product_Appointment_Staff( $user->ID );
$staff_availability = $staff->get_availability( true );
if ( ! empty( $staff_availability ) && is_array( $staff_availability ) ) {
if ( ! empty( $staff_availability[0] ) ) {
foreach ( $staff_availability as $availability ) {
include 'views/html-appointment-availability-fields.php';
}
}
}
?>
</tbody>
<tfoot>
<tr>
<th colspan="8">
<a href="#" class="button add_row" data-row="<?php
ob_start();
include 'views/html-appointment-availability-fields.php';
$html = ob_get_clean();
echo esc_attr( $html );
?>"><?php esc_html_e( 'Add Rule', 'woocommerce-appointments' ); ?></a>
<span class="description"><?php esc_html_e( get_wc_appointment_rules_explanation() ); ?></span>
</th>
</tr>
</tfoot>
</table>
</div>
<div class="clear"></div>
</div>
</div>
</td>
</tr>
<?php if ( ! class_exists( 'SitePress' ) && ! class_exists( 'woocommerce_wpml' ) && ! class_exists( 'WPML_Element_Translation_Package' ) && apply_filters( 'woocommerce_appointments_staff_product_assignement', true ) ) { ?>
<tr class="staff-products">
<th><label><?php esc_html_e( 'Assigned Products', 'woocommerce-appointments' ); ?></label></th>
<td>
<div class="woocommerce">
<div id="appointments_products" class="panel-wrap">
<div class="table_grid">
<table class="widefat">
<thead>
<tr>
<th class="sort" width="1%"> </th>
<th class="staff_product"><?php esc_html_e( 'Product', 'woocommerce-appointments' ); ?></th>
<th class="product_cost"><?php esc_html_e( 'Price', 'woocommerce-appointments' ); ?></th>
<th class="product_qty"><?php esc_html_e( 'Quantity', 'woocommerce-appointments' ); ?></th>
<th class="staff_cost"><?php esc_html_e( 'Additional Cost', 'woocommerce-appointments' ); ?><?php echo wc_help_tip( __( 'Additional cost for this staff, which will be calculated into overall product cost.', 'woocommerce-appointments' ) ); ?></th>
<th class="staff_qty"><?php esc_html_e( 'Staff Quantity', 'woocommerce-appointments' ); ?><?php echo wc_help_tip( __( 'The maximum number of appointments per slot. Overrides product quantity.', 'woocommerce-appointments' ) ); ?></th>
<th class="remove" width="1%"> </th>
</tr>
</thead>
<tbody id="product_rows" class="woocommerce_staff_products">
<?php
$user_product_ids = WC_Data_Store::load( 'product-appointment' )->get_appointable_product_ids_for_staff( $user->ID );
$user_product_ids_comma = ! empty( $user_product_ids ) && is_array( $user_product_ids ) ? implode( ',', $user_product_ids ) : '';
$all_appointable_products = WC_Appointments_Admin::get_appointment_products( true );
if ( ! empty( $user_product_ids ) && is_array( $user_product_ids ) ) {
foreach ( $user_product_ids as $user_product_id ) {
$user_id = $user->ID;
include 'views/html-appointment-staff-fields.php';
}
}
?>
<input type="hidden" id="wc_appointments_staff_product_ids" name="wc_appointments_staff_product_ids" value="<?php echo esc_attr( $user_product_ids_comma ); ?>" />
</tbody>
<tfoot>
<tr>
<th colspan="7">
<div class="toolbar">
<button type="button" class="button add_product"><?php esc_html_e( 'Assign Product', 'woocommerce-appointments' ); ?></button>
<?php if ( $all_appointable_products && ! empty( $all_appointable_products ) ) { ?>
<select id="add_product_id" name="add_product_id" class="add_select_id wc-enhanced-select" data-staff="<?php echo esc_attr( absint( $user->ID ) ); ?>" style="min-width:160px;">
<?php
foreach ( $all_appointable_products as $appointable_product ) {
echo '<option value="' . esc_attr( $appointable_product->get_id() ) . '">' . esc_html( $appointable_product->get_title() ) . '</option>';
}
?>
</select>
<?php } ?>
</div>
</th>
</tr>
</tfoot>
</table>
</div>
<div class="clear"></div>
</div>
</div>
</td>
</tr>
<?php } ?>
</table>
<?php
}
/**
* Save handler
*/
public function save_staff_meta_fields( $user_id ) {
// Availability.
$availability = array();
$row_size = isset( $_POST['wc_appointment_availability_type'] ) ? count( $_POST['wc_appointment_availability_type'] ) : 0;
for ( $i = 0; $i < $row_size; $i ++ ) {
$availability[ $i ]['type'] = wc_clean( $_POST['wc_appointment_availability_type'][ $i ] );
$availability[ $i ]['appointable'] = wc_clean( $_POST['wc_appointment_availability_appointable'][ $i ] );
$availability[ $i ]['priority'] = wc_clean( $_POST['wc_appointment_availability_priority'][ $i ] );
switch ( $availability[ $i ]['type'] ) {
case 'custom' :
$availability[ $i ]['from'] = wc_clean( $_POST['wc_appointment_availability_from_date'][ $i ] );
$availability[ $i ]['to'] = wc_clean( $_POST['wc_appointment_availability_to_date'][ $i ] );
break;
case 'months' :
$availability[ $i ]['from'] = wc_clean( $_POST['wc_appointment_availability_from_month'][ $i ] );
$availability[ $i ]['to'] = wc_clean( $_POST['wc_appointment_availability_to_month'][ $i ] );
break;
case 'weeks' :
$availability[ $i ]['from'] = wc_clean( $_POST['wc_appointment_availability_from_week'][ $i ] );
$availability[ $i ]['to'] = wc_clean( $_POST['wc_appointment_availability_to_week'][ $i ] );
break;
case 'days' :
$availability[ $i ]['from'] = wc_clean( $_POST['wc_appointment_availability_from_day_of_week'][ $i ] );
$availability[ $i ]['to'] = wc_clean( $_POST['wc_appointment_availability_to_day_of_week'][ $i ] );
break;
case 'time' :
case 'time:1' :
case 'time:2' :
case 'time:3' :
case 'time:4' :
case 'time:5' :
case 'time:6' :
case 'time:7' :
$availability[ $i ]['from'] = wc_appointment_sanitize_time( $_POST['wc_appointment_availability_from_time'][ $i ] );
$availability[ $i ]['to'] = wc_appointment_sanitize_time( $_POST['wc_appointment_availability_to_time'][ $i ] );
break;
case 'time:range' :
$availability[ $i ]['from'] = wc_appointment_sanitize_time( $_POST['wc_appointment_availability_from_time'][ $i ] );
$availability[ $i ]['to'] = wc_appointment_sanitize_time( $_POST['wc_appointment_availability_to_time'][ $i ] );
$availability[ $i ]['from_date'] = wc_clean( $_POST['wc_appointment_availability_from_date'][ $i ] );
$availability[ $i ]['to_date'] = wc_clean( $_POST['wc_appointment_availability_to_date'][ $i ] );
break;
}
}
update_user_meta( $user_id, '_wc_appointment_availability', $availability );
// Assigned Products.
$staff_products = isset( $_POST['staff_product_id'] ) ? $_POST['staff_product_id'] : '';
$staff_base_costs = isset( $_POST['staff_base_costs'] ) ? $_POST['staff_base_costs'] : '';
$staff_qtys = isset( $_POST['staff_qtys'] ) ? $_POST['staff_qtys'] : '';
if ( $staff_products && ! empty( $staff_products ) ) {
foreach ( $staff_products as $staff_product_id ) {
$appointable_product = new WC_Product_Appointment( $staff_product_id );
if ( ! is_a( $appointable_product, 'WC_Product_Appointment' ) ) {
continue;
}
// Asssign staff to product.
$staff_ids = $appointable_product->get_staff_ids();
if ( ! in_array( $user_id, $staff_ids ) ) {
$staff_ids[] = $user_id;
}
$appointable_product->set_staff_ids( $staff_ids );
// Add staff base costs to product.
$product_staff_base_costs = $appointable_product->get_staff_base_costs();
$product_staff_base_costs[ $user_id ] = floatval( $staff_base_costs[ $staff_product_id ] );
$appointable_product->set_staff_base_costs( $product_staff_base_costs );
// Add staff base costs to product.
$product_staff_qtys = $appointable_product->get_staff_qtys();
$product_staff_qtys[ $user_id ] = intval( $staff_qtys[ $staff_product_id ] );
$appointable_product->set_staff_qtys( $product_staff_qtys );
$appointable_product->save();
}
}
// Calendar ID.
$calendar_id = isset( $_POST['wc_appointments_gcal_calendar_id'] ) ? $_POST['wc_appointments_gcal_calendar_id'] : '';
if ( ! $calendar_id ) {
delete_user_meta( $user_id, 'wc_appointments_gcal_calendar_id' );
delete_user_meta( $user_id, 'wc_appointments_gcal_availability' );
delete_user_meta( $user_id, 'wc_appointments_gcal_availability_last_synced' );
wp_clear_scheduled_hook( 'wc-appointment-sync-from-gcal', array( $user_id ) );
} else {
update_user_meta( $user_id, 'wc_appointments_gcal_calendar_id', $calendar_id );
}
// Schedule incremental sync each hour.
if ( $calendar_id && ! wp_next_scheduled( 'wc-appointment-sync-from-gcal', array( $user_id ) ) ) {
wp_clear_scheduled_hook( 'wc-appointment-sync-from-gcal', array( $user_id ) );
wp_schedule_event( time(), apply_filters( 'woocommerce_appointments_sync_from_gcal', 'hourly' ), 'wc-appointment-sync-from-gcal' );
}
// Clear incremental sync each hour.
if ( ! $calendar_id ) {
wp_clear_scheduled_hook( 'wc-appointment-sync-from-gcal', array( $user_id ) );
}
}
/**
* Actions to be done when staff is deleted
*/
public function delete_staff( $user_id ) {
$user_meta = get_userdata( $user_id );
// Check roles if user is shop staff.
if ( in_array( 'shop_staff', (array) $user_meta->roles ) ) {
// Get all staff appointments and remove staff from them.
$appointments_args = array(
'meta_query' => array(
array(
'key' => '_appointment_staff_id',
'value' => absint( $user_id ),
),
),
'post_status' => get_wc_appointment_statuses( 'validate' ),
);
$staff_appointments = WC_Appointments_Controller::get_appointments( $appointments_args );
if ( ! empty( $staff_appointments ) ) {
foreach ( $staff_appointments as $staff_appointment ) {
delete_post_meta( $staff_appointment->id, '_appointment_staff_id' );
}
}
// Get all products that current staff is assigned to and remove him/her from product (revert the relational db table and post meta logic in class-wc-appointments-admin.php on line 559-593)
$staff_product_ids = WC_Data_Store::load( 'product-appointment' )->get_appointable_product_ids_for_staff( $user_id );
if ( ! empty( $staff_product_ids ) ) {
foreach ( $staff_product_ids as $staff_product_id ) {
WC_Data_Store::load( 'product-appointment' )->remove_staff_from_product( $user_id, $staff_product_id );
}
}
// Check roles if user is shop staff.
} elseif ( in_array( 'customer', (array) $user_meta->roles ) ) {
$customer_appointments_args = array(
'meta_query' => array(
array(
'key' => '_appointment_customer_id',
'value' => absint( $user_id ),
'compare' => 'IN',
),
),
'post_status' => get_wc_appointment_statuses( 'user' ),
);
$customer_appointments = WC_Appointments_Controller::get_appointments( $customer_appointments_args );
if ( ! empty( $customer_appointments ) ) {
foreach ( $customer_appointments as $customer_appointment ) {
delete_post_meta( $customer_appointment->id, '_appointment_customer_id' );
}
}
}
}
}
return new WC_Appointments_Admin_Staff_Profile();