php [专业网站] - 网站/博客列表中的自定义选项,以帮助进行PayPal快速网关续订测试
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php [专业网站] - 网站/博客列表中的自定义选项,以帮助进行PayPal快速网关续订测试相关的知识,希望对你有一定的参考价值。
<?php
/**
* Plugin Name: [Pro Sites] - Additional options on Sites Table
* Plugin URI: https://premium.wpmudev.org/
* Description: Adds more options on the Sites table
* Author: Panos Lyrakis @ WPMUDEV
* Author URI: https://premium.wpmudev.org/
* License: GPLv2 or later
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'WPMUDEV_PS_Sites_Options' ) ) {
class WPMUDEV_PS_Sites_Options {
private static $_instance = null;
public static function get_instance() {
if( is_null( self::$_instance ) ){
self::$_instance = new WPMUDEV_PS_Sites_Options();
}
return self::$_instance;
}
private function __construct() {
add_filter( 'wpmu_blogs_columns', array( $this, 'add_head_column' ), 10 );
add_action( 'manage_sites_custom_column', array( $this, 'add_column_field' ), 10, 2 );
add_action( 'admin_footer', array( $this, 'footer_script' ), 10 );
add_action( 'wp_ajax_wpmudev_ps_withdraw_blog', array( __CLASS__, 'force_withdraw_blog' ), 10 );
add_action( 'wp_ajax_wpmudev_ps_reset_blog_expire', array( __CLASS__, 'reset_blog_expire_ajax' ), 10 );
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ), 10 );
add_action( 'admin_head', array( $this, 'admin_head' ), 10 );
}
public function add_head_column( $columns ) {
$first_array = array_splice( $columns, 0, 2 );
$columns = array_merge( $first_array, array( 'ps_options' => __( 'Custom Options', 'psts' ) ), $columns );
return $columns;
}
public function add_column_field( $column, $blog_id ){
if( 'ps_options' != $column ){
return;
}
global $psts;
echo '<div>' . $this->force_withdraw_blog_option( $blog_id ) . '</div>';
echo '<div>' . $this->stripe_info( $blog_id ) . '</div>';
echo '<div>' . $this->force_ipn_simulator_option( $blog_id ) . '</div>';
echo '<div><code>' . date( 'd-m-Y H:i:s', $psts->get_expire( $blog_id ) ) . '</code></div>';
if ( ! is_main_site( $blog_id ) && is_pro_site( $blog_id ) ){
echo '<div class="datepicker-wrap">
<input type="text" class="datepicker" value="' . date( 'd-m-Y', $psts->get_expire( $blog_id ) ) . '" >
<button class="datechanger" data-blog-id="' . $blog_id . '" disabled>'. __( 'Change date' ) .'</button>
<input type="hidden" class="expire_time" value="' . date( 'H:i:s', $psts->get_expire( $blog_id ) ) . '" />
</div>';
}
}
public function stripe_info( $blog_id ){
if ( is_main_site( $blog_id ) || ! is_pro_site( $blog_id ) ) {
return;
}
global $wpdb;
$stripe_table = $wpdb->base_prefix . 'pro_sites_stripe_customers';
$stripe_info = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$stripe_table} WHERE blog_id=%d", $blog_id ) );
if( empty($stripe_info ) ){
return '<div class="stripe-info"><small><code>No stripe info</code></small></div>';
}
$out = '<div class="stripe-info">';
$out .= '<div class="stripe-info-created hidden">';
$out .= '<small>created: <code>'. time() .'</code></small>';
$out .= '</div>';
$out .= '<div class="stripe-info-blog-id hidden">';
$out .= '<small>blog_id: <code>'. $blog_id .'</code></small>';
$out .= '</div>';
$out .= '<div class="stripe-info-customer-id hidden">';
$out .= '<small>customer_id: <code>'. $stripe_info->customer_id .'</code></small>';
$out .= '</div>';
$out .= '<div class="stripe-info-subscription-id hidden">';
$out .= '<small>subscription_id: <code>'. $stripe_info->subscription_id .'</code></small>';
$out .= '</div>';
$out .= '<div class="stripe-info-start hidden">';
$out .= '<small>start (anything after): <code>'. strtotime( date() ) .'</code></small>';
$out .= '</div>';
$out .= '<div class="stripe-info-end hidden">';
$out .= '<small>end (anything after): <code>'. strtotime( date() . "+1 days" ) .'</code></small>';
$out .= '</div>';
$out .= '<div class="stripe-info-postman">';
$out .= '<small>Postman:
<a href="#" class="stripe-to-postman button"
data-blog-id="' . $blog_id . '"
data-created="' . time() . '"
data-customer="' . $stripe_info->customer_id . '"
data-subscription="' . $stripe_info->subscription_id . '"
data-start="' . time() . '"
data-end="' . strtotime( date() . "+1 days" ) . '"
>
Postman test
</a></small>';
$out .= '</div>';
$out .= '</div>';
$stripe_fieldset = '<fieldset style="border: 1px solid #ddd; padding:2px;"><legend>Stripe</legend>' . $out . '</fieldset>';
return $stripe_fieldset;
}
public function force_withdraw_blog_option( $blog_id ){
$out = '';
if ( ! is_main_site( $blog_id ) && is_pro_site( $blog_id ) ) {
$out = '<a class="button wpmudev-ps-withdraw-blog-btn" data-blog-id="' . $blog_id . '">Withdraw</a>';
}
return $out;
}
public function force_ipn_simulator_option( $blog_id ){
global $wpdb, $psts;
$blog_info = $wpdb->get_row( "SELECT * FROM {$wpdb->base_prefix}pro_sites WHERE blog_ID = '$blog_id'" );
$pref = 'psts';
$level = $psts->get_level( $blog_id );
if( 0 == $level ){
$level = '[LEVEL]';
}
$period = $blog_info->term;
$amount = $blog_info->amount;
$timestamp = time();
$activation_key = $blog_info->identifier;
if( $activation_key == '' ){
$blog_path = $wpdb->get_var( "SELECT path FROM {$wpdb->base_prefix}blogs WHERE blog_id={$blog_id}" );
$activation_key = $wpdb->get_var( "SELECT activation_key FROM {$wpdb->base_prefix}signups WHERE path='{$blog_path}'" );
}
$simulator_custom_field = $pref . '_' . $blog_id . '_' . $level . '_' . $period . '_' . $amount . '_' . $timestamp . '_' . $activation_key;
$simulator_custom_fieldset = '<fieldset style="border: 1px solid #ddd; padding:2px;"><legend>PayPal IPN</legend><small><code>' . $simulator_custom_field . '</code></small></fieldset>';
return $simulator_custom_fieldset;
}
public static function force_withdraw_blog(){
check_ajax_referer( 'wpmudev-ps-withdraw-blog', 'security' );
global $psts;
$blog_id = (int)$_POST['blog_id'];
$return = array(
'success' => false,
'blog_id' => $blog_id
);
if( ! is_wp_error( $psts->withdraw( $blog_id ) ) ){
$return = array(
'success' => true,
'blog_id' => $blog_id
);
}
wp_send_json($return);
}
public static function reset_blog_expire_ajax(){
check_ajax_referer( 'wpmudev-ps-reset-blog-expire', 'security' );
global $psts;
$blog_id = (int)$_POST['blog_id'];
$new_expire = strtotime( $_POST['new_expire'] );
$return = array(
'success' => false,
'blog_id' => $blog_id
);
if( self::reset_blog_expire( $blog_id, $new_expire ) ){
$return = array(
'success' => true,
'blog_id' => $blog_id
);
$psts->log_action( $blog_id, 'Blog was manually extended to ' . date( 'F j, Y H:i:s', $new_expire ) . '. This was set with custom action' );
}
wp_send_json($return);
}
public static function reset_blog_expire( $blog_id, $new_expire ){
global $wpdb;
$exists = false;
if ( ! empty( $blog_id ) ) {
$exists = $wpdb->get_var( $wpdb->prepare( "SELECT expire FROM {$wpdb->base_prefix}pro_sites WHERE blog_ID = %d", $blog_id ) );
}
if( ! $exists ){
return false;
}
$wpdb->query( $wpdb->prepare( "
UPDATE {$wpdb->base_prefix}pro_sites
SET expire = %d
WHERE blog_ID = %d",
$new_expire,
$blog_id
) );
return true;
}
public function admin_enqueue_scripts(){
$screen = get_current_screen();
if( 'sites-network' != $screen->id ){
return;
}
wp_enqueue_script( 'jquery-ui-datepicker' );
//For popup :
wp_enqueue_script( 'jquery-ui-dialog' ); // jquery and jquery-ui should be dependencies, didn't check though...
wp_enqueue_style( 'wp-jquery-ui-dialog' );
}
public function admin_head(){
$screen = get_current_screen();
if( 'sites-network' != $screen->id ){
return;
}
?>
<style>
.datepicker-wrap .datepicker{
max-width: 110px;
}
.ui-widget {
font-family: "Helvetica Neue","Trebuchet MS",Tahoma,Verdana,Arial,sans-serif;
background: #fff;
}
.ui-datepicker,
.ui-datepicker a,
.ui-datepicker th,
.ui-datepicker td{
padding: 10px !important;
}
.ui-datepicker {
padding: 0;
-webkit-box-shadow: 0px 2px 14px 1px rgba(0,0,0,0.75);
-moz-box-shadow: 0px 2px 14px 1px rgba(0,0,0,0.75);
box-shadow: 0px 2px 14px 1px rgba(0,0,0,0.75);
}
.ui-datepicker-header {
border: none;
font-size: 80%;
-moz-border-radius: 4px 4px 0 0;
-webkit-border-radius: 4px 4px 0 0;
border-radius: 4px 4px 0 0; /* border radius */
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box; /* prevents bg color from leaking outside the border */
background-color: #e0e8ec; /* layer fill content */
-moz-box-shadow: 0 1px 0 rgba(255,255,255,.53), inset 0 -1px 0 rgba(0,0,0,.12); /* drop shadow and inner shadow */
-webkit-box-shadow: 0 1px 0 rgba(255,255,255,.53), inset 0 -1px 0 rgba(0,0,0,.12); /* drop shadow and inner shadow */
box-shadow: 0 1px 0 rgba(255,255,255,.53), inset 0 -1px 0 rgba(0,0,0,.12); /* drop shadow and inner shadow */
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEwMCAxMDAiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iaGF0MCIgZ3JhZGllbnRVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giIHgxPSI1MCUiIHkxPSIxMDAlIiB4Mj0iNTAlIiB5Mj0iLTEuNDIxMDg1NDcxNTIwMmUtMTQlIj4KPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMCIgc3RvcC1vcGFjaXR5PSIwLjIxIi8+CjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmZiIgc3RvcC1vcGFjaXR5PSIwLjIxIi8+CiAgIDwvbGluZWFyR3JhZGllbnQ+Cgo8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgZmlsbD0idXJsKCNoYXQwKSIgLz4KPC9zdmc+); /* gradient overlay */
background-image: -moz-linear-gradient(bottom, rgba(0,0,0,.21) 0%, rgba(255,255,255,.21) 100%); /* gradient overlay */
background-image: -o-linear-gradient(bottom, rgba(0,0,0,.21) 0%, rgba(255,255,255,.21) 100%); /* gradient overlay */
background-image: -webkit-linear-gradient(bottom, rgba(0,0,0,.21) 0%, rgba(255,255,255,.21) 100%); /* gradient overlay */
background-image: linear-gradient(bottom, rgba(0,0,0,.21) 0%, rgba(255,255,255,.21) 100%); /* gradient overlay */
padding: 20px;
text-align: center;
}
.ui-datepicker-title {
color: #515d65; /* text color */
font-size: 13px;
font-weight: bold;
text-shadow: 0 1px 1px rgba(255,255,255,.8); /* drop shadow */
}
.ui-icon-circle-triangle-e {
background-image: url(images/ui-icons_454545_256x240.png);
background-position: -32px -16px;
}
.ui-icon-circle-triangle-w {
background-image: url(images/ui-icons_454545_256x240.png);
background-position: -96px -16px;
}
.ui-datepicker .ui-datepicker-prev,
.ui-datepicker .ui-datepicker-next {
border-color: transparent;
}
.ui-state-default {
background: transparent;
border: none;
color: #2b2b2b;
font-family: "Myriad Pro";
font-weight: normal;
text-align: center;
}
.ui-datepicker-header .ui-state-hover {
background: #bdc5c9;
}
.ui-datepicker table {
margin: 0;
}
.ui-datepicker th {
color: #9da7af;
font-size: 12px;
font-weight: normal;
-moz-border-radius: 216px 0 0 0 / 0 0 0 0;
-webkit-border-radius: 216px 0 0 0 / 0 0 0 0;
border-radius: 216px 0 0 0 / 0 0 0 0;
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box;
background-color: rgba(0,0,0,.08);
}
.ui-datepicker td {
border-top: 1px solid #ddd;
border-right: 1px solid #ddd;
padding: 0;
-moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.4);
-webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.4);
box-shadow: inset 0 1px 0 rgba(255,255,255,.4);
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEwMCAxMDAiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iaGF0MCIgZ3JhZGllbnRVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giIHgxPSI1MCUiIHkxPSIxMDAlIiB4Mj0iNTAlIiB5Mj0iLTEuNDIxMDg1NDcxNTIwMmUtMTQlIj4KPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMCIgc3RvcC1vcGFjaXR5PSIwLjA2Ii8+CjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmZiIgc3RvcC1vcGFjaXR5PSIwLjA2Ii8+CiAgIDwvbGluZWFyR3JhZGllbnQ+Cgo8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgZmlsbD0idXJsKCNoYXQwKSIgLz4KPC9zdmc+);
background-image: -moz-linear-gradient(bottom, rgba(0,0,0,.06) 0%, rgba(255,255,255,.06) 100%);
background-image: -o-linear-gradient(bottom, rgba(0,0,0,.06) 0%, rgba(255,255,255,.06) 100%);
background-image: -webkit-linear-gradient(bottom, rgba(0,0,0,.06) 0%, rgba(255,255,255,.06) 100%);
background-image: linear-gradient(bottom, rgba(0,0,0,.06) 0%, rgba(255,255,255,.06) 100%);
}
.ui-datepicker td:last-child {
border-right: none;
}
.ui-datepicker td span,
.ui-datepicker td a {
padding: .7em 0;
color: #6a747a;
font-size: 12px;
font-weight: bold;
font-family: Arial;
}
.ui-datepicker-calendar .ui-state-hover {
background-image: -moz-linear-gradient(bottom, rgba(0,0,0,.12) 0%, rgba(255,255,255,.06) 100%);
background-image: -o-linear-gradient(bottom, rgba(0,0,0,.12) 0%, rgba(255,255,255,.06) 100%);
background-image: -webkit-linear-gradient(bottom, rgba(0,0,0,.12) 0%, rgba(255,255,255,.06) 100%);
background-image: -webkit-linear-gradient(bottom, rgba(0,0,0,.12) 0%, rgba(255,255,255,.06) 100%);
}
td a.ui-state-active,
td a.ui-state-active.ui-state-hover {
color: #fff;
background-color: #8ab8ed;
text-shadow: 0 1px 0 rgba(0,0,0,.26);
-moz-box-shadow: inset 0 4px 9px rgba(0,0,0,.24);
-webkit-box-shadow: inset 0 4px 9px rgba(0,0,0,.24);
box-shadow: inset 0 4px 9px rgba(0,0,0,.24);
}
.ui-datepicker td.ui-state-disabled span,
.ui-datepicker td.ui-state-disabled a
{
color: #ddd;
}
</style>
<?php
}
public function footer_script(){
$screen = get_current_screen();
if( 'sites-network' != $screen->id ){
return;
}
?>
<script type="text/javascript">
(function($){
$(document).ready(function(){
var ps_withdraw_btn = $( '.wpmudev-ps-withdraw-blog-btn' );
ps_withdraw_btn.on( 'click', function(e){
var $this = $(this);
$this.html( 'Withdrawing...' );
var blog_id = $(this).data( 'blog-id' );
var data = {
action: 'wpmudev_ps_withdraw_blog',
security: '<?php echo wp_create_nonce( "wpmudev-ps-withdraw-blog" ); ?>',
blog_id: blog_id
};
$.post(ajaxurl, data, function(response) {
if( response.success ){
$this.fadeOut( '300', function(){ $this.remove(); } );
}
else{
alert( 'Blog could not be withdrawn...' );
}
window.location.reload();
});
});
$( '.datepicker' ).on( 'change', function(){
var $this = $( this );
var new_date = $this.val();
$this.parent().find( '.datechanger' ).attr( 'disabled', false );
});
$( '.datechanger' ).on( 'click', function(){
$( '.datepicker-wrap' ).append( '<div>Please wait. Updating expiration date.</div>' );
var $this = $( this );
$this.attr( 'disabled', true );
var blog_id = $this.data( 'blog-id' );
var new_expire = $this.parent().find( '.datepicker' ).val();
var expire_time = $this.parent().find( '.expire_time' ).val();
new_expire += ' ' + expire_time;
var data = {
action: 'wpmudev_ps_reset_blog_expire',
security: '<?php echo wp_create_nonce( "wpmudev-ps-reset-blog-expire" ); ?>',
blog_id: blog_id,
new_expire: new_expire
};
$.post(ajaxurl, data, function(response) {
if( response.success ){
$this.fadeOut( '300', function(){ $this.remove(); } );
}
else{
alert( 'Could not set new expiration date for blog...' );
}
window.location.reload();
});
});
$('.datepicker').datepicker({
dateFormat : 'dd-mm-yy',
minDate: 0
});
$('.stripe-to-postman').on( 'click', function(e){
e.preventDefault();
var $this = $( this );
var blog_id = $this.data( 'blog-id' );
var created = $this.data( 'created' );
var start = $this.data( 'start' );
var end = $this.data( 'end' );
var customer = $this.data( 'customer' );
var subscription = $this.data( 'subscription' );
var default_content = $( '#stripe-postman-default-content' ).html();
var new_content = default_content;
new_content = new_content.replace( '[%blog_id%]', blog_id );
new_content = new_content.replace( '[%created%]', created );
new_content = new_content.replace( '[%subscription%]', subscription );
new_content = new_content.replace( '[%customer%]', customer );
new_content = new_content.replace( '[%start%]', start );
new_content = new_content.replace( '[%end%]', end );
$('#stripe-postman-dialog .dialog-content').html( '<code>' + new_content + '</code>' )
$('#stripe-postman-dialog').dialog('open');
});
//Postman PopUp dialog
$('#stripe-postman-dialog').dialog({
title: 'Postman test',
dialogClass: 'wp-dialog',
autoOpen: false,
draggable: false,
width: 'auto',
modal: true,
resizable: false,
closeOnEscape: true,
position: {
my: "center",
at: "center",
of: window
},
open: function () {
// close dialog by clicking the overlay behind it
$('.ui-widget-overlay').bind('click', function(){
$('#stripe-postman-dialog').dialog('close');
})
},
create: function () {
// style fix for WordPress admin
$('.ui-dialog-titlebar-close').addClass('ui-button');
},
});
});
})(jQuery);
</script>
<!-- The modal / dialog box, for Stripe postmane -->
<div id="stripe-postman-dialog" class="hidden" style="min-width:600px;max-width:1000px">
<h3>Please copy following into postman to test stripe succesfull payment</h3>
<div class="dialog-content"></div>
</div>
<div id="stripe-postman-default-content" style="display:none">
{
"created": [%created%],
"livemode": false,
"id": "evt_00000000000000",
"type": "invoice.payment_succeeded",
"object": "event",
"request": null,
"pending_webhooks": 1,
"api_version": "2017-08-15",
"data": {
"object": {
"id": "in_00000000000000",
"object": "invoice",
"amount_due": 2000,
"application_fee": null,
"attempt_count": 1,
"attempted": true,
"billing": "charge_automatically",
"charge": "_00000000000000",
"closed": true,
"currency": "usd",
"customer": "[%customer%]",
"date": 1463604240,
"description": null,
"discount": null,
"ending_balance": 0,
"forgiven": false,
"lines": {
"data": [
{
"id": "sub_9lgdj4XYXu40PH",
"object": "line_item",
"amount": 4000,
"currency": "usd",
"description": null,
"discountable": true,
"livemode": true,
"metadata": {
"period": "1",
"level": "4",
"activation": "5f5dea9fd30af1ee",
"blog_id": "[%blog_id%]"
},
"period": {
"start": [%start%],
"end": [%end%]
},
"plan": {
"id": "ms-plan-4637-aZugfMmEub0xFkF7VLjuA",
"object": "plan",
"amount": 800,
"created": 1503821272,
"currency": "usd",
"interval": "day",
"interval_count": 30,
"livemode": false,
"metadata": {
},
"name": "Root",
"statement_descriptor": null,
"trial_period_days": null
},
"proration": false,
"quantity": 1,
"subscription": null,
"subscription_item": "si_19S9GBKvwjw7Q9S7tRdETFHQ",
"type": "subscription"
}
],
"has_more": false,
"object": "list",
"url": "/v1/invoices/in_18CbWOKvwjw7Q9S7rk3NnjGT/lines"
},
"livemode": false,
"metadata": {
},
"next_payment_attempt": null,
"paid": true,
"period_end": 1463604240,
"period_start": 1463604240,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": null,
"subscription": "[%subscription%]",
"subtotal": 2000,
"tax": null,
"tax_percent": null,
"total": 2000,
"webhooks_delivered_at": 1463604240
}
}
}
</div>
<!-- This script should be enqueued properly in the footer -->
<script>
(function ($) {
$( document ).ready(function(){
// initalise the dialog
});
})(jQuery);
</script>
<?php
}
}
add_action( 'plugins_loaded', function(){
$GLOBALS['WPMUDEV_PS_Sites_Options'] = WPMUDEV_PS_Sites_Options::get_instance();
}, 10 );
}
以上是关于php [专业网站] - 网站/博客列表中的自定义选项,以帮助进行PayPal快速网关续订测试的主要内容,如果未能解决你的问题,请参考以下文章