Skip to content

Instantly share code, notes, and snippets.

@JarrydLong
Created March 18, 2026 07:26
Show Gist options
  • Select an option

  • Save JarrydLong/7b5803c0c8b479ca805fe541ce0094d3 to your computer and use it in GitHub Desktop.

Select an option

Save JarrydLong/7b5803c0c8b479ca805fe541ce0094d3 to your computer and use it in GitHub Desktop.
<?php
/*
Plugin Name: Paid Memberships Pro - Demo Data
Description: Complete PMPro demo environment generator with levels, users, orders, renewals, and lifecycle simulation
*/
if ( ! defined( 'ABSPATH' ) ) exit;
/*
============================
ADMIN MENU
============================
*/
add_action('admin_menu', function(){
add_menu_page(
'PMPro Demo Data',
'PMPro Demo',
'manage_options',
'pmprod-demo-data',
'pmprod_demo_page',
'dashicons-database',
58
);
});
function pmprod_demo_page(){
if ( isset($_POST['pmprod_generate']) ) {
pmprod_reset_demo_data();
pmprod_generate_demo_data();
echo '<div class="updated"><p>Demo data generated.</p></div>';
}
?>
<div class="wrap">
<h1>PMPro Demo Mode</h1>
<p>This tool will reset your PMPro data and generate a fresh set of demo data, including various membership levels, users, orders, and subscription histories. Use this to test features, troubleshoot issues, or develop customizations in a safe environment.</p>
<p>Do not run this on a live site. Always back up your data before using.</p>
<form method="post">
<button class="button button-primary" name="pmprod_generate">
Reset & Generate Demo Data
</button>
</form>
</div>
<?php
}
/*
============================
RESET
============================
*/
function pmprod_reset_demo_data(){
$users = get_users([
'meta_key' => 'pmprod_demo_user',
'meta_value' => 1
]);
foreach($users as $user){
wp_delete_user($user->ID);
}
global $wpdb;
$wpdb->query("DELETE FROM {$wpdb->pmpro_memberships_users}");
$wpdb->query("DELETE FROM {$wpdb->pmpro_membership_orders}");
}
/*
============================
HELPERS
============================
*/
function pmprod_create_user($email){
if(email_exists($email)){
return get_user_by('email',$email)->ID;
}
$id = wp_create_user($email,'password',$email);
update_user_meta($id,'pmprod_demo_user',1);
update_user_meta($id,'first_name',ucfirst(explode('@',$email)[0]));
update_user_meta($id,'last_name','Demo');
update_user_meta($id,'company','Company '.rand(1,100));
update_user_meta($id,'phone','+1'.rand(600000000,699999999));
update_user_meta($id,'account_manager_notes','Demo account');
pmprod_assign_random_avatar($id);
return $id;
}
function pmprod_create_order($user_id, $level_id, $status, $amount, $time, $subscription_id){
$o = new MemberOrder();
$o->user_id = $user_id;
$o->membership_id = $level_id;
$o->status = $status;
$o->total = $amount;
$o->gateway = 'stripe';
$o->payment_transaction_id = 'txn_' . wp_generate_password(6,false);
$o->subscription_transaction_id = $subscription_id;
$o->timestamp = $time; // MUST be UNIX timestamp (int)
$o->date = date('Y-m-d H:i:s', $time); // also set date explicitly
$o->saveOrder();
}
function pmprod_generate_subscription_history($user,$level,$months,$amount){
$sub = 'sub_'.wp_generate_password(6,false);
for($i=0;$i<$months;$i++){
$time = strtotime("-$i months");
pmprod_create_order($user,$level,'success',$amount,$time,$sub);
}
pmprod_create_order($user,$level,'error',$amount,strtotime('-1 week'),$sub);
}
/*
============================
LEVEL CREATION
============================
*/
function pmprod_create_or_update_level( $data ) {
global $wpdb;
$table = $wpdb->pmpro_membership_levels;
$existing = $wpdb->get_row(
$wpdb->prepare("SELECT * FROM $table WHERE name = %s LIMIT 1",$data['name'])
);
$defaults = [
'name'=>'',
'description'=>'',
'confirmation'=>'',
'initial_payment'=>0,
'billing_amount'=>0,
'cycle_number'=>0,
'cycle_period'=>'',
'billing_limit'=>0,
'trial_amount'=>0,
'trial_limit'=>0,
'expiration_number'=>0,
'expiration_period'=>''
];
$data = wp_parse_args($data,$defaults);
if($existing){
$wpdb->update($table,$data,['id'=>$existing->id]);
return (int)$existing->id;
} else {
$wpdb->insert($table,$data);
return (int)$wpdb->insert_id;
}
}
/*
============================
PMPro SAFE LEVEL ARRAY
============================
*/
function pmprod_get_full_level_array($level_id,$user_id,$overrides=[]){
$level = pmpro_getLevel($level_id);
return array_merge([
'user_id'=>$user_id,
'membership_id'=>$level->id,
'code_id'=>0,
'initial_payment'=>$level->initial_payment ?? 0,
'billing_amount'=>$level->billing_amount ?? 0,
'cycle_number'=>$level->cycle_number ?? 0,
'cycle_period'=>$level->cycle_period ?? '',
'billing_limit'=>$level->billing_limit ?? 0,
'trial_amount'=>$level->trial_amount ?? 0,
'trial_limit'=>$level->trial_limit ?? 0,
// CRITICAL FIX → ensures active membership
'startdate'=>current_time('timestamp'),
'enddate'=>0
],$overrides);
}
function pmprod_set_expired_level($user_id,$level_id,$days=5){
pmpro_changeMembershipLevel(
pmprod_get_full_level_array($level_id,$user_id,[
'enddate'=>strtotime("-$days days")
]),
$user_id
);
}
/*
============================
MAIN GENERATOR
============================
*/
function pmprod_generate_demo_data(){
/*
LEVELS
*/
$levels = [];
$levels['free'] = pmprod_create_or_update_level(['name'=>'Free Membership']);
$levels['one_time'] = pmprod_create_or_update_level([
'name'=>'One-Time','initial_payment'=>50
]);
$levels['monthly'] = pmprod_create_or_update_level([
'name'=>'Monthly','billing_amount'=>10,'cycle_number'=>1,'cycle_period'=>'Month'
]);
$levels['annual'] = pmprod_create_or_update_level([
'name'=>'Annual','billing_amount'=>100,'cycle_number'=>1,'cycle_period'=>'Year'
]);
$levels['trial'] = pmprod_create_or_update_level([
'name'=>'Trial + Monthly','trial_limit'=>1,'billing_amount'=>15,'cycle_number'=>1,'cycle_period'=>'Month'
]);
$levels['lifetime'] = pmprod_create_or_update_level([
'name'=>'Lifetime','initial_payment'=>300
]);
$levels['expiring'] = pmprod_create_or_update_level([
'name'=>'30 Day Access','expiration_number'=>30,'expiration_period'=>'Day'
]);
wp_cache_flush();
/*
USERS
*/
$u1 = pmprod_create_user('history@example.com');
pmpro_changeMembershipLevel(pmprod_get_full_level_array($levels['monthly'],$u1),$u1);
pmprod_generate_subscription_history($u1,$levels['monthly'],6,10);
$u2 = pmprod_create_user('failed@example.com');
pmpro_changeMembershipLevel(pmprod_get_full_level_array($levels['monthly'],$u2),$u2);
pmprod_generate_subscription_history($u2,$levels['monthly'],3,10);
$u3 = pmprod_create_user('new@example.com');
pmpro_changeMembershipLevel(pmprod_get_full_level_array($levels['monthly'],$u3),$u3);
pmprod_create_order($u3,$levels['monthly'],'success',10,time(),'sub_new');
$u4 = pmprod_create_user('expired@example.com');
pmprod_set_expired_level($u4,$levels['expiring'],10);
$u5 = pmprod_create_user('cancelled@example.com');
pmpro_changeMembershipLevel(pmprod_get_full_level_array($levels['monthly'],$u5),$u5);
pmpro_cancelMembershipLevel($u5);
$u6 = pmprod_create_user('trial@example.com');
pmpro_changeMembershipLevel(pmprod_get_full_level_array($levels['trial'],$u6),$u6);
$u7 = pmprod_create_user('lifetime@example.com');
pmpro_changeMembershipLevel(pmprod_get_full_level_array($levels['lifetime'],$u7),$u7);
$u8 = pmprod_create_user('onetime@example.com');
pmpro_changeMembershipLevel(pmprod_get_full_level_array($levels['one_time'],$u8),$u8);
$u9 = pmprod_create_user('manual@example.com');
pmpro_changeMembershipLevel(pmprod_get_full_level_array($levels['free'],$u9),$u9);
/*
RANDOM USERS
*/
for($i=1;$i<=10;$i++){
$user = pmprod_create_user("user$i@example.com");
$type = rand(1,5);
switch($type){
case 1:
pmpro_changeMembershipLevel(pmprod_get_full_level_array($levels['monthly'],$user),$user);
pmprod_generate_subscription_history($user,$levels['monthly'],rand(2,6),10);
break;
case 2:
pmpro_changeMembershipLevel(pmprod_get_full_level_array($levels['free'],$user),$user);
break;
case 3:
pmpro_changeMembershipLevel(pmprod_get_full_level_array($levels['annual'],$user),$user);
pmprod_create_order($user,$levels['annual'],'success',100,strtotime('-3 months'),'sub_a');
break;
case 4:
pmpro_changeMembershipLevel(pmprod_get_full_level_array($levels['monthly'],$user),$user);
pmpro_cancelMembershipLevel($user);
break;
case 5:
pmprod_set_expired_level($user,$levels['expiring'],5);
break;
}
}
/*
UPGRADE / DOWNGRADE
*/
$u10 = pmprod_create_user('upgrade@example.com');
pmpro_changeMembershipLevel(pmprod_get_full_level_array($levels['free'],$u10),$u10);
pmpro_changeMembershipLevel(pmprod_get_full_level_array($levels['monthly'],$u10),$u10);
pmpro_changeMembershipLevel(pmprod_get_full_level_array($levels['annual'],$u10),$u10);
pmpro_changeMembershipLevel(pmprod_get_full_level_array($levels['free'],$u10),$u10);
/*
MULTI LEVEL
*/
if(function_exists('pmpro_addMembershipLevel')){
$u11 = pmprod_create_user('stacked@example.com');
pmpro_changeMembershipLevel(pmprod_get_full_level_array($levels['free'],$u11),$u11);
pmpro_addMembershipLevel($levels['monthly'],$u11);
}
}
function pmprod_assign_random_avatar($user_id){
if (get_user_meta($user_id, 'pmprod_avatar_url', true)) return;
$user = get_user_by('id', $user_id);
if (!$user) return;
// Deterministic seed
$seed = md5($user->user_email);
$response = wp_remote_get("https://randomuser.me/api/?seed=$seed&inc=picture");
if (is_wp_error($response)) return;
$body = json_decode(wp_remote_retrieve_body($response), true);
if (!empty($body['results'][0]['picture']['large'])) {
update_user_meta($user_id, 'pmprod_avatar_url',
esc_url_raw($body['results'][0]['picture']['large'])
);
}
}
/*
============================
AVATAR FILTER
============================
*/
add_filter('get_avatar_url', 'pmprod_randomuser_avatar', 10, 3);
function pmprod_randomuser_avatar($url, $id_or_email, $args){
$user = false;
if (is_numeric($id_or_email)) {
$user = get_user_by('id', $id_or_email);
} elseif (is_object($id_or_email)) {
if (!empty($id_or_email->user_id)) {
$user = get_user_by('id', $id_or_email->user_id);
} elseif (!empty($id_or_email->comment_author_email)) {
$user = get_user_by('email', $id_or_email->comment_author_email);
}
} elseif (is_string($id_or_email)) {
$user = get_user_by('email', $id_or_email);
}
if (!$user) return $url;
if (get_user_meta($user->ID, 'pmprod_demo_user', true) != 1) {
return $url;
}
$avatar = get_user_meta($user->ID, 'pmprod_avatar_url', true);
if (!empty($avatar)) {
return $avatar;
}
// fallback
return "https://api.dicebear.com/7.x/personas/svg?seed=" . $user->ID;
}
function pmprod_add_user_fields() {
// Safety check
if ( ! function_exists( 'pmpro_add_user_field' ) ) {
return;
}
$fields = [];
/*
============================
COMPANY
============================
*/
$fields[] = new PMPro_Field(
'company',
'text',
[
'label' => 'Company',
'size' => 40,
'class' => 'company',
'profile' => true,
'required' => false,
'showrequired'=> false,
'memberslistcsv' => true,
]
);
/*
============================
PHONE
============================
*/
$fields[] = new PMPro_Field(
'phone',
'text',
[
'label' => 'Phone Number',
'size' => 20,
'class' => 'phone',
'profile' => true,
'required' => false,
'showrequired'=> false,
'memberslistcsv' => true,
]
);
/*
============================
ACCOUNT MANAGER NOTES
============================
*/
$fields[] = new PMPro_Field(
'account_manager_notes',
'textarea',
[
'label' => 'Account Manager Notes',
'class' => 'notes',
'required' => false,
'showrequired'=> false,
]
);
/*
============================
ADD TO "More Information"
============================
*/
foreach ( $fields as $field ) {
pmpro_add_user_field(
'more_information',
$field
);
}
}
add_action( 'init', 'pmprod_add_user_fields' );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment