Plugin Directory

Changeset 3447263


Ignore:
Timestamp:
01/26/2026 05:16:34 PM (2 months ago)
Author:
wordpresschef
Message:

Update trunk - version 10.30.13

Location:
salon-booking-system/trunk
Files:
3 added
6 edited

Legend:

Unmodified
Added
Removed
  • salon-booking-system/trunk/readme.txt

    r3446244 r3447263  
    55Tested up to: 6.9
    66Requires PHP: 7.4.8
    7 Stable tag: 10.30.12
     7Stable tag: 10.30.13
    88License: GPLv2 or later
    99License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    409409== Changelog ==
    410410
     41126.01.2026 - 10.30.13
     412
     413* Minor fixes implemented
     414
    41141524.01.2026 - 10.30.12
    412416
  • salon-booking-system/trunk/salon.php

    r3446244 r3447263  
    44Plugin Name: Salon Booking System - Free Version
    55Description: Let your customers book you services through your website. Perfect for hairdressing salons, barber shops and beauty centers.
    6 Version: 10.30.12
     6Version: 10.30.13
    77Plugin URI: http://salonbookingsystem.com/
    88Author: Salon Booking System
     
    4646define('SLN_PLUGIN_DIR', untrailingslashit(dirname(__FILE__)));
    4747define('SLN_PLUGIN_URL', untrailingslashit(plugins_url('', __FILE__)));
    48 define('SLN_VERSION', '10.30.12');
     48define('SLN_VERSION', '10.30.13');
    4949define('SLN_STORE_URL', 'https://salonbookingsystem.com');
    5050define('SLN_AUTHOR', 'Salon Booking');
     
    250250
    251251register_activation_hook(__FILE__, function () {
     252    // Record activation time for churn analysis
     253    if (!get_option('sln_activation_time')) {
     254        update_option('sln_activation_time', current_time('timestamp'));
     255    }
     256   
    252257    // Track activation to salonbookingsystem.com
    253258    wp_remote_post('https://www.salonbookingsystem.com/wp-json/sbs-tracker/v1/activation', array(
     
    267272
    268273register_deactivation_hook(__FILE__, function () {
    269     // Track deactivation to salonbookingsystem.com
     274    // Track deactivation to salonbookingsystem.com with survey data
    270275    try {
     276        // Get survey data if available (set by AJAX handler)
     277        $survey_data = get_transient('sln_deactivation_survey_data');
     278       
     279        // Calculate activation metrics
     280        $activation_time = get_option('sln_activation_time', current_time('timestamp'));
     281        $days_active = floor((current_time('timestamp') - $activation_time) / DAY_IN_SECONDS);
     282       
     283        // Prepare payload
     284        $payload = array(
     285            'version' => defined('SLN_VERSION_PAY') && SLN_VERSION_PAY ? 'pro' : 'free',
     286            'plugin_version' => SLN_VERSION,
     287            'site_hash' => hash('sha256', home_url()),
     288            'days_active' => intval($days_active)
     289        );
     290       
     291        // Add survey data if available
     292        if ($survey_data) {
     293            $payload['deactivation_reason'] = isset($survey_data['reason']) ? $survey_data['reason'] : 'skipped';
     294            $payload['deactivation_feedback'] = isset($survey_data['feedback']) ? $survey_data['feedback'] : '';
     295            $payload['deactivation_rating'] = isset($survey_data['rating']) ? intval($survey_data['rating']) : 0;
     296            $payload['setup_progress'] = isset($survey_data['setup_progress']) ? intval($survey_data['setup_progress']) : 0;
     297            $payload['completed_first_booking'] = isset($survey_data['completed_first_booking']) ? (bool) $survey_data['completed_first_booking'] : false;
     298        } else {
     299            // No survey data - user skipped
     300            $payload['deactivation_reason'] = 'skipped';
     301            $payload['deactivation_feedback'] = '';
     302            $payload['deactivation_rating'] = 0;
     303            $payload['setup_progress'] = 0;
     304            $payload['completed_first_booking'] = false;
     305        }
     306       
    271307        wp_remote_post('https://www.salonbookingsystem.com/wp-json/sbs-tracker/v1/deactivation', array(
    272308            'blocking' => false,
    273309            'timeout' => 2,
    274310            'sslverify' => true,
    275             'body' => array(
    276                 'version' => defined('SLN_VERSION_PAY') && SLN_VERSION_PAY ? 'pro' : 'free',
    277                 'plugin_version' => SLN_VERSION,
    278                 'site_hash' => hash('sha256', home_url())
    279             )
     311            'body' => $payload
    280312        ));
     313       
     314        // Clean up transient
     315        delete_transient('sln_deactivation_survey_data');
     316       
    281317    } catch (Error $e) {
    282318        // Fail silently - don't break deactivation
  • salon-booking-system/trunk/src/SLN/Action/Init.php

    r3446244 r3447263  
    4343        $p = $this->plugin;
    4444        if(!defined("SLN_VERSION_CODECANYON") && defined("SLN_VERSION_PAY") && SLN_VERSION_PAY ) { $this->initLicense(); }
     45       
     46        // CRITICAL DEBUG: Log ALL booking status transitions to catch status reversion
     47        // Only logs when plugin debug mode is enabled (respects sln_debug_enabled option)
     48        add_action('transition_post_status', function($new_status, $old_status, $post) {
     49            if ($post->post_type === SLN_Plugin::POST_TYPE_BOOKING) {
     50                // Get the call stack to see what's triggering the status change
     51                $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10);
     52                $caller_info = array();
     53                foreach ($backtrace as $i => $trace) {
     54                    if (isset($trace['file']) && isset($trace['line'])) {
     55                        $caller_info[] = basename($trace['file']) . ':' . $trace['line'];
     56                    }
     57                }
     58               
     59                $context_flags = array();
     60                if (defined('DOING_AJAX') && DOING_AJAX) $context_flags[] = 'AJAX';
     61                if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) $context_flags[] = 'AUTOSAVE';
     62                if (defined('DOING_CRON') && DOING_CRON) $context_flags[] = 'CRON';
     63                $context = !empty($context_flags) ? ' [' . implode(',', $context_flags) . ']' : '';
     64               
     65                // Use plugin's standard logging (respects debug mode setting)
     66                SLN_Plugin::addLog(sprintf(
     67                    'BOOKING STATUS TRANSITION: #%d: %s → %s%s | Caller: %s',
     68                    $post->ID,
     69                    $old_status,
     70                    $new_status,
     71                    $context,
     72                    implode(' → ', array_slice($caller_info, 0, 3))
     73                ));
     74            }
     75        }, 10, 3);
    4576
    4677
     
    98129        new SLN_Admin_Reports($p);
    99130        new SLN_Admin_Settings($p);
     131        new SLN_Admin_DeactivationSurvey($p);
    100132       
    101133        // Cache Warmer Setup Notice
  • salon-booking-system/trunk/src/SLN/Metabox/Abstract.php

    r3185641 r3447263  
    8080    public function wp_insert_post_data($data, $postarr)
    8181    {
     82        // CRITICAL FIX: Prevent paid bookings from being reverted to auto-draft
     83        // This happens when WordPress auto-save tries to restore cached status
     84        if (isset($postarr['ID']) && $postarr['ID'] > 0) {
     85            $post = get_post($postarr['ID']);
     86           
     87            if ($post && $post->post_type === SLN_Plugin::POST_TYPE_BOOKING) {
     88                $current_status = get_post_status($postarr['ID']);
     89                $new_status = isset($data['post_status']) ? $data['post_status'] : '';
     90               
     91                // If booking is currently paid/confirmed, don't allow reverting to auto-draft/draft
     92                if (in_array($current_status, ['sln-b-paid', 'sln-b-confirmed'])) {
     93                    if (in_array($new_status, ['auto-draft', 'draft'])) {
     94                        // Log this attempted reversion (only when debug mode enabled)
     95                        $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 5);
     96                        $caller = isset($backtrace[1]) ? basename($backtrace[1]['file'] ?? 'unknown') . ':' . ($backtrace[1]['line'] ?? '?') : 'unknown';
     97                       
     98                        $context_flags = array();
     99                        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) $context_flags[] = 'AUTOSAVE';
     100                        if (defined('DOING_AJAX') && DOING_AJAX) $context_flags[] = 'AJAX';
     101                        $context = !empty($context_flags) ? ' [' . implode(',', $context_flags) . ']' : '';
     102                       
     103                        // Use plugin's standard logging (respects sln_debug_enabled option)
     104                        SLN_Plugin::addLog(sprintf(
     105                            '🛑 BLOCKED STATUS REVERSION! Booking #%d: %s → %s (attempted)%s | Caller: %s',
     106                            $postarr['ID'],
     107                            $current_status,
     108                            $new_status,
     109                            $context,
     110                            $caller
     111                        ));
     112                       
     113                        // Keep the current paid status instead
     114                        $data['post_status'] = $current_status;
     115                    }
     116                }
     117            }
     118        }
     119       
    82120        return $data;
    83121    }
  • salon-booking-system/trunk/src/SLN/Wrapper/Abstract.php

    r3437523 r3447263  
    8787    public function setStatus($status)
    8888    {
    89         // #region agent log
     89        // Debug logging (only when debug mode enabled)
    9090        $currentStatusBeforeCheck = $this->object->post_status;
    9191        $postObject = get_post($this->getId());
    92         file_put_contents('/Users/macbookpro/Desktop/Salon Booking System/development/bitbucket/.cursor/debug.log', json_encode(['timestamp'=>time()*1000,'location'=>'Wrapper/Abstract.php:89','message'=>'setStatus() ENTRY','data'=>['booking_id'=>$this->getId(),'target_status'=>$status,'current_status_from_object'=>$currentStatusBeforeCheck,'current_status_from_db'=>($postObject ? $postObject->post_status : 'null'),'post_date_from_db'=>($postObject ? $postObject->post_date : 'null'),'post_date_gmt_from_db'=>($postObject ? $postObject->post_date_gmt : 'null')],'sessionId'=>'debug-session','hypothesisId'=>'B,C']) . "\n", FILE_APPEND);
    93         // #endregion
     92        SLN_Plugin::addLog(sprintf(
     93            'setStatus() called for Booking #%d: %s → %s | DB status: %s, post_date_gmt: %s',
     94            $this->getId(),
     95            $currentStatusBeforeCheck,
     96            $status,
     97            $postObject ? $postObject->post_status : 'null',
     98            $postObject ? $postObject->post_date_gmt : 'null'
     99        ));
    94100       
    95101        $post = array();
     
    108114            $post['post_date_gmt'] = $now_gmt;
    109115           
    110             // #region agent log
    111             file_put_contents('/Users/macbookpro/Desktop/Salon Booking System/development/bitbucket/.cursor/debug.log', json_encode(['timestamp'=>time()*1000,'location'=>'Wrapper/Abstract.php:104','message'=>'AUTO-DRAFT FIX TRIGGERED','data'=>['booking_id'=>$this->getId(),'current_status'=>$currentStatus,'target_status'=>$status,'post_date_set'=>$now,'post_date_gmt_set'=>$now_gmt],'sessionId'=>'debug-session','hypothesisId'=>'B']) . "\n", FILE_APPEND);
    112             // #endregion
     116            // Debug logging (only when debug mode enabled)
     117            SLN_Plugin::addLog(sprintf(
     118                'AUTO-DRAFT FIX TRIGGERED for Booking #%d: Setting post_date=%s, post_date_gmt=%s',
     119                $this->getId(),
     120                $now,
     121                $now_gmt
     122            ));
    113123           
    114124            // Log the transition for debugging
     
    121131                ));
    122132            }
    123         } else {
    124             // #region agent log
    125             file_put_contents('/Users/macbookpro/Desktop/Salon Booking System/development/bitbucket/.cursor/debug.log', json_encode(['timestamp'=>time()*1000,'location'=>'Wrapper/Abstract.php:113','message'=>'AUTO-DRAFT FIX NOT TRIGGERED','data'=>['booking_id'=>$this->getId(),'current_status'=>$currentStatus,'target_status'=>$status,'condition_check'=>'currentStatus='.$currentStatus.' === auto-draft? '.($currentStatus === 'auto-draft' ? 'YES' : 'NO')],'sessionId'=>'debug-session','hypothesisId'=>'B']) . "\n", FILE_APPEND);
    126             // #endregion
    127         }
    128        
    129         // #region agent log
    130         file_put_contents('/Users/macbookpro/Desktop/Salon Booking System/development/bitbucket/.cursor/debug.log', json_encode(['timestamp'=>time()*1000,'location'=>'Wrapper/Abstract.php:116','message'=>'BEFORE wp_update_post()','data'=>['booking_id'=>$this->getId(),'post_array'=>$post],'sessionId'=>'debug-session','hypothesisId'=>'C']) . "\n", FILE_APPEND);
    131         // #endregion
     133        }
    132134       
    133135        $result = wp_update_post($post);
    134        
    135         // #region agent log
    136         file_put_contents('/Users/macbookpro/Desktop/Salon Booking System/development/bitbucket/.cursor/debug.log', json_encode(['timestamp'=>time()*1000,'location'=>'Wrapper/Abstract.php:120','message'=>'AFTER wp_update_post()','data'=>['booking_id'=>$this->getId(),'wp_update_post_result'=>$result,'is_wp_error'=>is_wp_error($result),'result_is_zero'=>($result === 0),'status_from_db_after'=>get_post_status($this->getId())],'sessionId'=>'debug-session','hypothesisId'=>'C']) . "\n", FILE_APPEND);
    137         // #endregion
    138136       
    139137        // CRITICAL: If wp_update_post fails, use direct database update as fallback
     
    151149            }
    152150           
    153             // #region agent log
    154             file_put_contents('/Users/macbookpro/Desktop/Salon Booking System/development/bitbucket/.cursor/debug.log', json_encode(['timestamp'=>time()*1000,'location'=>'Wrapper/Abstract.php:145','message'=>'wp_update_post FAILED - attempting direct DB update','data'=>['booking_id'=>$this->getId(),'wp_error'=>is_wp_error($result),'result'=>$result],'sessionId'=>'debug-session','hypothesisId'=>'D']) . "\n", FILE_APPEND);
    155             // #endregion
    156            
    157151            // Attempt direct database update as fallback
    158152            global $wpdb;
     
    176170                array('%d')
    177171            );
    178            
    179             // #region agent log
    180             file_put_contents('/Users/macbookpro/Desktop/Salon Booking System/development/bitbucket/.cursor/debug.log', json_encode(['timestamp'=>time()*1000,'location'=>'Wrapper/Abstract.php:170','message'=>'Direct DB update result','data'=>['booking_id'=>$this->getId(),'wpdb_result'=>$directResult,'wpdb_last_error'=>$wpdb->last_error,'status_from_db_after'=>get_post_status($this->getId())],'sessionId'=>'debug-session','hypothesisId'=>'D']) . "\n", FILE_APPEND);
    181             // #endregion
    182172           
    183173            if ($directResult !== false) {
     
    205195                    ));
    206196                }
    207                
    208                 // #region agent log
    209                 file_put_contents('/Users/macbookpro/Desktop/Salon Booking System/development/bitbucket/.cursor/debug.log', json_encode(['timestamp'=>time()*1000,'location'=>'Wrapper/Abstract.php:200','message'=>'CRITICAL: Both update methods failed','data'=>['booking_id'=>$this->getId(),'wpdb_last_error'=>$wpdb->last_error],'sessionId'=>'debug-session','hypothesisId'=>'D']) . "\n", FILE_APPEND);
    210                 // #endregion
    211197            }
    212198        }
  • salon-booking-system/trunk/src/SLN/Wrapper/Booking.php

    r3446244 r3447263  
    551551    public function markPaid($transactionId, $remainedAmount = 0)
    552552    {
    553         // #region agent log
    554         file_put_contents('/Users/macbookpro/Desktop/Salon Booking System/development/bitbucket/.cursor/debug.log', json_encode(['timestamp'=>time()*1000,'location'=>'Wrapper/Booking.php:495','message'=>'markPaid() ENTRY','data'=>['booking_id'=>$this->getId(),'current_status'=>$this->getStatus(),'transaction_id'=>$transactionId,'remained_amount'=>$remainedAmount],'sessionId'=>'debug-session','hypothesisId'=>'A']) . "\n", FILE_APPEND);
    555         // #endregion
     553        // Debug logging (only when debug mode enabled)
     554        SLN_Plugin::addLog(sprintf(
     555            'markPaid() called for Booking #%d: current_status=%s, transaction_id=%s',
     556            $this->getId(),
     557            $this->getStatus(),
     558            $transactionId
     559        ));
    556560       
    557561        $transactions = $this->getTransactionId();
     
    586590        }
    587591       
    588         // #region agent log
    589         file_put_contents('/Users/macbookpro/Desktop/Salon Booking System/development/bitbucket/.cursor/debug.log', json_encode(['timestamp'=>time()*1000,'location'=>'Wrapper/Booking.php:505','message'=>'BEFORE setStatus(PAID)','data'=>['booking_id'=>$this->getId(),'current_status'=>$this->getStatus(),'target_status'=>SLN_Enum_BookingStatus::PAID],'sessionId'=>'debug-session','hypothesisId'=>'A']) . "\n", FILE_APPEND);
    590         // #endregion
    591        
    592592        // Only change status if not already paid/confirmed
    593593        if (!in_array($this->getStatus(), [SLN_Enum_BookingStatus::PAID, SLN_Enum_BookingStatus::CONFIRMED])) {
     
    605605            ));
    606606        }
    607        
    608         // #region agent log
    609         file_put_contents('/Users/macbookpro/Desktop/Salon Booking System/development/bitbucket/.cursor/debug.log', json_encode(['timestamp'=>time()*1000,'location'=>'Wrapper/Booking.php:508','message'=>'AFTER setStatus(PAID)','data'=>['booking_id'=>$this->getId(),'status_from_object'=>$this->getStatus(),'status_from_db'=>get_post_status($this->getId())],'sessionId'=>'debug-session','hypothesisId'=>'A,D']) . "\n", FILE_APPEND);
    610         // #endregion
    611607
    612608    do_action('sln_booking_mark_paid_after', $this);
Note: See TracChangeset for help on using the changeset viewer.