Created
March 18, 2026 07:26
-
-
Save JarrydLong/7b5803c0c8b479ca805fe541ce0094d3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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