Advanced Web Server Manager
Complete File Manager & Terminal - Standalone Version
By Sid Gifari | Gifari Industries
Current path:
/
/
home
/
qtdcvxyp
/
public_html
/
wp-content
/
plugins
/
star4hire-core
/
includes
✏️
Editing: class-s4h-program-packages.php
<?php if ( ! defined( 'ABSPATH' ) ) { exit; } /** Editable master promises for each programme. Cloned into each enrollment, then customizable per participant. */ class S4H_Program_Packages { const OPT='s4h_program_package_master_v1'; const CONSULT_MIGRATION_OPT='s4h_included_consultation_migration'; const CONSULT_MIGRATION_VERSION='1.10.1'; const CONSULT_SERVICE_NAME='1-on-1 Career GPS Consultation'; public static function init(){add_action('admin_menu',array(__CLASS__,'menu'),46);add_action('admin_init',array(__CLASS__,'handle'));} public static function menu(){add_submenu_page('s4h-core','Program Package Master','Program Packages','manage_s4h','s4h-program-packages',array(__CLASS__,'page'));} public static function defaults(){ $out=array(); if(!class_exists('S4H_Success'))return $out; foreach(S4H_Success::programs() as $key=>$program){ $out[$key]=array('documents'=>S4H_Success::default_documents(),'services'=>array()); foreach(S4H_Success::default_services($key) as $svc)$out[$key]['services'][]=array('service_name'=>$svc['service_name'],'service_type'=>$svc['service_type'],'included_qty'=>isset($svc['included_qty'])?(float)$svc['included_qty']:1,'unit_label'=>$svc['unit_label']??'service','public_note'=>$svc['public_note']??''); } return $out; } public static function consultation_item(){ return array( 'service_name'=>self::CONSULT_SERVICE_NAME, 'service_type'=>'career', 'included_qty'=>2, 'unit_label'=>'session', 'public_note'=>'2 one-on-one Career GPS sessions are included with this programme. Additional sessions are Rp200,000/session unless otherwise agreed.', ); } public static function is_consultation_service($service){ $name=is_object($service)?($service->service_name??''):($service['service_name']??''); return strtolower(trim((string)$name))===strtolower(self::CONSULT_SERVICE_NAME); } public static function maybe_migrate_included_consultations(){ if(get_option(self::CONSULT_MIGRATION_OPT)==self::CONSULT_MIGRATION_VERSION)return; // 1) Add the entitlement to every programme package without overwriting custom items. $all=self::all();$item=self::consultation_item();$changed=false; foreach(S4H_Success::programs() as $key=>$program){ if(!isset($all[$key]))$all[$key]=array('documents'=>array(),'services'=>array()); if(!isset($all[$key]['services'])||!is_array($all[$key]['services']))$all[$key]['services']=array(); $exists=false;foreach($all[$key]['services'] as $svc){if(self::is_consultation_service($svc)){$exists=true;break;}} if(!$exists){$all[$key]['services'][]=$item;$changed=true;} } if($changed)update_option(self::OPT,$all,false); // 2) Backfill existing active enrollments. Idempotent: existing consultation entitlements are never duplicated. global $wpdb;$t=S4H_DB::tables();$offset=0;$batch=200;$guard=0; do{ $rows=$wpdb->get_results($wpdb->prepare("SELECT * FROM {$t['program_enrollments']} WHERE status='active' ORDER BY id ASC LIMIT %d OFFSET %d",$batch,$offset)); if(!$rows)break; foreach($rows as $e){ $services=S4H_DB::service_entitlements_for_enrollment($e->id);$exists=false; foreach($services as $svc){if(self::is_consultation_service($svc)){$exists=true;break;}} if($exists)continue; S4H_DB::create_service_entitlement(array( 'enrollment_db_id'=>$e->id,'talent_db_id'=>$e->talent_db_id,'talent_id'=>$e->talent_id, 'service_name'=>$item['service_name'],'service_type'=>$item['service_type'],'included_qty'=>$item['included_qty'], 'used_qty'=>0,'unit_label'=>$item['unit_label'],'status'=>'active','public_note'=>$item['public_note'],'created_by'=>0, )); } $offset+=count($rows);$guard++; }while(count($rows)===$batch && $guard<50); update_option(self::CONSULT_MIGRATION_OPT,self::CONSULT_MIGRATION_VERSION,false); } public static function all(){ $saved=get_option(self::OPT,array());$base=self::defaults();if(!is_array($saved))$saved=array(); foreach($saved as $key=>$pkg){if(!isset($base[$key]))$base[$key]=array('documents'=>array(),'services'=>array());foreach(array('documents','services') as $type)if(isset($pkg[$type])&&is_array($pkg[$type]))$base[$key][$type]=$pkg[$type];} return $base; } public static function package($program_key){$all=self::all();return $all[$program_key]??array('documents'=>array(),'services'=>array());} public static function handle(){ if(empty($_POST['s4h_package_action'])||!current_user_can('manage_s4h'))return;check_admin_referer('s4h_program_packages');$action=sanitize_key($_POST['s4h_package_action']);$program=sanitize_key($_POST['program_key']??'');$all=self::all();if(!isset($all[$program]))$all[$program]=array('documents'=>array(),'services'=>array()); if($action==='add_service'){ $name=sanitize_text_field(wp_unslash($_POST['service_name']??''));if($name)$all[$program]['services'][]=array('service_name'=>$name,'service_type'=>sanitize_key($_POST['service_type']??'service'),'included_qty'=>max(0,(float)($_POST['included_qty']??1)),'unit_label'=>sanitize_text_field(wp_unslash($_POST['unit_label']??'service')),'public_note'=>sanitize_text_field(wp_unslash($_POST['public_note']??''))); }elseif($action==='add_document'){ $label=sanitize_text_field(wp_unslash($_POST['label']??''));if($label)$all[$program]['documents'][]=array('doc_key'=>sanitize_key($_POST['doc_key']??sanitize_title($label)),'label'=>$label); }elseif($action==='delete_service'){ $i=absint($_POST['index']??-1);if(isset($all[$program]['services'][$i]))array_splice($all[$program]['services'],$i,1); }elseif($action==='delete_document'){ $i=absint($_POST['index']??-1);if(isset($all[$program]['documents'][$i]))array_splice($all[$program]['documents'],$i,1); }elseif($action==='reset_program'){ $defs=self::defaults();$all[$program]=$defs[$program]??array('documents'=>array(),'services'=>array()); } update_option(self::OPT,$all,false);S4H_DB::audit(get_current_user_id(),'program_package_updated','program_package',0,'',array('program_key'=>$program,'action'=>$action));wp_safe_redirect(admin_url('admin.php?page=s4h-program-packages&program='.$program.'&saved=1'));exit; } private static function form_hidden($action,$program,$index=null){wp_nonce_field('s4h_program_packages');echo '<input type="hidden" name="s4h_package_action" value="'.esc_attr($action).'"><input type="hidden" name="program_key" value="'.esc_attr($program).'">';if($index!==null)echo '<input type="hidden" name="index" value="'.esc_attr($index).'">';} public static function page(){ if(!current_user_can('manage_s4h'))return;$programs=S4H_Success::programs();$selected=sanitize_key($_GET['program']??'tnd');if(!isset($programs[$selected]))$selected=array_key_first($programs);$pkg=self::package($selected); echo '<div class="wrap"><h1>Program Package Master</h1><p>Define what is promised by each programme once. On enrollment, STAR4Hire clones this package into the participant case; the participant copy can then be customized without changing the master. Keep the master aligned with the signed enrollment agreement.</p><p><strong>Default consultation policy:</strong> each programme includes 2 one-on-one Career GPS consultation sessions. Edit the quantity or remove the item here if a specific programme agreement is different.</p>'; if(!empty($_GET['saved']))echo '<div class="notice notice-success"><p>Package master updated.</p></div>'; echo '<form method="get"><input type="hidden" name="page" value="s4h-program-packages"><label><strong>Programme</strong> <select name="program" onchange="this.form.submit()">';foreach($programs as $k=>$v)echo '<option value="'.esc_attr($k).'" '.selected($k,$selected,false).'>'.esc_html($v['label']).'</option>';echo '</select></label></form>'; echo '<h2>Included Services / Classes / Merchandise</h2><table class="widefat striped"><thead><tr><th>Item</th><th>Type</th><th>Included</th><th>Unit</th><th>Participant note</th><th></th></tr></thead><tbody>'; foreach($pkg['services'] as $i=>$svc){echo '<tr><td><strong>'.esc_html($svc['service_name']).'</strong></td><td>'.esc_html($svc['service_type']).'</td><td>'.esc_html($svc['included_qty']).'</td><td>'.esc_html($svc['unit_label']).'</td><td>'.esc_html($svc['public_note']??'').'</td><td><form method="post">';self::form_hidden('delete_service',$selected,$i);echo '<button class="button-link-delete" onclick="return confirm(\'Remove this master item?\')">Remove</button></form></td></tr>';} if(!$pkg['services'])echo '<tr><td colspan="6">No service items yet.</td></tr>';echo '</tbody></table>'; echo '<form method="post" style="background:#fff;padding:14px;margin:12px 0">';self::form_hidden('add_service',$selected);echo '<strong>Add master item</strong><p><label>Item <input required name="service_name" placeholder="T-Shirt / Theory Class / Practice Class"></label> <label>Type <select name="service_type"><option value="merchandise">Merchandise</option><option value="learning">Learning/Class</option><option value="career">Career</option><option value="placement">Placement</option><option value="education">Education</option><option value="mobility">Mobility/Visa</option><option value="service">Other</option></select></label> <label>Included <input type="number" min="0" step="0.1" name="included_qty" value="1" style="width:75px"></label> <label>Unit <input name="unit_label" value="service" style="width:100px"></label> <label>Participant note <input name="public_note" class="regular-text"></label> <button class="button button-primary">Add</button></p></form>'; echo '<h2>Required Documents</h2><table class="widefat striped"><thead><tr><th>Document</th><th>Key</th><th></th></tr></thead><tbody>';foreach($pkg['documents'] as $i=>$doc){echo '<tr><td>'.esc_html($doc['label']).'</td><td><code>'.esc_html($doc['doc_key']).'</code></td><td><form method="post">';self::form_hidden('delete_document',$selected,$i);echo '<button class="button-link-delete" onclick="return confirm(\'Remove this master document?\')">Remove</button></form></td></tr>';}if(!$pkg['documents'])echo '<tr><td colspan="3">No document requirements yet.</td></tr>';echo '</tbody></table>'; echo '<form method="post" style="background:#fff;padding:14px;margin:12px 0">';self::form_hidden('add_document',$selected);echo '<strong>Add document</strong><p><label>Label <input required name="label" placeholder="Passport"></label> <label>Key <input name="doc_key" placeholder="passport"></label> <button class="button button-primary">Add</button></p></form>'; echo '<form method="post" style="margin-top:20px">';self::form_hidden('reset_program',$selected);echo '<button class="button" onclick="return confirm(\'Reset this program to starter defaults?\')">Reset to Starter Defaults</button></form></div>'; } }
💾 Save Changes
❌ Cancel