SHARE
TWEET

Woocommerce Order_Barcodes

a guest Mar 27th, 2017 202 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <?php
  2.  
  3. if ( ! defined( 'ABSPATH' ) ) exit;
  4.  
  5. class WooCommerce_Order_Barcodes {
  6.  
  7.     /**
  8.      * The single instance of WooCommerce_Order_Barcodes.
  9.      * @var     object
  10.      * @access  private
  11.      * @since   1.0.0
  12.      */
  13.     private static $_instance = null;
  14.  
  15.     /**
  16.      * Settings class object
  17.      * @var     object
  18.      * @access  public
  19.      * @since   1.0.0
  20.      */
  21.     public $settings = null;
  22.  
  23.     /**
  24.      * The version number.
  25.      * @var     string
  26.      * @access  public
  27.      * @since   1.0.0
  28.      */
  29.     public $_version;
  30.  
  31.     /**
  32.      * The token.
  33.      * @var     string
  34.      * @access  public
  35.      * @since   1.0.0
  36.      */
  37.     public $_token;
  38.  
  39.     /**
  40.      * The main plugin file.
  41.      * @var     string
  42.      * @access  public
  43.      * @since   1.0.0
  44.      */
  45.     public $file;
  46.  
  47.     /**
  48.      * The main plugin directory.
  49.      * @var     string
  50.      * @access  public
  51.      * @since   1.0.0
  52.      */
  53.     public $dir;
  54.  
  55.     /**
  56.      * The plugin assets directory.
  57.      * @var     string
  58.      * @access  public
  59.      * @since   1.0.0
  60.      */
  61.     public $assets_dir;
  62.  
  63.     /**
  64.      * The plugin assets URL.
  65.      * @var     string
  66.      * @access  public
  67.      * @since   1.0.0
  68.      */
  69.     public $assets_url;
  70.  
  71.     /**
  72.      * Suffix for Javascripts.
  73.      * @var     string
  74.      * @access  public
  75.      * @since   1.0.0
  76.      */
  77.     public $script_suffix;
  78.  
  79.     /**
  80.      * Type of barcode to be used.
  81.      * @var     string
  82.      * @access  public
  83.      * @since   1.0.0
  84.      */
  85.     public $barcode_type = 'code128';
  86.  
  87.     /**
  88.      * Color of barcode.
  89.      * @var     string
  90.      * @access  public
  91.      * @since   1.0.0
  92.      */
  93.     public $barcode_colours = array( 'foreground' => '#000000', 'background' => '#FFFFFF' );
  94.  
  95.     /**
  96.      * Constructor function.
  97.      * @access  public
  98.      * @since   1.0.0
  99.      * @param   string $file    Plugin file
  100.      * @param   string $version Plugin version
  101.      * @return  void
  102.      */
  103.     public function __construct ( $file = '', $version = '1.0.0' ) {
  104.  
  105.         // Set plugin data
  106.         $this->_version = $version;
  107.         $this->_token = 'woocommerce_order_barcodes';
  108.  
  109.         // Set global variables
  110.         $this->file = $file;
  111.         $this->dir = dirname( $this->file );
  112.         $this->assets_dir = trailingslashit( $this->dir ) . 'assets';
  113.         $this->assets_url = esc_url( trailingslashit( plugins_url( '/assets/', $this->file ) ) );
  114.         $this->script_suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
  115.  
  116.         // Apply plugin settings
  117.         $this->barcode_enable = get_option( 'wc_order_barcodes_enable', 'yes' );
  118.         $this->barcode_type = get_option( 'wc_order_barcodes_type', 'code128' );
  119.         $this->barcode_colours = get_option( 'wc_order_barcodes_colours', array( 'foreground' => '#000000', 'background' => '#FFFFFF' ) );
  120.  
  121.         // Run installation function
  122.         register_activation_hook( $this->file, array( $this, 'install' ) );
  123.  
  124.         // Register JS
  125.         add_action( 'admin_enqueue_scripts', array( $this, 'register_assets' ), 1 );
  126.         add_action( 'wp_enqueue_scripts', array( $this, 'register_assets' ), 1 );
  127.  
  128.         // Add barcode to order complete email
  129.         add_action( 'woocommerce_email_after_order_table', array( $this, 'get_email_barcode' ), 1, 1 );
  130.         add_action( 'init', array( $this, 'get_barcode_image' ), 1 );
  131.  
  132.         // Display barcode on order details page
  133.         add_action( 'woocommerce_order_details_after_order_table', array( $this, 'get_display_barcode' ), 1, 1 );
  134.  
  135.         // Display barcode on order edit screen
  136.         add_action( 'add_meta_boxes', array( $this, 'add_order_metabox' ), 30 );
  137.  
  138.         // Generate and save barcode as order meta
  139.         add_action( 'woocommerce_after_checkout_form', array( $this, 'generate_barcode_checkout' ) );
  140.         add_action( 'woocommerce_after_order_notes', array( $this, 'add_checkout_fields' ), 1, 1 );
  141.         add_action( 'woocommerce_new_order', array( $this, 'update_order_meta' ), 1, 1 );
  142.         add_action( 'woocommerce_resume_order', array( $this, 'update_order_meta' ), 1, 1 );
  143.  
  144.         // Save barcode from order edit screen
  145.         add_action( 'wp_ajax_save_barcode', array( $this, 'save_barcode' ) );
  146.         add_action( 'wp_ajax_nopriv_save_barcode', array( $this, 'save_barcode' ) );
  147.  
  148.         // Add shortcode for barcode scanner
  149.         add_shortcode( 'scan_barcode', array( $this, 'barcode_scan_form' ) );
  150.  
  151.         // Process barcode input/scan
  152.         add_action( 'wp_ajax_scan_barcode', array( $this, 'scan_barcode' ) );
  153.         add_action( 'wp_ajax_nopriv_scan_barcode', array( $this, 'scan_barcode' ) );
  154.  
  155.         // Add check in status drop down to order edit screen
  156.         add_action( 'woocommerce_admin_order_data_after_order_details', array( $this, 'checkin_status_edit_field' ), 10, 1 );
  157.         add_action( 'woocommerce_process_shop_order_meta', array( $this, 'checkin_status_edit_save' ), 40, 2 );
  158.  
  159.         // Handle localisation
  160.         $this->load_plugin_textdomain();
  161.         add_action( 'init', array( $this, 'load_localisation' ), 0 );
  162.  
  163.     } // End __construct ()
  164.  
  165.     /**
  166.      * Add barcode fields to checkout form
  167.      * @access  public
  168.      * @since   1.0.0
  169.      * @param   object $checkout Checkout object
  170.      * @return  void
  171.      */
  172.     public function add_checkout_fields ( $checkout ) {
  173.  
  174.         if( 'yes' != $this->barcode_enable ) {
  175.             return;
  176.         }
  177.  
  178.         // Prepare barcode image
  179.         woocommerce_form_field( 'order_barcode_image', array(
  180.             'type'  => 'text',
  181.             'class' => array( 'order_barcode_image' ),
  182.         ), $checkout->get_value( 'order_barcode_image' ) );
  183.  
  184.         // Prepare barcode text
  185.         woocommerce_form_field( 'order_barcode_text', array(
  186.             'type'  => 'text',
  187.             'class' => array( 'order_barcode_text' ),
  188.         ), $checkout->get_value( 'order_barcode_text' ) );
  189.  
  190.     } //End add_checkout_fields ()
  191.  
  192.     /**
  193.      * Add barcode to order meta
  194.      * @access  public
  195.      * @since   1.0.0
  196.      * @param   integer $order_id Order ID
  197.      * @return  void
  198.      */
  199.     public function update_order_meta ( $order_id = 0 ) {
  200.  
  201.         // Only run if barcodes are enabled
  202.         if( 'yes' != $this->barcode_enable ) {
  203.             return;
  204.         }
  205.  
  206.         // Add encoded barcode image to order
  207.         if ( isset( $_POST['order_barcode_image'] ) && ! empty( $_POST['order_barcode_image'] ) ) {
  208.             update_post_meta( $order_id, '_barcode_image', $_POST['order_barcode_image'] );
  209.         }
  210.  
  211.         // Add barcode text to order
  212.         if ( isset( $_POST['order_barcode_text'] ) && ! empty( $_POST['order_barcode_text'] ) ) {
  213.             update_post_meta( $order_id, '_barcode_text', $_POST['order_barcode_text'] );
  214.         }
  215.  
  216.         // Add order note
  217.         $order = new WC_Order( $order_id );
  218.         $barcode_url = $this->barcode_url( $order_id );
  219.         $order_note = sprintf( __( 'Barcode generated successfully: %s', 'woocommerce-order-barcodes' ), '<a href="' . esc_url( $barcode_url ) . '" target="_blank">' . $barcode_url . '</a>' );
  220.         $order->add_order_note( $order_note );
  221.  
  222.     } // End update_order_meta ()
  223.  
  224.     /**
  225.      * Generate barcode on checkout page
  226.      * @access  public
  227.      * @since   1.0.0
  228.      * @return  void
  229.      */
  230.     public function generate_barcode_checkout () {
  231.         $this->generate_barcode( 'checkout' );
  232.     }
  233.  
  234.     /**
  235.      * Generate unique barcode
  236.      * @access  public
  237.      * @since   1.0.0
  238.      * @return  void
  239.      */
  240.     public function generate_barcode ( $context = 'checkout' ) {
  241.  
  242.         if( 'yes' != $this->barcode_enable ) {
  243.             return;
  244.         }
  245.  
  246.         // Load JS & CSS needed for barcode generation
  247.         $this->load_barcode_assets();
  248.  
  249.         // Get unqiue barcode string
  250.         $barcode_string = $this->get_barcode_string();
  251.  
  252.         // Generate barcode image based on string and selected type
  253.         switch( $this->barcode_type ) {
  254.             case 'qr':
  255.  
  256.                 // Build up JS for QR code generation
  257.                 $js = "$( '#barcode_container' ).qrcode( { text: '" . $barcode_string . "', label: '" . $barcode_string . "', fill: '" . $this->barcode_colours['foreground'] . "', background: '" . $this->barcode_colours['background'] . "', render: 'image', width: 100, height: 100 } );";
  258.                 $barcode_obj = array( 'img', 'src' );
  259.  
  260.             break;
  261.             default:
  262.  
  263.                 // Set extra data for certain barcode types
  264.                 switch( $this->barcode_type ) {
  265.                     case 'code93': $data_tail = ', crc: true'; break;
  266.                     case 'datamatrix': $data_tail = ', rect: false';
  267.                     default: $data_tail = '';
  268.                 }
  269.  
  270.                 // Build up JS for barcode generation
  271.                 $js = "$( '#barcode_container' ).barcode( { code: '" . $barcode_string . "'" . $data_tail . " }, '" . $this->barcode_type . "', { color: '" . $this->barcode_colours['foreground'] . "', bgColor: '" . $this->barcode_colours['background'] . "', barWidth: 2, barHeight: 70, fontSize: 14, output: 'bmp' } );";
  272.                 $barcode_obj = array( 'object', 'data' );
  273.  
  274.             break;
  275.         }
  276.  
  277.         $js .= "var barcode = $('#barcode_container " . $barcode_obj[0] . "').attr( '" . $barcode_obj[1] . "' );";
  278.  
  279.         switch( $context ) {
  280.             case 'checkout':
  281.                 $js .= "$('#order_barcode_image').val( barcode );
  282.                         $('#order_barcode_text').val( '" . $barcode_string . "' );";
  283.                 $tail_content = '';
  284.             break;
  285.  
  286.             case 'dashboard':
  287.                 global $post;
  288.                 if( isset( $post->ID ) ) {
  289.                     $js .= "$.post( '" . admin_url( 'admin-ajax.php' ) . "', { action: 'save_barcode', order_id: '" . $post->ID . "', order_barcode_image: barcode, order_barcode_text: '" . $barcode_string . "' } );";
  290.                     $tail_content = '<span style="color:' . $this->barcode_colours['foreground'] . ';font-family:monospace;text-align:center;width:100%;display:block;">' . $barcode_string . '</span>';
  291.                 }
  292.             break;
  293.         }
  294.  
  295.         ob_start();
  296.  
  297.         // Set barcode container
  298.         echo '<div id="barcode_container"></div>' . $tail_content;
  299.  
  300.         // Run JS for barcode generation
  301.         wc_enqueue_js( $js );
  302.  
  303.         $barcode = ob_get_clean();
  304.  
  305.         // Display barcode
  306.         echo $barcode;
  307.  
  308.     } // End generate_barcode ()
  309.  
  310.     /**
  311.      * Save barcode via ajax
  312.      * @access  public
  313.      * @since   1.0.0
  314.      * @return  void
  315.      */
  316.     public function save_barcode() {
  317.  
  318.         if( ! current_user_can( 'manage_woocommerce' ) ) {
  319.             exit;
  320.         }
  321.  
  322.         if( ! isset( $_POST['order_id'] ) ) {
  323.             exit;
  324.         }
  325.  
  326.         $this->update_order_meta( intval( $_POST['order_id'] ) );
  327.  
  328.         exit;
  329.     }
  330.  
  331.     /**
  332.      * Get text string for barcode
  333.      * @access  public
  334.      * @since   1.0.0
  335.      * @return  void
  336.      */
  337.     public function get_barcode_string () {
  338.  
  339.         // Use PHP's uniqid() for the barcode
  340.         $barcode_string = uniqid();
  341.  
  342.         // Check if this barcode already exists and add increment if so
  343.         $existing_order_id = $this->get_barcode_order( $barcode_string );
  344.         $orig_string = $barcode_string;
  345.         $i = 1;
  346.         while( $existing_order_id != 0 ) {
  347.             $barcode_string = $orig_string . $i;
  348.             $existing_order_id = $this->get_barcode_order( $barcode_string );
  349.             ++$i;
  350.         }
  351.  
  352.         // Return unique barcode
  353.         return apply_filters( $this->_token . '_barcode_string', $barcode_string );
  354.  
  355.     } // End get_barcode_string ()
  356.  
  357.     /**
  358.      * Get barcode for display in an email
  359.      * @access  public
  360.      * @since   1.0.0
  361.      * @param   object $order Order object
  362.      * @return  void
  363.      */
  364.     public function get_email_barcode ( $order ) {
  365.  
  366.         if( ! $order ) return;
  367.  
  368.         // Generate correctly formatted HTML for email
  369.         ob_start(); ?>
  370. <table cellspacing="0" cellpadding="0" border="0" style="width:100%;border:0;text-align:center;margin-top:20px;margin-bottom:20px;">
  371.     <tbody>
  372.         <tr>
  373.             <td style="text-align:center;vertical-align:middle;word-wrap:normal;">
  374.                 <p>
  375. <?php
  376.         // Get before text
  377.         $before = ob_get_clean();
  378.  
  379.         ob_start(); ?>
  380.                 </p>
  381.             </td>
  382.         </tr>
  383.     </tbody>
  384. </table>
  385. <?php
  386.         // Get after text
  387.         $after = ob_get_clean();
  388.  
  389.         // Display barcode
  390.         $this->display_barcode( $order->id, $before, $after );
  391.  
  392.     } // End get_email_barcode ()
  393.  
  394.     /**
  395.      * Get barcode for frontend display
  396.      * @access  public
  397.      * @since   1.0.0
  398.      * @param   object $order Order object
  399.      * @return  void
  400.      */
  401.     public function get_display_barcode ( $order ) {
  402.  
  403.         if( ! $order ) return;
  404.  
  405.         wp_enqueue_style( $this->_token . '-frontend' );
  406.  
  407.         $before = '<div id="view-order-barcode">';
  408.  
  409.         $after = '</div>';
  410.  
  411.         $this->display_barcode( $order->id, $before, $after );
  412.     }
  413.  
  414.     /**
  415.      * Add barcode meta box to order edit screen
  416.      * @access  public
  417.      * @since   1.0.0
  418.      * @return  void
  419.      */
  420.     public function add_order_metabox () {
  421.         global $post;
  422.         $barcode_text = get_post_meta( $post->ID, '_barcode_text', true );
  423.         if( 'yes' == $this->barcode_enable || $barcode_text ) {
  424.             add_meta_box( 'woocommerce-order-barcode', __( 'Order Barcode', 'woocommerce-order-barcodes' ), array( $this, 'get_metabox_barcode' ), 'shop_order', 'side', 'default' );
  425.         }
  426.     }
  427.  
  428.     /**
  429.      * Get barcode for display in the order metabox
  430.      * @access  public
  431.      * @since   1.0.0
  432.      * @param   object $order Order post object
  433.      * @return  void
  434.      */
  435.     public function get_metabox_barcode ( $order ) {
  436.  
  437.         if( ! $order ) return;
  438.  
  439.         $barcode_text = get_post_meta( $order->ID, '_barcode_text', true );
  440.  
  441.         wp_enqueue_style( $this->_token . '-admin' );
  442.  
  443.         if( $barcode_text ) {
  444.  
  445.             $barcode_url = $this->barcode_url( $order->ID );
  446.  
  447.             $before = '<p><a href="' . $barcode_url . '" target="_blank">';
  448.  
  449.             $after = '</a></p>';
  450.  
  451.             $this->display_barcode( $order->ID, $before, $after );
  452.  
  453.         } else {
  454.             $this->generate_barcode( 'dashboard' );
  455.         }
  456.     }
  457.  
  458.     /**
  459.      * Display barcode as an image
  460.      * @access  public
  461.      * @since   1.0.0
  462.      * @param   integer $order_id Order ID
  463.      * @param   string  $before   Markup/text to display before barcode
  464.      * @param   string  $after    Markup/text to display after barcode
  465.      * @param   boolean $echo     Whether to echo out the barcode or just return it
  466.      * @return  void
  467.      */
  468.     public function display_barcode ( $order_id = 0, $before = '', $after = '', $echo = true ) {
  469.  
  470.         if( ! $order_id ) return;
  471.  
  472.         // Get barcode text
  473.         $barcode_text = get_post_meta( $order_id, '_barcode_text', true );
  474.  
  475.         if( ! $barcode_text ) return;
  476.  
  477.         // Get URL for barcode image
  478.         $barcode_url = $this->barcode_url( $order_id );
  479.  
  480.         // Display barcode with before & after text
  481.         $barcode = $before . '<img src="' . esc_url( $barcode_url ) . '" title="' . __( 'Barcode', 'woocommerce-order-barcodes' ) . '" alt="' . __( 'Barcode', 'woocommerce-order-barcodes' ) . '" style="display:inline;border:0;" /><br/><span style="color:' . $this->barcode_colours['foreground'] . ';font-family:monospace;">' . $barcode_text . '</span>' . $after;
  482.  
  483.         if( ! $echo ) {
  484.             return $barcode;
  485.         }
  486.  
  487.         echo $barcode;
  488.  
  489.     } // End display_barcode ()
  490.  
  491.     /**
  492.      * Get the URL for a given order's barcode
  493.      * @access  public
  494.      * @since   1.0.0
  495.      * @param   integer $order_id Order ID
  496.      * @return  string            URL for barcode
  497.      */
  498.     public function barcode_url ( $order_id = 0 ) {
  499.  
  500.         if( ! $order_id ) return;
  501.  
  502.         return trailingslashit( get_site_url() ) . '?wc_barcode=' . $order_id;
  503.  
  504.     } // End barcode_url ()
  505.  
  506.     /**
  507.      * Get barcode image
  508.      * @access  public
  509.      * @since   1.0.0
  510.      * @return  void
  511.      */
  512.     public function get_barcode_image () {
  513.         if( isset( $_GET['wc_barcode'] ) && 0 < intval( $_GET['wc_barcode'] ) ) {
  514.  
  515.             // Get order ID
  516.             $order_id = intval( $_GET['wc_barcode'] );
  517.  
  518.             // Get order barcode
  519.             $barcode_data = get_post_meta( $order_id, '_barcode_image', true );
  520.  
  521.             // Get image data from barcode string
  522.             list( $settings, $string ) = explode( ',', $barcode_data );
  523.             list( $img_type, $method ) = explode( ';', substr( $settings, 5 ) );
  524.  
  525.             // Get image extensoin
  526.             $img_ext = str_replace( 'image/', '', $img_type );
  527.  
  528.             // Decode barcode image
  529.             $barcode = base64_decode( $string );
  530.  
  531.             // Set headers for image output
  532.             if( ini_get( 'zlib.output_compression' ) ) { ini_set( 'zlib.output_compression', 'Off' ); }
  533.             header( 'Pragma: public' );
  534.             header( 'Expires: 0' );
  535.             header( 'Cache-Control: must-revalidate, post-check=0, pre-check=0' );
  536.             header( 'Cache-Control: private', false );
  537.             header( 'Content-Transfer-Encoding: binary' );
  538.             header( 'Content-Type: ' . $img_type );
  539.             header( 'Content-Length: ' . strlen( $barcode ) );
  540.  
  541.             // Output image and die
  542.             die( $barcode );
  543.  
  544.         }
  545.     } // End get_barcode_image ()
  546.  
  547.     /**
  548.      * Form for scanning barcodes
  549.      * @param  array  $params Shortcode parameters
  550.      * @return string         Form markup
  551.      */
  552.     public function barcode_scan_form ( $params = array() ) {
  553.  
  554.         // Check if user has barcode scanning permissions
  555.         $can_scan = apply_filters( $this->_token . '_scan_permission', current_user_can( 'manage_woocommerce' ), 0 );
  556.         if( ! $can_scan ) return;
  557.  
  558.         // Get shortcode parameters
  559.         extract( shortcode_atts( array(
  560.             'action' => '',
  561.         ), $params ) );
  562.  
  563.         // Add .woocommerce class as CSS namespace
  564.         $html = '<div class="woocommerce">';
  565.  
  566.             // Create form
  567.             $html .= '<div id="barcode-scan-form">
  568.                         <form name="barcode-scan" action="" method="post">
  569.                             <select name="scan-action" id="scan-action" class="scan_action" required>
  570.                                 <option value="" ' . selected( $action, '', false ) . '>' . __( 'Select action', 'woocommerce-order-barcodes' ) . '</option>
  571.                                 <option value="lookup" ' . selected( $action, 'lookup', false ) . '>' . __( 'Look up', 'woocommerce-order-barcodes' ) . '</option>
  572.                                 <option value="complete" ' . selected( $action, 'complete', false ) . '>' . __( 'Complete order', 'woocommerce-order-barcodes' ) . '</option>
  573.                                 <option value="checkin" ' . selected( $action, 'checkin', false ) . '>' . __( 'Check in', 'woocommerce-order-barcodes' ) . '</option>
  574.                                 <option value="checkout" ' . selected( $action, 'checkout', false ) . '>' . __( 'Check out', 'woocommerce-order-barcodes' ) . '</option>
  575.                             </select>
  576.  
  577.                             <input type="text" name="scan-code" id="scan-code" value="" placeholder="' . __( 'Scan or enter barcode', 'woocommerce-order-barcodes' ) . '" required />
  578.  
  579.                             <input type="submit" value="' . __( 'Go', 'woocommerce-order-barcodes' ) . '" />
  580.                         </form>
  581.                       </div>';
  582.  
  583.             // Add loading text
  584.             $html .= '<div id="barcode-scan-loader">' . __( 'Processing barcode...', 'woocommerce-order-barcodes' ) . '</div>';
  585.  
  586.             // Add empty div for scan results to be loaded via ajax
  587.             $html .= '<div id="barcode-scan-result"></div>';
  588.  
  589.         $html .= '</div>';
  590.  
  591.         // Load necessary JS & CSS
  592.         $this->load_scanner_assets();
  593.  
  594.         return $html;
  595.  
  596.     } // End barcode_scan_form ()
  597.  
  598.     /**
  599.      * Process scanning/input of barcode
  600.      * @return void
  601.      */
  602.     public function scan_barcode () {
  603.  
  604.         // Security check
  605.         $do_nonce_check = apply_filters( $this->_token . '_do_nonce_check', true );
  606.         if( $do_nonce_check && ! wp_verify_nonce( $_POST[ $this->_token . '_scan_nonce' ], 'scan-barcode' ) ) {
  607.             $this->display_notice( __( 'Permission denied: Security check failed', 'woocommerce-order-barcodes' ), 'error' );
  608.             exit;
  609.         }
  610.  
  611.         // Retrieve order ID from barcode
  612.         $order_id = $this->get_barcode_order( $_POST['barcode_input'] );
  613.         if( ! $order_id ) {
  614.             $this->display_notice( __( 'Invalid barcode', 'woocommerce-order-barcodes' ), 'error' );
  615.             exit;
  616.         }
  617.  
  618.         // Check if user has barcode scanning permissions
  619.         $can_scan = apply_filters( $this->_token . '_scan_permission', current_user_can( 'manage_woocommerce' ), $order_id );
  620.         if( ! $can_scan ) {
  621.             $this->display_notice( __( 'Permission denied: You do not have sufficient permissions to scan barcodes', 'woocommerce-order-barcodes' ), 'error' );
  622.             exit;
  623.         }
  624.  
  625.         // Get order object
  626.         $order = new WC_Order( $order_id );
  627.         if( ! $order->id || is_wp_error( $order ) ) {
  628.             $this->display_notice( __( 'Invalid order ID', 'woocommerce-order-barcodes' ), 'error' );
  629.             exit;
  630.         }
  631.  
  632.         $response_type = 'success';
  633.  
  634.         // Get selected action and process accordingly
  635.         $action = esc_attr( $_POST['scan_action'] );
  636.         switch( $action ) {
  637.             case 'complete':
  638.                 if ( apply_filters( $this->_token . '_complete_order', true, $order_id ) ) {
  639.                     if ( 'completed' === $order->get_status() ) {
  640.                         $response      = __( 'Order already completed', 'woocommerce-order-barcodes' );
  641.                         $response_type = 'notice';
  642.                     } else {
  643.                         $order->update_status( 'completed' );
  644.                         $response = __( 'Order marked as complete', 'woocommerce-order-barcodes' );
  645.                         $order = new WC_Order( $order_id );
  646.                     }
  647.                 } else {
  648.                     $response = __( 'Not able to complete order', 'woocommerce-order-barcodes' );
  649.                     $response_type = 'error';
  650.                 }
  651.             break;
  652.  
  653.             case 'checkin':
  654.                 if ( 'yes' === get_post_meta( $order_id, '_checked_in', true ) ) {
  655.                     $response      = __( 'Customer already checked in', 'woocommerce-order-barcodes' );
  656.                     $response_type = 'notice';
  657.                 } else {
  658.                     update_post_meta( $order_id, '_checked_in', 'yes' );
  659.                     $response = __( 'Customer has checked in', 'woocommerce-order-barcodes' );
  660.                 }
  661.             break;
  662.  
  663.             case 'checkout':
  664.                 if ( 'no' === get_post_meta( $order_id, '_checked_in', true ) ) {
  665.                     $response      = __( 'Customer already checked out', 'woocommerce-order-barcodes' );
  666.                     $response_type = 'notice';
  667.                 } else {
  668.                     update_post_meta( $order_id, '_checked_in', 'no' );
  669.                     $response = __( 'Customer has checked out', 'woocommerce-order-barcodes' );
  670.                 }
  671.             break;
  672.  
  673.             case 'lookup':
  674.                 $response = sprintf( __( 'Found matched order: #%s', 'woocommerce-order-barcodes' ), $order->id );
  675.             break;
  676.  
  677.             default:
  678.                 $response      = __( 'Please select an action to perform', 'woocommerce-order-barcodes' );
  679.                 $response_type = 'error';
  680.             break;
  681.         }
  682.  
  683.         // Display response notice.
  684.         if ( $response ) {
  685.             $this->display_notice( $response, $response_type );
  686.         }
  687.  
  688.         // No need to display order info if response_type is 'error'.
  689.         if ( 'error' === $response_type ) {
  690.             exit;
  691.         }
  692.  
  693.         // Display check-in status if set
  694.         $checked_in = get_post_meta( $order_id, '_checked_in', true );
  695.         if ( $checked_in ) {
  696.             $checkin_status = ( 'yes' === $checked_in ) ? __( 'Checked in', 'woocommerce-order-barcodes' ) : __( 'Checked out', 'woocommerce-order-barcodes' );
  697.             echo '<h3 class="checked_in ' . esc_attr( $checked_in ) . '">' . $checkin_status . '</h3>';
  698.         }
  699.  
  700.         // Display order details template
  701.         wc_get_template( 'myaccount/view-order.php', array(
  702.             'status'    => get_term_by( 'slug', $order->status, 'shop_order_status' ),
  703.             'order'     => $order,
  704.             'order_id'  => $order_id
  705.         ) );
  706.  
  707.         // Exit function to prevent '0' displaying at the end of ajax request
  708.         exit;
  709.  
  710.     } // End scan_barcode ()
  711.  
  712.     /**
  713.      * Display custom WooCommerce notice
  714.      * @return void
  715.      */
  716.     public function display_notice ( $message = '', $type = 'success' ) {
  717.  
  718.         if( ! $message ) return;
  719.  
  720.         // Display notice template
  721.         wc_get_template( "notices/{$type}.php", array(
  722.             'messages' => array( $message ),
  723.         ) );
  724.  
  725.     } // End display_notice ()
  726.  
  727.     /**
  728.      * Retrieve order ID from barcode
  729.      * @param  string  $barcode Scanned barcode
  730.      * @return integer          Order ID
  731.      */
  732.     public function get_barcode_order ( $barcode = '' ) {
  733.  
  734.         if( ! $barcode ) return 0;
  735.  
  736.         // Set up query
  737.         $args = array(
  738.             'post_type' => 'shop_order',
  739.             'posts_per_page' => 1,
  740.             'meta_key' => '_barcode_text',
  741.             'meta_value' => $barcode,
  742.         );
  743.  
  744.         if( version_compare( WC()->version, 2.2, ">=" ) ) {
  745.             $args['post_status'] = array_keys( wc_get_order_statuses() );
  746.         }
  747.  
  748.         // Get orders
  749.         $orders = get_posts( $args );
  750.  
  751.         // Get order ID
  752.         $order_id = 0;
  753.         if( 0 < count( $orders ) ) {
  754.             foreach( $orders as $order ) {
  755.                 $order_id = $order->ID;
  756.                 break;
  757.             }
  758.         }
  759.  
  760.         return $order_id;
  761.  
  762.     } // End get_barcode_order ()
  763.  
  764.     /**
  765.      * Display check in status field on order edit screen
  766.      * @access  public
  767.      * @since   1.0.0
  768.      * @param   object $order Order object
  769.      * @return  void
  770.      */
  771.     public function checkin_status_edit_field ( $order ) {
  772.  
  773.         $checked_in = get_post_meta( $order->id, '_checked_in', true );
  774.  
  775.         if( $checked_in ) {
  776.             ?>
  777.             <p class="form-field form-field-wide"><label for="checkin_status"><?php _e( 'Check in status:', 'woocommerce-order-barcodes' ) ?></label>
  778.             <select id="checkin_status" name="checkin_status">
  779.                 <option value="<?php esc_attr_e( 'yes' ); ?>" <?php selected( 'yes', $checked_in, true ); ?>><?php _e( 'Checked in', 'woocommerce-order-barcodes' ); ?></option>
  780.                 <option value="<?php esc_attr_e( 'no' ); ?>" <?php selected( 'no', $checked_in, true ); ?>><?php _e( 'Checked out', 'woocommerce-order-barcodes' ); ?></option>
  781.             </select></p>
  782.             <?php
  783.         }
  784.     } // End checkin_status_edit_field ()
  785.  
  786.     /**
  787.      * Save check in status on order edit screen
  788.      * @access  public
  789.      * @since   1.0.0
  790.      * @param   integer $post_id Order post ID
  791.      * @param   object  $post    Order post object
  792.      * @return  void
  793.      */
  794.     public function checkin_status_edit_save ( $post_id, $post ) {
  795.         if( isset( $_POST['checkin_status'] ) && $_POST['checkin_status'] ) {
  796.             update_post_meta( $post_id, '_checked_in', $_POST['checkin_status'] );
  797.         }
  798.     } // End checkin_status_edit_save ()
  799.  
  800.     /**
  801.      * Register all required JS & CSS
  802.      * @access  public
  803.      * @since   1.0.0
  804.      * @return  void
  805.      */
  806.     public function register_assets () {
  807.  
  808.         // Barcodes (all types)
  809.         wp_register_script( $this->_token . '-barcode', esc_url( $this->assets_url ) . 'js/jquery.barcode' . $this->script_suffix . '.js', array( 'jquery' ), $this->_version );
  810.  
  811.         // QR codes
  812.         wp_register_script( $this->_token . '-qrcode-src', esc_url( $this->assets_url ) . 'js/qrcode' . $this->script_suffix . '.js', array(), $this->_version );
  813.         wp_register_script( $this->_token . '-qrcode', esc_url( $this->assets_url ) . 'js/jquery.qrcode' . $this->script_suffix . '.js', array( 'jquery', $this->_token . '-qrcode-src' ), $this->_version );
  814.  
  815.         // Scanner detection
  816.         wp_register_script( $this->_token . '-scanner-compat', esc_url( $this->assets_url ) . 'js/jquery.scannerdetection.compatibility' . $this->script_suffix . '.js', array( 'jquery' ), $this->_version );
  817.         wp_register_script( $this->_token . '-scanner', esc_url( $this->assets_url ) . 'js/jquery.scannerdetection' . $this->script_suffix . '.js', array( 'jquery', $this->_token . '-scanner-compat' ), $this->_version );
  818.  
  819.         if( ! is_admin() ) {
  820.             wp_register_script( $this->_token . '-frontend', esc_url( $this->assets_url ) . 'js/frontend' . $this->script_suffix . '.js', array( 'jquery', $this->_token . '-scanner' ), $this->_version );
  821.             wp_register_style( $this->_token . '-frontend', esc_url( $this->assets_url ) . 'css/frontend.css', array(), $this->_version );
  822.  
  823.             // Pass data to frontend JS
  824.             wp_localize_script( $this->_token . '-frontend', 'wc_order_barcodes', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ), 'scan_nonce' => wp_create_nonce( 'scan-barcode' ) ) );
  825.         } else {
  826.             wp_register_style( $this->_token . '-admin', esc_url( $this->assets_url ) . 'css/admin.css', array(), $this->_version );
  827.         }
  828.  
  829.     } // End register_assets ()
  830.  
  831.     /**
  832.      * Load JS & CSS required for barcode generation
  833.      * @access  public
  834.      * @since   1.0.0
  835.      * @return  void
  836.      */
  837.     public function load_barcode_assets () {
  838.         wp_enqueue_script( $this->_token . '-barcode' );
  839.         wp_enqueue_script( $this->_token . '-qrcode' );
  840.         if( ! is_admin() ) {
  841.             wp_enqueue_style( $this->_token . '-frontend' );
  842.         }
  843.     } // End load_barcode_assets ()
  844.  
  845.     /**
  846.      * Load JS & CSS required for scanner form
  847.      * @access  public
  848.      * @since   1.0.0
  849.      * @return  void
  850.      */
  851.     public function load_scanner_assets () {
  852.         wp_enqueue_script( $this->_token . '-frontend' );
  853.         wp_enqueue_style( $this->_token . '-frontend' );
  854.     } // End load_scanner_assets ()
  855.  
  856.     /**
  857.      * Load plugin localisation
  858.      * @access  public
  859.      * @since   1.0.0
  860.      * @return  void
  861.      */
  862.     public function load_localisation () {
  863.         load_plugin_textdomain( 'woocommerce-order-barcodes', false, dirname( plugin_basename( $this->file ) ) . '/lang/' );
  864.     } // End load_localisation ()
  865.  
  866.     /**
  867.      * Load plugin textdomain
  868.      * @access  public
  869.      * @since   1.0.0
  870.      * @return  void
  871.      */
  872.     public function load_plugin_textdomain () {
  873.         $domain = 'woocommerce-order-barcodes';
  874.  
  875.         $locale = apply_filters( 'plugin_locale', get_locale(), $domain );
  876.  
  877.         load_textdomain( $domain, WP_LANG_DIR . '/' . $domain . '/' . $domain . '-' . $locale . '.mo' );
  878.         load_plugin_textdomain( $domain, FALSE, dirname( plugin_basename( $this->file ) ) . '/lang/' );
  879.     } // End load_plugin_textdomain ()
  880.  
  881.     /**
  882.      * Main class instance - ensures only one instance of the class is loaded or can be loaded
  883.      * @access public
  884.      * @since  1.0.0
  885.      * @static
  886.      * @see    WC_Order_Barcodes()
  887.      * @return Main WooCommerce_Order_Barcodes instance
  888.      */
  889.     public static function instance ( $file = '', $version = '1.0.0' ) {
  890.         if ( is_null( self::$_instance ) ) {
  891.             self::$_instance = new self( $file, $version );
  892.         }
  893.         return self::$_instance;
  894.     } // End instance ()
  895.  
  896.     /**
  897.      * Cloning is forbidden
  898.      * @access public
  899.      * @since  1.0.0
  900.      */
  901.     public function __clone () {
  902.         _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?' ), $this->_version );
  903.     } // End __clone ()
  904.  
  905.     /**
  906.      * Unserializing instances of this class is forbidden
  907.      * @access public
  908.      * @since  1.0.0
  909.      */
  910.     public function __wakeup () {
  911.         _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?' ), $this->_version );
  912.     } // End __wakeup ()
  913.  
  914.     /**
  915.      * Plugin installation - runs on activation
  916.      * @access  public
  917.      * @since   1.0.0
  918.      * @return  void
  919.      */
  920.     public function install () {
  921.         $this->_log_version_number();
  922.     } // End install ()
  923.  
  924.     /**
  925.      * Log the plugin version number
  926.      * @access  public
  927.      * @since   1.0.0
  928.      * @return  void
  929.      */
  930.     private function _log_version_number () {
  931.         update_option( $this->_token . '_version', $this->_version );
  932.     } // End _log_version_number ()
  933.  
  934. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top