/**
  * Checks for proper gateway configuration (required fields populated, etc)
  * and that there are no missing dependencies
  *
  * @see WC_Payment_Gateway::is_available()
  */
 public function is_available()
 {
     // proper configuration
     if (!$this->get_ssl_merchant_id() || !$this->get_ssl_user_id() || !$this->get_ssl_pin()) {
         return false;
     }
     // all dependencies met
     if (count(wc_elavon_vm()->get_missing_dependencies()) > 0) {
         return false;
     }
     return parent::is_available();
 }
 /**
  * Perform the transaction request
  *
  * @param object $request request object
  * @return SimpleXMLElement response, or false on error
  */
 public function transaction_request($request)
 {
     // build the simplexml object
     $request_xml = simplexml_load_string("<txn />");
     $request_xml->addChild('ssl_merchant_id', $this->ssl_merchant_id);
     $request_xml->addChild('ssl_user_id', $this->ssl_user_id);
     $request_xml->addChild('ssl_pin', $this->ssl_pin);
     $request_xml->addChild('ssl_test_mode', $request->ssl_test_mode);
     $request_xml->addChild('ssl_transaction_type', $request->ssl_transaction_type);
     $request_xml->addChild('ssl_invoice_number', $this->stripspecialchars($request->ssl_invoice_number));
     $request_xml->addChild('ssl_card_number', $request->ssl_card_number);
     $request_xml->addChild('ssl_exp_date', $request->ssl_exp_date);
     $request_xml->addChild('ssl_amount', $request->ssl_amount);
     $request_xml->addChild('ssl_salestax', $request->ssl_salestax);
     $request_xml->addChild('ssl_customer_code', $request->ssl_customer_code);
     $request_xml->addChild('ssl_cvv2cvc2_indicator', $request->ssl_cvv2cvc2_indicator);
     if (isset($request->ssl_cvv2cvc2)) {
         $request_xml->addChild('ssl_cvv2cvc2', $request->ssl_cvv2cvc2);
     }
     $request_xml->addChild('ssl_first_name', $this->stripspecialchars($request->ssl_first_name));
     $request_xml->addChild('ssl_last_name', $this->stripspecialchars($request->ssl_last_name));
     $request_xml->addChild('ssl_company', $this->stripspecialchars($request->ssl_company));
     $request_xml->addChild('ssl_avs_address', $this->stripspecialchars($request->ssl_avs_address));
     $request_xml->addChild('ssl_address2', $this->stripspecialchars($request->ssl_address2));
     $request_xml->addChild('ssl_city', $this->stripspecialchars($request->ssl_city));
     $request_xml->addChild('ssl_state', $this->stripspecialchars($request->ssl_state));
     $request_xml->addChild('ssl_avs_zip', $this->stripspecialchars($request->ssl_avs_zip));
     $request_xml->addChild('ssl_country', $this->stripspecialchars($request->ssl_country));
     $request_xml->addChild('ssl_email', $this->stripspecialchars($request->ssl_email));
     $request_xml->addChild('ssl_phone', $this->stripspecialchars($request->ssl_phone));
     $request_xml->addChild('ssl_cardholder_ip', $request->ssl_cardholder_ip);
     // allow other actors to modify the request.  Useful for adding custom fields
     $request_xml = apply_filters('wc_payment_gateway_elavon_vm_request_xml', $request_xml, $request);
     // According to Elavon's tech support, their "XML" protocol isn't actually
     //  true XML, and will report the request as invalid if it contains the
     //  normal XML header, so strip it out of our requests
     $request = str_replace("<?xml version=\"1.0\"?>\n", '', $request_xml->asXML());
     $start_time = microtime(true);
     $response = $this->perform_request($this->endpoint_url, $request);
     $time = round(microtime(true) - $start_time, 5);
     // log the request
     if ($this->log_enabled) {
         $dom = new DOMDocument();
         $dom->preserveWhiteSpace = FALSE;
         $dom->loadXML($request);
         $dom->formatOutput = TRUE;
         $request = $dom->saveXml();
         // make the request data safe for display
         // replace merchant authentication
         if (preg_match('/<ssl_pin>(.*)<\\/ssl_pin>/', $request, $matches)) {
             $request = preg_replace('/<ssl_pin>.*<\\/ssl_pin>/', '<ssl_pin>' . str_repeat('*', strlen($matches[1])) . '</ssl_pin>', $request);
         }
         // replace real card number
         if (preg_match('/<ssl_card_number>(.*)<\\/ssl_card_number>/', $request, $matches)) {
             $request = preg_replace('/<ssl_card_number>.*<\\/ssl_card_number>/', '<ssl_card_number>' . str_repeat('*', strlen($matches[1]) - 4) . substr($matches[1], -4) . '</ssl_card_number>', $request);
         }
         // replace real CSC code
         if (isset($request->ssl_cvv2cvc2) && preg_match('/<ssl_cvv2cvc2>(.**)<\\/ssl_cvv2cvc2>/', $request, $matches)) {
             $request = preg_replace('/<ssl_cvv2cvc2>.**<\\/ssl_cvv2cvc2>/', '<ssl_cvv2cvc2>' . str_repeat('*', strlen($matches[1])) . '</ssl_cvv2cvc2>', $request);
         }
         $request = str_replace("<?xml version=\"1.0\"?>\n", '', $request);
         wc_elavon_vm()->log(sprintf(__("Request Time (s): %s\nRequest Method: %s\nRequest URI: %s\nRequest Body:\n %s", WC_Elavon_VM::TEXT_DOMAIN), $time, 'POST', $this->endpoint_url, $request));
     }
     return simplexml_load_string($response);
 }
function init_woocommerce_gateway_elavon()
{
    /**
     * The main class for the Elavon VM Payment Gateway.  This class handles all the
     * non-gateway tasks such as verifying dependencies are met, loading the text
     * domain, etc.
     *
     */
    class WC_Elavon_VM extends SV_WC_Plugin
    {
        /** version number */
        const VERSION = '1.3.0';
        /** @var WC_Elavon_VM single instance of this plugin */
        protected static $instance;
        /** plugin id */
        const PLUGIN_ID = 'elavon_vm';
        /** plugin text domain */
        const TEXT_DOMAIN = 'woocommerce-gateway-elavon';
        /** string class name to load as gateway */
        const GATEWAY_CLASS_NAME = 'WC_Gateway_Elavon_VM';
        /**
         * Initialize the plugin
         *
         * @see SV_WC_Plugin::__construct()
         */
        public function __construct()
        {
            parent::__construct(self::PLUGIN_ID, self::VERSION, self::TEXT_DOMAIN, array('dependencies' => array('simplexml', 'dom')));
            // Load the gateway
            add_action('sv_wc_framework_plugins_loaded', array($this, 'load_classes'));
        }
        /**
         * Loads Gateway class once parent class is available
         */
        public function load_classes()
        {
            // Elavon gateway
            require_once 'includes/class-wc-gateway-elavon-vm.php';
            // Add class to WC Payment Methods
            add_filter('woocommerce_payment_gateways', array($this, 'load_gateway'));
        }
        /**
         * Adds gateway to the list of available payment gateways
         *
         * @param array $gateways array of gateway names or objects
         * @return array $gateways array of gateway names or objects
         */
        public function load_gateway($gateways)
        {
            $gateways[] = self::GATEWAY_CLASS_NAME;
            return $gateways;
        }
        /**
         * Load the translation so that WPML is supported
         *
         * @see SV_WC_Plugin::load_translation()
         */
        public function load_translation()
        {
            load_plugin_textdomain('woocommerce-gateway-elavon', false, dirname(plugin_basename($this->get_file())) . '/i18n/languages');
        }
        /**
         * Gets the plugin documentation url
         *
         * @since 1.2
         * @see SV_WC_Plugin::get_documentation_url()
         * @return string documentation URL
         */
        public function get_documentation_url()
        {
            return 'http://docs.woothemes.com/document/elavon-vm-payment-gateway/';
        }
        /**
         * Returns the review page url
         *
         * @since 1.2
         * @see SV_WC_Plugin::get_review_url()
         * @return string review URL, or ''
         */
        public function get_review_url()
        {
            return 'http://www.skyverge.com/product/woocommerce-elavon-vm-payment-gateway/#tab-reviews';
        }
        /**
         * Gets the gateway configuration URL
         *
         * @since 1.2
         * @see SV_WC_Plugin::get_settings_url()
         * @param string $plugin_id the plugin identifier.  Note that this can be a
         *        sub-identifier for plugins with multiple parallel settings pages
         *        (ie a gateway that supports both credit cards and echecks)
         * @return string plugin settings URL
         */
        public function get_settings_url($plugin_id = null)
        {
            return $this->get_payment_gateway_configuration_url(self::GATEWAY_CLASS_NAME);
        }
        /**
         * Returns true if on the gateway settings page
         *
         * @since 1.2
         * @see SV_WC_Plugin::is_plugin_settings()
         * @return boolean true if on the admin gateway settings page
         */
        public function is_plugin_settings()
        {
            return $this->is_payment_gateway_configuration_page(self::GATEWAY_CLASS_NAME);
        }
        /**
         * Returns the admin configuration url for the gateway with class name
         * $gateway_class_name
         *
         * @since 2.2.0-1
         * @param string $gateway_class_name the gateway class name
         * @return string admin configuration url for the gateway
         */
        public function get_payment_gateway_configuration_url($gateway_class_name)
        {
            return admin_url('admin.php?page=wc-settings&tab=checkout&section=' . strtolower($gateway_class_name));
        }
        /**
         * Returns true if the current page is the admin configuration page for the
         * gateway with class name $gateway_class_name
         *
         * @since 2.2.0-1
         * @param string $gateway_class_name the gateway class name
         * @return boolean true if the current page is the admin configuration page for the gateway
         */
        public function is_payment_gateway_configuration_page($gateway_class_name)
        {
            return isset($_GET['page']) && 'wc-settings' == $_GET['page'] && isset($_GET['tab']) && 'checkout' == $_GET['tab'] && isset($_GET['section']) && strtolower($gateway_class_name) == $_GET['section'];
        }
        /**
         * Checks if required PHP extensions are loaded and SSL is enabled. Adds an admin notice if either check fails.
         * Also gateway settings are checked as well.
         *
         * @since 1.2.3
         * @see SV_WC_Plugin::add_delayed_admin_notices()
         */
        public function add_delayed_admin_notices()
        {
            parent::add_delayed_admin_notices();
            // show a notice for any settings/configuration issues
            $this->add_ssl_required_admin_notice();
        }
        /**
         * Render the SSL Required notice, as needed
         *
         * @since 1.2.3
         */
        private function add_ssl_required_admin_notice()
        {
            // check settings:  gateway active and SSl enabled
            $settings = get_option('woocommerce_elavon_settings');
            if (isset($settings['enabled']) && 'yes' == $settings['enabled'] && isset($settings['environment']) && 'production' == $settings['environment']) {
                // SSL check if gateway enabled/production mode
                if ('no' === get_option('woocommerce_force_ssl_checkout')) {
                    $message = sprintf(__("%Elavon Error%s: WooCommerce is not being forced over SSL; your customer's payment data is at risk.", self::TEXT_DOMAIN), '<strong>', '</strong>');
                    $this->get_admin_notice_handler()->add_admin_notice($message, 'ssl-required');
                }
            }
        }
        /** Helper methods ******************************************************/
        /**
         * Main <Plugin Name> Instance, ensures only one instance is/can be loaded
         *
         * @since 1.3.0
         * @see wc_elavon_vm()
         * @return WC_Elavon_VM
         */
        public static function instance()
        {
            if (is_null(self::$instance)) {
                self::$instance = new self();
            }
            return self::$instance;
        }
        /**
         * Returns the plugin name, localized
         *
         * @since 1.2
         * @see SV_WC_Payment_Gateway::get_plugin_name()
         * @return string the plugin name
         */
        public function get_plugin_name()
        {
            return __('WooCommerce Elavon', self::TEXT_DOMAIN);
        }
        /**
         * Returns __FILE__
         *
         * @since 1.2
         * @return string the full path and filename of the plugin file
         */
        protected function get_file()
        {
            return __FILE__;
        }
        /** Lifecycle methods ******************************************************/
        /**
         * Run every time.  Used since the activation hook is not executed when updating a plugin
         *
         * @see SV_WC_Plugin::install()
         */
        protected function install()
        {
            // check for a pre 1.2 version
            $legacy_version = get_option('wc_gateway_elavon_vm');
            if (false !== $legacy_version) {
                // upgrade path from previous version, trash old version option
                delete_option('wc_gateway_elavon_vm');
                // upgrade path
                $this->upgrade($legacy_version);
                // and we're done
                return;
            }
        }
        /**
         * Run when plugin version number changes
         *
         * @see SV_WC_Plugin::upgrade()
         */
        protected function upgrade($installed_version)
        {
            global $wpdb;
            // if installed version is less than 1.0.4, set the correct account type, if needed
            if (version_compare($installed_version, "1.0.4", '<')) {
                // Can't think of a great way of grabbing this from the abstract WC_Settings_API class
                $plugin_id = 'woocommerce_';
                $form_field_settings = (array) get_option($plugin_id . self::PLUGIN_ID . '_settings');
                // for existing installs, configured prior to the introduction of the 'account' setting
                if ($form_field_settings && !isset($form_field_settings['account'])) {
                    if (isset($form_field_settings['testmode']) && 'yes' == $form_field_settings['testmode']) {
                        $form_field_settings['account'] = 'demo';
                    } else {
                        $form_field_settings['account'] = 'production';
                    }
                    // set the account type
                    update_option($plugin_id . self::PLUGIN_ID . '_settings', $form_field_settings);
                }
            }
            // standardize debug_mode setting
            if (version_compare($installed_version, "1.1.1", '<') && ($settings = get_option('woocommerce_' . self::PLUGIN_ID . '_settings'))) {
                // previous settings
                $log_enabled = isset($settings['log']) && 'yes' == $settings['log'] ? true : false;
                $debug_enabled = isset($settings['debug']) && 'yes' == $settings['debug'] ? true : false;
                // logger -> debug_mode
                if ($log_enabled && $debug_enabled) {
                    $settings['debug_mode'] = 'both';
                } elseif (!$log_enabled && !$debug_enabled) {
                    $settings['debug_mode'] = 'off';
                } elseif ($log_enabled) {
                    $settings['debug_mode'] = 'log';
                } else {
                    $settings['debug_mode'] = 'checkout';
                }
                unset($settings['log']);
                unset($settings['debug']);
                update_option('woocommerce_' . self::PLUGIN_ID . '_settings', $settings);
            }
        }
    }
    // end WC_Elavon_VM
    /**
     * Returns the One True Instance of Elavon VM
     *
     * @since 1.3.0
     * @return WC_Elavon_VM
     */
    function wc_elavon_vm()
    {
        return WC_Elavon_VM::instance();
    }
    /**
     * The WC_Elavon_VM global object, exists only for backwards compat
     *
     * @deprecated 1.3.0
     * @name $wc_elavon_vm
     * @global WC_Elavon_VM $GLOBALS['wc_elavon_vm']
     */
    $GLOBALS['wc_elavon_vm'] = wc_elavon_vm();
}