9c9
<    Time stamp: 2025-06-20 07:49:27
---
>    Time stamp: 2025-07-17 18:17:23
12,13c12,13
< # TODO: debugNonce should be enabled by option variable
< # TODO: make [exksc product-list] work correctly
---
> # TODO: document the differences between normal and standalone mode
> # TODO: make [exksc product-list] work correctly for GoHighLevel
15d14
< # TODO: Remove WishListMember code
39c38,39
<    Order processing # TODO: Update for Go High Level
---
>    Order processing
>    TODO: Create documentation for Go High Level and move it out of this source file.
131a132,139
>   # The determination about whether the code is being actively debugged (stored in
>   # $this->_debugging) is made as follows:
>   #   normal mode      the method conditionalDebug examines the option debug_user and
>   #                    calls either exkscEnableDebug or exkscDisableDebug according to whether
>   #                    the current user matches the condition specified in the option value.
>   #   standalone mode  the standalone code calls Exelana::implementStandalone, which in turn
>   #                    calls exkscStandalone passing $debug, which is saved in _debugging
> 
142c150,151
<   private $_debug_nonce;            // Nonce debugging
---
>   private $_debug_nonce;            // Nonce debugging (enabled from EXKSC_DEBUG)
>   private $_debugging;              // Actively debugging (see exkscEnableDebug and exkscStandalone)
152c161
<   public $_init_called;            // init function has been called
---
>   protected $_init_called;          // init function has been called
212a222,223
>     if (array_key_exists('bar',$param))
>       $init['bar'] = $param['bar'];
226a238
>     $this->_debugging = false;
255,261c267,273
< $this->_rfc_output = array();
< $this->_shipping = array();
< $this->_ty_create = false;
< $this->_user = null;
< $this->_user_id = null;
< $this->_uri = null;
< $this->_validated_merchant_id = null;
---
>     $this->_rfc_output = array();
>     $this->_shipping = array();
>     $this->_ty_create = false;
>     $this->_user = null;
>     $this->_user_id = null;
>     $this->_uri = null;
>     $this->_validated_merchant_id = null;
270c282
<       $this->addAction('init',array($this,'init'));
---
>       $this->addAction('init',array($this,'exkscInit'));
275c287
<       $this->addAction('init',array($this,'init'));
---
>       $this->addAction('init',array($this,'exkscInit'));
285a298
>   # TODO: nothing currently invokes this routine... use it or delete it
294,303d306
<   private function exkscInitVarsFromOptions()
<   {
<     if (is_callable('get_option'))
<     {
<       # _db_exit should only be set to die in a development environment
<       if ($this->_development)
<         $this->_db_exit = $this->get_option('exksc_db_die',false) ? 'die' : 'exit';
<     }
<   }
< 
313d315
<     $this->dieIfDeferred();
551a554,556
>     // The remaining code is disabled because KickStartCart has been deactivated
>     return;
> 
714a720,721
>     $this->exkscInit();
>     $this->_debugging = $debug;
718c725
<   public function init()
---
>   public function exkscInit() # fnDiff: match ExelanaKickStartCart::init
725a733,734
>     # TODO: remove temporary debugging (dieAfter)
>     $this->dieAfter(30);
727,728c736,740
<     $this->exkscInitVarsFromOptions();
<     $this->controlDumpAtShutdown();
---
> 
>     # Process EXKSC_DEBUG
>     $this->configureDebugging();
>     if ($this->_dump_at_shutdown['nonce'])
>       $this->_debug_nonce = true;
752a765,767
>     # Note: For standalone mode, whether debugging is turned on or not is determined based on the
>     # arguments passed to Exelana::implementStandalone and the _debugging variable is set in
>     # exkscStandalone.
794,809d808
<     // Include EVP code if Easy Video Player processing is enabled
<     $need_evp = false;
<     $evp_code = array();
<     if (!is_admin() && !$this->_ignore)
<     {
<       if ($this->getOption('evp_splash')
<        || $this->getOption('evp_track_ended')
<        || $this->getOption('evp_track_play')
<        || $this->getOption('evp_track_timeupdate'))
<       {
<         $need_evp = true;
<         $this->enqueueScript('exksc-evp-js','js/evp.js',array('evp','new EXEVP(exksc.utility)'),10);
<         array_push($evp_code,'exksc.code.init_evp()');
<       }
<     }
< 
861c860
<     return true;
---
>     return false; # true; KickStartCart has been deactivated
869c868
<   private function controlDumpAtShutdown()
---
>   private function configureDebugging()
887c886,892
<             $this->_dump_at_shutdown[$matches[1]] = (strtolower($matches[2]) == 'true') ? true : false;
---
>             if ($matches[1] == 'db-exit')
>             {
>               $this->_db_exit = (strtolower($matches[2]) == 'true') ? 'die' : 'exit';
>             } else {
>               $this->_dump_at_shutdown[$matches[1]] =
>                 (strtolower($matches[2]) == 'true') ? true : false;
>             }
909c914,915
<   # development then enable the necessary controls in EXKSC_DUMP during active debugging.
---
>   # development then enable the necessary controls in EXKSC_DUMP until you have comnpleted
>   # active debugging.
914c920
<       return;
---
>       return; # already requested
978,984c984,989
<     # TODO: These inits are necessary because they don't get called for a standalone
<     # implementation, but the real fix is to add it for standalone code.
<     $this->exkscInitDatabase();
<     $this->exkscInitAPI();
<     # Resume original code without the inits hack
< 
<     if (!$this->cartActive())
---
>     $runKickStartCart = false; # KickStartCart deactivated, but the product list is still in the
>                                # database. Using this variable to make it abundantly clear which
>                                # code is being disabled for this reason. There is no reason to
>                                # keep this variable once the code has been refactored to work
>                                # with GoHighLevel.
>     if ($runKickStartCart && !$this->cartActive())
994,995d998
<     $errors = ''; // Note: Only used by deprecated WLM code
< 
1014c1017
<       if (!array_key_exists($product['sku'],$catalog))
---
>       if ($runKickStartCart && !array_key_exists($product['sku'],$catalog))
1020c1023
<     $this->synchProducts($forceSynch);
---
>     if (false) $this->synchProducts($forceSynch);
1053,1113d1055
< /*
<     if (is_callable('wlmapi_get_level_pages'))
<     {
<       // Get the pages and posts for all levels associated with any product
<       $pages = array();
<       $posts = array();
<       foreach ($this->_dl_sku as $product)
<       {
<         $level = $product['level'];
<         if ($level != '' && !array_key_exists($level,$pages))
<         {
<           $result = wlmapi_get_level_pages($level);
<           if ($result['success'])
<             $pages[$level] = $result['pages']['page'];
<           $result = wlmapi_get_level_posts($level);
<           if ($result['success'])
<             $posts[$level] = $result['posts']['post'];
<         }
<       }
<       foreach ($this->_dl_sku as $product)
<       {
<         $level = $product['level'];
<         if ($level != '')
<         {
<           foreach ($product['items'] as $item)
<           {
<             $post_id = url_to_postid($item);
<             if ($post_id == 0)
<             {
<               $errors .= '<div class="updated notice"><p>'.$this->getPluginName().
<                 ': Page/post missing for SKU '.$product['sku'].'</p></div>';
<             } else {
<               $post = get_post($post_id);
<               if ($post->post_type == 'page')
<               {
<                 $found = false;
<                 foreach ($pages[$level] as $entry)
<                   if ($entry['ID'] == $post_id)
<                     $found = true;
<                 if (!$found)
<                 {
<                   $result = wlmapi_add_page_to_level($level,
<                     array('ContentIds' => array($post_id)));
<                 }
<               } else {
<                   $found = false;
<                 foreach ($posts[$level] as $entry)
<                   if ($entry['ID'] == $post_id)
<                     $found = true;
<                 if (!$found)
<                 {
<                   $result = wlmapi_add_post_to_level($level,
<                     array('ContentIds' => array($post_id)));
<                 }
<               }
<             }
<           }
<         }
<       }
<     }
< */
1143d1084
< #    $this->alwaysDebug("$fn: running");
1147d1087
< #      $this->alwaysDebug("$fn reason remote: ".$this->_debug_reason);
1156d1095
< #        $this->alwaysDebug("$fn reason case 0: ".$this->_debug_reason);
1164d1102
< #        $this->alwaysDebug("$fn reason case -3: ".$this->_debug_reason);
1169d1106
< #        $this->alwaysDebug("$fn reason case -2: ".$this->_debug_reason);
1177d1113
< #        $this->alwaysDebug("$fn reason case -1: ".$this->_debug_reason);
1186d1121
< #        $this->alwaysDebug("$fn reason case default: ".$this->_debug_reason);
1194d1128
< #    $this->alwaysDebug("debugging disabled");
1200c1134
< #    $this->alwaysDebug("debugging enabled");
---
>     $this->_debugging = true;
1456,1472d1389
<           $levels = array();
< /*
<           if ($logged_in && is_callable('wlmapi_get_member_levels'))
<           {
<             $wlm_levels = wlmapi_get_member_levels($this->_user_id);
<             # $this->debug($this->export($levels));
<             foreach ($wlm_levels as $level)
<             {
<               if (is_a($level,'stdClass'))
<                 $level = (array)$level;
<               # $this->debug('Level: '.$this->export($level));
<               if ($level['Active'] == 'true')
<                 $levels[$level['Name']] = $level;
<             }
<           }
<           # $this->debug('Levels: '.join(',',array_keys($levels)));
< */
1486,1487d1402
< #            else if ($item['state'] == 'level' && array_key_exists($item['level'],$levels))
< #              $show = true;
1894a1810,1829
>     # [exksc product-link attributes]
>     # Returns link to add product to shopping cart
>     # For example: [exksc product-link sku=9999 price=99.99]
>     } elseif ($keys[0] == 'product-link-new') {
>       $this->requestDumpAtShutdown('product-link','shortcode product-link'); # TODO: remove
>       $search = array();
>       for ($i = 1; $i < count($keys); $i++)
>         $search[$keys[$i]] = $attr[$keys[$i]];
> 
>       $products = $this->getProductsWithURL($search,$reason);
>       $this->debugData("$fn: getProductsWithURL result",$products);
>       if (count($products) == 0)
>       {
>         $error = preg_replace(array('/^\[exksc\s+product-link\s+/','/\]$/'),'',$raw);
>         $message = str_replace('$1',$error,__('No product matches "$1"','exksc'));
>         $this->addBarEvent('error',$message.($reason == '' ? '' : "; $reason"));
>         return $this->_shortcodeOutput($raw,"<span style='color:red'>$message</span><a href='#'>");
>       }
>       return $this->_shortcodeOutput($raw,'<a href="'.$products[0]['url'].'" target=_blank>');
> 
1991c1926
<         $this->requestDumpAtShutdown('page_view_id','page_view_id is null');
---
>         $this->requestDumpAtShutdown('page-view-id','page_view_id is null');
2407,2409c2342,2353
<     $output = str_replace(array('%t',                            '%v'),
<                           array(substr($cond['text'],$cond['p']),$cond['value']),
<               $this->_rfcHistoryArray($content));
---
>     $fn = $this->start();
>     if (!is_array($content))
>       $content = array($content);
>     for ($i = 0; $i < count($content); $i++)
>     {
>       $output = $content[$i];
>       if (strpos($output,'%t') >= 0 && array_key_exists('text',$cond))
>         $output = str_replace('%t',$cond['text'],$output);
>       if (strpos($output,'%p') >= 0 && array_key_exists('p',$cond))
>         $output = str_replace('%p',$cond['p'],$output);
>       if (strpos($output,'%v') >= 0 && array_key_exists('value',$cond))
>         $output = str_replace('%v',$this->export($cond['value']),$output);
2411c2355
<       $output .= " <span style='color:red'>error</span>";
---
>         $output = "<span style='color:red'>$output</span>";
2412a2357,2359
> if (strpos($output,'null') > 0)
>   $this->progressWriteExport("$fn: #CHECK# null in output",'$content',$content,'$output',$output,'$cond',$cond);
>     }
3185c3132
<     $this->_last_error = ''; # TODO: should this really only work once?
---
>     $this->_last_error = '';
3225c3172
<     $catalog = $this->db->get_rows('product','');
---
>     $catalog = $this->db->get_rowsA('product','');
3262c3209
<     $order_has_client = $this->db->get_rows('order_has_client',
---
>     $order_has_client = $this->db->get_rowsA('order_has_client',
3349,3367d3295
< /*
<   private function _productGrantAccess($sku)
<   {
<     $fn = $this->start();
<     $this->initDownloads();
<     if (array_key_exists($sku,$this->_dl_sku))
<     {
<       $level = $this->_dl_sku[$sku]['level'];
<       if ($level != '' && $this->_user_id != 0 && is_callable('wlmapi_get_member_levels'))
<       {
<         $found = false;
<         $wlm_levels = wlmapi_get_member_levels($this->_user_id);
<         foreach ($wlm_levels as $wlm_level)
<           if ($wlm_level->Level_ID == $level)
<             $found = true;
<         if (!$found)
<           $result = wlmapi_add_member_to_level($level, array('Users' => array($this->_user_id)));
<       }
<     }
3369,3375d3296
<     if ($this->_dl_sku[$sku]['type'] == 'page')
<     {
<       // TODO: make sure the user has access to the page
<       // Ticket opened 8/2/18
<     }
<   }
< */
3692,3702d3612
< /*        $level = $this->_dl_sku[$sku]['level'];
<         if ($level != '' && $this->_user_id != 0 && is_callable('wlmapi_get_member_levels'))
<         {
<           $found = false;
<           $wlm_levels = wlmapi_get_member_levels($this->user_id);
<           foreach ($wlm_levels as $wlm_level)
<             if ($wlm_level->Level_ID == $level)
<               $found = true;
<           if (!$found)
<             $result = wlmapi_add_member_to_level($level, array('Users' => array($this->user_id)));
<         } */
3705c3615
<           $products .= $this->_thank_you_product($order,$order['item'][$i]['product']);
---
>           $products .= $this->_thankYouProduct($order,$order['item'][$i]['product']);
3740,3741c3650
<   # TODO: why underscores?
<   protected function _thank_you_product($order,$product)
---
>   protected function _thankYouProduct($order,$product)
4121c4030
<             'reason'=>$this->_logToNonce('Invalid nonce; refresh the page and try again',true)));
---
>             'reason'=>$this->_logNonce('Invalid nonce; refresh the page and try again',true)));
4183c4092
<                 'reason'=>$this->_logToNonce('refresh: invalid page nonce',true)));
---
>                 'reason'=>$this->_logNonce('refresh: invalid page nonce',true)));
4192c4101
<                 'reason'=>$this->_logToNonce('refresh: invalid page video nonce',true)));
---
>                 'reason'=>$this->_logNonce('refresh: invalid page video nonce',true)));
4203c4112
<                 'reason'=>$this->_logToNonce('refresh: invalid video nonce',true)));
---
>                 'reason'=>$this->_logNonce('refresh: invalid video nonce',true)));
4415c4324
<         'reason'=>$this->_logToNonce('invalid page video nonce',true)));
---
>         'reason'=>$this->_logNonce('invalid page video nonce',true)));
4427c4336
<             'reason'=>$this->_logToNonce('invalid video nonce',true)));
---
>             'reason'=>$this->_logNonce('invalid video nonce',true)));
4432c4341
<           'reason'=>$this->_logToNonce('expecting video nonce for '.$request['video']['type'])));
---
>           'reason'=>$this->_logNonce('expecting video nonce for '.$request['video']['type'])));
4502,4516d4410
< /*
<     if (is_callable('wlmapi_add_member_to_level'))
<     {
<       $member_level = $this->getOption('member_level');
<       if ($member_level != '')
<       {
<         $result = wlmapi_add_member_to_level($member_level,array('Users' => array($this->_user_id)));
<         $this->debug("$fn: wlmapi_add_member_to_level() => ".$this->export($result));
<         if (!$result['success'])
<           $this->_ajaxResponse(array('result'=>false,'reason'=>'add user to WLM failed: '.
<             $result['ERROR']));
<       }
<     }
< */
< 
4636c4530
<         'reason'=>$this->_logToNonce("Invalid login nonce",true)));
---
>         'reason'=>$this->_logNonce("Invalid login nonce",true)));
4788c4682
<       $client = $this->db->get_rows('leads',array('machine_id' => $this->getMachineID()));
---
>       $client = $this->db->get_rowsA('leads',array('machine_id' => $this->getMachineID()));
4901d4794
<     # TODO: remove this code or add setting to enable/disable nonce debugging
4923d4815
<     # TODO: remove this code or add setting to enable/disable nonce debugging
4940c4832
<     $dn = $this->start();
---
>     $fn = $this->start();
4943,4944d4834
<     // Note: wp_verify_nonce returns 1, 2, or null (meaning not verified); log will
<     // contain 'true' for 1 or 2 and 'false' for null
4946c4836
<     $this->_logToNonce("nonce:$action,$fn,$type,".
---
>     $this->_logNonce("nonce:$action,$fn,$type,".
4951c4841
<   private function _logToNonce($s,$dump=false)
---
>   private function _logNonce($s,$dump=false)
4952a4843,4845
>     if (!$this->_debug_nonce)
>       return $s;
> 
4961c4854
<       $this->requestDumpAtShutdown('nonce',"_logToNonce: $s");
---
>       $this->requestDumpAtShutdown('nonce',"_logNonce: $s");
5027c4920
<       if ($rows === false)
---
>       if ($rows === false || count($rows) == 0)
5066c4959
<     if ($this->_current_client === false)
---
>     if ($this->_current_client === false || count($this->_current_client) == 0)
5070c4963
<     $result = $this->db->get_rowA('user',array('wp_user_id'=>$this->_user_id));
---
>     $result = $this->db->get_rowA('user',array('wp_user_id' => $this->_user_id));
5348c5241
<       $order_has_item = $this->db->get_rows('order_has_item',array('order_id' => $order_id));
---
>       $order_has_item = $this->db->get_rowsA('order_has_item',array('order_id' => $order_id));
6018c5911,5912
<     if (!$this->cartActive())
---
>     # Note: cartActive now always returns false because KickStartCart has been deactivated
>     if (false && !$this->cartActive()) # TODO: update for GoHighLevel
6074c5968,5973
<         $product['url'] = '/cmd.php?pid='.$product['pid'];
---
>         # The following is what was done for KickStartCart
>         # $product['url'] = '/cmd.php?pid='.$product['pid'];
>         #########################################################################################
>         # New temporary code for transition to GoHighLevel
>         $product['url'] = 'https://store.theinvinciblemindsettrainer.com/product-details/product/6823e37fe4798a47349e7ce2?impax_host=1';
>         #########################################################################################
6314c6213,6214
<     $pathOnly = (array_key_exists('path',$_GET)) ? $_GET['path'] : false;
---
>     $pathOnly = (array_key_exists('path',$_GET)) ?
>                   ($_GET['path'] == 'true' ? true : false) : false;
6438,6450d6337
< /*
<         $level = $this->_dl_sku[$sku]['level'];
<         if ($level != '' && $this->_user_id != 0 && is_callable('wlmapi_get_member_levels'))
<         {
<           $found = false;
<           $wlm_levels = wlmapi_get_member_levels($this->_user_id);
<           foreach ($wlm_levels as $wlm_level)
<             if ($wlm_level->Level_ID == $level)
<               $found = true;
<           if (!$found)
<             return $this->_downloadMessage('download_dir','message_access_denied');
<         }
< */
