/**
  * Tells Membership2 Admin to display this form to manage this rule.
  *
  * @since  1.0.0
  *
  * @param array $callback (Invalid callback)
  * @param array $data The data collection.
  * @return array Correct callback.
  */
 public function handle_render_callback($callback, $data)
 {
     $view = MS_Factory::load('MS_Addon_BuddyPress_Rule_View');
     $view->data = $data;
     $callback = array($view, 'to_html');
     return $callback;
 }
 /**
  * Fires only at user creation from admin
  * Create even to send notification email.
  *
  * @since 1.0.2.6
  *
  * @var int $user_id
  */
 public function save_user_create_event($user_id)
 {
     if (is_admin()) {
         $member = MS_Factory::load('MS_Model_Member', $user_id);
         MS_Model_Event::save_event(MS_Model_Event::TYPE_MS_REGISTERED, $member);
     }
 }
    /**
     * Create view output.
     *
     * @since  1.0.0
     * @return string
     */
    public function to_html()
    {
        $list_table = MS_Factory::create('MS_Helper_ListTable_Event');
        $list_table->prepare_items();
        if (isset($_REQUEST['membership_id'])) {
            $membership = MS_Factory::load('MS_Model_Membership', $_REQUEST['membership_id']);
            $title = sprintf(__('%s News', 'membership2'), $membership->get_name_tag());
            $url = esc_url_raw(add_query_arg(array('step' => MS_Controller_Membership::STEP_OVERVIEW), remove_query_arg(array('paged', 'order', 'post_mime_type', 'detached', 'orderby', 's'))));
            $back_link = array('id' => 'back', 'type' => MS_Helper_Html::TYPE_HTML_LINK, 'value' => __('» Back to Overview', 'membership2'), 'url' => $url, 'class' => 'wpmui-field-button button');
        } else {
            $title = __('Membership News', 'membership2');
            $back_link = '';
        }
        ob_start();
        ?>

		<div class="wrap ms-wrap ms-membership-news">
			<?php 
        MS_Helper_Html::settings_header(array('title' => $title));
        MS_Helper_Html::html_element($back_link);
        $list_table->search_box();
        $list_table->views();
        ?>
			<form action="" method="post">
				<?php 
        $list_table->display();
        ?>
			</form>
		</div>

		<?php 
        $html = ob_get_clean();
        echo '' . $html;
    }
 /**
  * Tells Membership2 Admin to display this form to manage this rule.
  *
  * @since  1.0.0
  *
  * @param array $callback (Invalid callback)
  * @param array $data The data collection.
  * @return array Correct callback.
  */
 public function handle_render_callback($callback, $data)
 {
     $view = MS_Factory::load('MS_Rule_MemberRoles_View');
     $view->data = $data;
     $callback = array($view, 'to_html');
     return $callback;
 }
 /**
  * Initialize the object.
  *
  * @since  1.0.0
  */
 public function after_load()
 {
     parent::after_load();
     $this->_api = MS_Factory::load('MS_Gateway_Stripe_Api');
     // If the gateway is initialized for the first time then copy settings
     // from the Stripe Single gateway.
     if (false === $this->test_secret_key) {
         $single = MS_Factory::load('MS_Gateway_Stripe');
         $this->test_secret_key = $single->test_secret_key;
         $this->secret_key = $single->secret_key;
         $this->test_publishable_key = $single->test_publishable_key;
         $this->publishable_key = $single->publishable_key;
         $this->save();
     }
     $this->id = self::ID;
     $this->name = __('Stripe Subscriptions Gateway', MS_TEXT_DOMAIN);
     $this->group = 'Stripe';
     $this->manual_payment = false;
     // Recurring charged automatically
     $this->pro_rate = true;
     $this->unsupported_payment_types = array(MS_Model_Membership::PAYMENT_TYPE_PERMANENT, MS_Model_Membership::PAYMENT_TYPE_FINITE, MS_Model_Membership::PAYMENT_TYPE_DATE_RANGE);
     // Update all payment plans and coupons.
     $this->add_action('ms_gateway_toggle_stripeplan', 'update_stripe_data');
     // Update a single payment plan.
     $this->add_action('ms_saved_MS_Model_Membership', 'update_stripe_data_membership');
     // Update a single coupon.
     $this->add_action('ms_saved_MS_Addon_Coupon_Model', 'update_stripe_data_coupon');
 }
 /**
  * Checks if the current Add-on is enabled
  *
  * @since  1.0.0
  * @return bool
  */
 public static function is_active()
 {
     if (!self::wp_recaptcha_active() && MS_Model_Addon::is_enabled(self::ID)) {
         $model = MS_Factory::load('MS_Model_Addon');
         $model->disable(self::ID);
     }
     return MS_Model_Addon::is_enabled(self::ID);
 }
 /**
  * Returns the singleton instance of the MS_Model_Pages object
  *
  * @since  1.0.0
  * @return MS_Model_Pages
  */
 public static function get_model()
 {
     static $Model = null;
     if (null === $Model) {
         $Model = MS_Factory::load('MS_Model_Pages');
     }
     return $Model;
 }
 /**
  * Initializes the Add-on. Always executed.
  *
  * @since  1.0.0
  */
 public function init()
 {
     // Always remove bbpress from MS_Rule_CptGroup_Model.
     $this->add_filter('ms_rule_cptgroup_model_get_excluded_content', 'exclude_bbpress_cpts');
     if (self::is_active()) {
         $this->add_filter('ms_controller_protection_tabs', 'rule_tabs');
         MS_Factory::load('MS_Addon_Bbpress_Rule');
     }
 }
Example #9
0
 /**
  * Initialize the Add-On.
  *
  * @since  1.0.0
  */
 public function __construct()
 {
     parent::__construct();
     self::$model = MS_Factory::load('MS_Model_Addon');
     self::$settings = MS_Factory::load('MS_Model_Settings');
     $this->add_filter('ms_model_addon_register', 'register');
     $this->add_action('ms_model_addon_initialize', 'init_addon');
     $this->add_ajax_action($this->ajax_action(), 'ajax_update_settings');
 }
 /**
  * Initialize the object.
  *
  * @since  1.0.0
  * @internal
  */
 public function after_load()
 {
     parent::after_load();
     $this->_api = MS_Factory::load('MS_Gateway_Stripe_Api');
     $this->id = self::ID;
     $this->name = __('Stripe Single Gateway', 'membership2');
     $this->group = 'Stripe';
     $this->manual_payment = true;
     // Recurring billed/paid manually
     $this->pro_rate = true;
 }
 /**
  * Initialize the object.
  *
  * @since  1.0.0
  * @internal
  */
 public function after_load()
 {
     parent::after_load();
     $this->_api = MS_Factory::load('MS_Gateway_Stripe_Api');
     $this->id = self::ID;
     $this->name = __('Stripe Single Gateway', 'membership2');
     $this->group = 'Stripe';
     $this->manual_payment = true;
     // Recurring billed/paid manually
     $this->pro_rate = true;
     $this->add_filter('ms_model_pages_get_ms_page_url', 'ms_model_pages_get_ms_page_url_cb', 99, 4);
 }
 /**
  * Tests the Stripe Subscription gateway
  * @test
  */
 function stripeplan_subscription()
 {
     $gateway = MS_Model_Gateway::factory(MS_Gateway_Stripeplan::ID);
     $user_id = TData::id('user', 'editor');
     $membership_id = TData::id('membership', 'recurring');
     $subscription = TData::subscribe($user_id, $membership_id);
     $controller = MS_Factory::load('MS_Controller_Gateway');
     $gateway->update_stripe_data();
     $data = array('card' => array('number' => '4242424242424242', 'exp_month' => 12, 'exp_year' => date('Y') + 1, 'cvc' => '314'));
     $res = M2_Stripe_Token::create($data);
     $token = $res->id;
     $form_data = array('_wpnonce' => wp_create_nonce($gateway->id . '_' . $subscription->id), 'gateway' => $gateway->id, 'ms_relationship_id' => $subscription->id, 'step' => 'process_purchase', 'stripeToken' => $token, 'stripeTokenType' => 'card', 'stripeEmail' => '*****@*****.**');
     $_POST = $form_data;
     $_REQUEST = $_POST;
     // Right now the subscription must have status PENDING
     $this->assertEquals(MS_Model_Relationship::STATUS_PENDING, $subscription->status);
     /*
      * This function processes the purchase and will set the subscription
      * to active.
      */
     $controller->process_purchase();
     // Check the subscription status.
     $this->assertEquals(MS_Model_Relationship::STATUS_ACTIVE, $subscription->status);
     $this->assertEquals(1, count($subscription->payments));
     // Modify the expiration date to trigger another payment.
     $today = date('Y-m-d');
     $subscription->expire_date = $today;
     $this->assertEquals($today, $subscription->expire_date);
     $this->assertEquals(0, $subscription->get_remaining_period());
     // Trigger next payment and validate it.
     $subscription->check_membership_status();
     $this->assertEquals(2, count($subscription->payments));
     // Modify the expiration date to trigger another payment.
     $subscription->expire_date = $today;
     $this->assertEquals($today, $subscription->expire_date);
     $this->assertEquals(0, $subscription->get_remaining_period());
     // Trigger next payment and validate it.
     // THIS TIME NO PAYMENT SHOULD BE MADE because paycycle_repetitions = 2!
     $subscription->check_membership_status();
     $this->assertEquals(2, count($subscription->payments));
     // Also the subscription should be cancelled at stripe now.
     $customer_id = $subscription->get_member()->get_gateway_profile(MS_Gateway_Stripe_Api::ID, 'customer_id');
     $customer = M2_Stripe_Customer::retrieve($customer_id);
     $invoice = $subscription->get_previous_invoice();
     $stripe_sub_id = $invoice->external_id;
     $stripe_sub = $customer->subscriptions->retrieve($stripe_sub_id);
     $this->assertEquals('active', $stripe_sub->status);
     $this->assertTrue($stripe_sub->cancel_at_period_end);
     // Clean up.
     $customer->delete();
 }
Example #13
0
 /**
  * Checks if shared-setup was working.
  * @test
  */
 function staging_data_is_correct()
 {
     $this->assertFalse(empty(TData::id('user', 'admin')));
     wp_set_current_user(TData::id('user', 'admin'));
     $this->assertEquals(get_current_user_id(), TData::id('user', 'admin'));
     $this->assertFalse(empty(TData::id('user', 'editor')));
     $this->assertFalse(empty(TData::id('post', 'sample-page')));
     $this->assertEquals('page', get_post_type(TData::id('post', 'sample-page')));
     $ms_id = TData::id('membership', 'simple');
     $this->assertFalse(empty($ms_id));
     $membership = MS_Factory::load('MS_Model_Membership', $ms_id);
     $this->assertEquals($ms_id, $membership->id);
     $this->assertEquals(29, $membership->price);
 }
 /**
  * Prepares a list with field definitions that are required to render the
  * payment list/global options (i.e. currency and sender name)
  *
  * @since  1.0.0
  *
  * @return array
  */
 protected function get_global_payment_fields()
 {
     $settings = MS_Factory::load('MS_Model_Settings');
     $action = MS_Controller_Settings::AJAX_ACTION_UPDATE_SETTING;
     $nonce = wp_create_nonce($action);
     $fields = array('currency' => array('id' => 'currency', 'type' => MS_Helper_Html::INPUT_TYPE_SELECT, 'title' => __('Select payment currency', MS_TEXT_DOMAIN), 'value' => $settings->currency, 'field_options' => $settings->get_currencies(), 'class' => '', 'class' => 'chosen-select', 'data_ms' => array('field' => 'currency')), 'invoice_sender_name' => array('id' => 'invoice_sender_name', 'type' => MS_Helper_Html::INPUT_TYPE_TEXT, 'title' => __('Invoice sender name', MS_TEXT_DOMAIN), 'value' => $settings->invoice_sender_name, 'data_ms' => array('field' => 'invoice_sender_name')));
     foreach ($fields as $key => $field) {
         if (is_array($field['data_ms'])) {
             $fields[$key]['data_ms']['_wpnonce'] = $nonce;
             $fields[$key]['data_ms']['action'] = $action;
         }
     }
     return apply_filters('ms_gateway_view_get_global_payment_fields', $fields);
 }
Example #15
0
 /**
  * Check member capability add-on.
  * @test
  */
 function member_capabilities_rule()
 {
     // We only test the addon as an isolated unit.
     $addon = MS_Factory::load('MS_Rule_MemberCaps_Model');
     remove_all_filters('user_has_cap');
     $addon->protect_admin_content();
     wp_set_current_user(TData::id('user', 'admin'));
     $this->assertTrue(current_user_can('manage_options'), 'admin');
     $this->assertTrue(current_user_can('edit_theme_options'), 'admin');
     wp_set_current_user(TData::id('user', 'editor'));
     $this->assertFalse(current_user_can('manage_options'), 'editor');
     $this->assertFalse(current_user_can('edit_theme_options'), 'editor');
     $this->assertTrue(current_user_can('edit_pages'), 'editor');
     $this->assertTrue(current_user_can('delete_pages'), 'editor');
 }
 /**
  * Checks if the user did import data from this source before.
  *
  * This information is not entirely reliable, since data could have been
  * deleted again after import.
  *
  * @since  1.0.0
  * @return bool
  */
 public static function did_import()
 {
     $settings = MS_Factory::load('MS_Model_Settings');
     $did_import = !empty($settings->import[self::KEY]);
     /**
      * Allow users to manually declare that some M2 subscriptions were
      * imported from old Membership plugin.
      *
      * As a result M2 will additionally listen to the old M1 IPN URL for
      * PayPal payment notifications.
      *
      * @since  1.0.2.4
      * @param  bool $did_import
      */
     return apply_filters('ms_did_import_m1_data', $did_import);
 }
 public function column_membership($item)
 {
     $html = '';
     $is_any = true;
     foreach ($item->membership_id as $id) {
         if (MS_Model_Membership::is_valid_membership($id)) {
             $is_any = false;
             $membership = MS_Factory::load('MS_Model_Membership', $id);
             $html .= sprintf('<span class="ms-bold">%s</span><br />', $membership->name);
         }
     }
     if ($is_any) {
         $html = sprintf('<span class="ms-low">%s</span>', __('Any', 'membership2'));
     }
     return $html;
 }
Example #18
0
 /**
  * Constructor.
  *
  * @since  1.0.0
  *
  * @param array $data The data what has to be associated with this render.
  */
 public function __construct($data = array())
 {
     static $Simulate = null;
     $this->data = $data;
     /**
      * Actions to execute when constructing the parent View.
      *
      * @since  1.0.0
      * @param object $this The MS_View object.
      */
     do_action('ms_view_construct', $this);
     if (null === $Simulate && MS_Model_Simulate::can_simulate()) {
         $Simulate = MS_Factory::load('MS_Model_Simulate');
         self::$is_simulating = $Simulate->is_simulating();
     }
 }
 /**
  * Generate/Prepare the dialog attributes.
  *
  * @since  1.0.0
  */
 public function prepare()
 {
     $subscription_id = $_POST['subscription_id'];
     $subscription = MS_Factory::load('MS_Model_Relationship', $subscription_id);
     $data = array('model' => $subscription);
     $data = apply_filters('ms_view_member_payment_data', $data);
     // Dialog Title
     $this->title = sprintf(__('Subscription Details: %1$s', MS_TEXT_DOMAIN), esc_html($subscription->get_membership()->name));
     // Dialog Size
     $this->width = 940;
     $this->height = 600;
     // Contents
     $this->content = $this->get_contents($data);
     // Make the dialog modal
     $this->modal = true;
 }
 /**
  * Generate/Prepare the dialog attributes.
  *
  * @since  1.0.0
  */
 public function prepare()
 {
     $member_id = $_POST['member_id'];
     $member = MS_Factory::load('MS_Model_Member', $member_id);
     $data = array('model' => $member);
     $data = apply_filters('ms_view_member_dialog_data', $data);
     // Dialog Title
     $this->title = sprintf(__('Profile: %1$s %2$s', 'membership2'), esc_html($member->first_name), esc_html($member->last_name));
     // Dialog Size
     $this->width = 940;
     $this->height = 500;
     // Contents
     $this->content = $this->get_contents($data);
     // Make the dialog modal
     $this->modal = true;
 }
 /**
  * Generate/Prepare the dialog attributes.
  *
  * @since  1.0.0
  */
 public function prepare()
 {
     $subscription_id = $_POST['subscription_id'];
     $subscription = MS_Factory::load('MS_Model_Relationship', $subscription_id);
     if (!empty($_REQUEST['statuscheck'])) {
         $subscription->check_membership_status();
     }
     $data = array('model' => $subscription);
     $data = apply_filters('ms_view_member_subscription_data', $data);
     // Dialog Title
     $this->title = sprintf(__('Subscription Details: %1$s', 'membership2'), esc_html($subscription->get_membership()->name));
     // Dialog Size
     $this->width = 940;
     $this->height = 800;
     // Contents
     $this->content = $this->get_contents($data);
     // Make the dialog modal
     $this->modal = true;
 }
 /**
  * Returns tax information that must be applied to the specified amount.
  *
  * This function first checks the user-metadata for logged-in users and
  * takes the details that are stored in the user metadata table.
  *
  * If the user is not logged in or no metadata are found then the Taxamo API
  * is queried to get the default tax details for the country that
  * Taxamo automatically detects.
  *
  * @since  1.0.0
  * @api
  *
  * @param  numeric $amount The amount without taxes.
  * @return object {
  *         Tax information
  *
  *         string  $country Tax country (2-digit code)
  *         string  $name Tax name
  *         numeric $rate Tax rate (percent)
  *         numeric $amount Tax amount
  * }
  */
 public static function tax_info($amount = 0)
 {
     static $Info = null;
     if (null === $Info) {
         $settings = MS_Factory::load('MS_Model_Settings');
         try {
             $profile = self::get_tax_profile();
             $tax_number = null;
             if ($profile->use_vat_number) {
                 $tax_number = $profile->vat_number;
             }
             $resp = self::taxamo()->calculateSimpleTax(null, $tax_number, null, $profile->tax_country->code, null, null, null, null, 100, $profile->tax_country->code, $settings->currency, null);
             // Prepare the result object.
             if (isset($resp->transaction->transaction_lines[0])) {
                 $transaction = $resp->transaction->transaction_lines[0];
                 $Info = (object) array('country' => $resp->transaction->tax_country_code, 'rate' => $transaction->tax_rate, 'name' => $transaction->tax_name, 'amount' => 0);
             }
         } catch (Exception $ex) {
             MS_Helper_Debug::log('Taxamo error: ' . $ex->getMessage());
         }
     }
     if (!is_object($Info)) {
         $Info = (object) array();
     }
     if (!isset($Info->name)) {
         $Info->name = __('No Tax', 'membership2');
     }
     if (!isset($Info->rate)) {
         $Info->rate = 0;
     }
     if (!isset($Info->amount)) {
         $Info->amount = 0;
     }
     if (!isset($Info->country)) {
         $Info->country = 'US';
     }
     $Info->amount = $amount / 100 * $Info->rate;
     return $Info;
 }
 /**
  * Checks if the user did import data from this source before.
  *
  * This information is not entirely reliable, since data could have been
  * deleted again after import.
  *
  * @since  1.0.0
  * @return bool
  */
 public static function did_import()
 {
     $settings = MS_Factory::load('MS_Model_Settings');
     return !empty($settings->import[self::KEY]);
 }
 /**
  * Get user's coupon application.
  *
  * @since  1.0.0
  *
  * @param int $user_id The user id.
  * @param int $membership_id The membership id.
  * @return MS_Addon_Coupon_Model The coupon model object.
  */
 public static function get_application($user_id, $membership_id)
 {
     $key = self::get_transient_name($user_id, $membership_id);
     $transient = MS_Factory::get_transient($key);
     $coupon = null;
     if (is_array($transient) && !empty($transient['id'])) {
         $the_id = intval($transient['id']);
         $coupon = MS_Factory::load('MS_Addon_Coupon_Model', $the_id);
         $coupon->coupon_message = $transient['message'];
     } else {
         $coupon = MS_Factory::load('MS_Addon_Coupon_Model');
     }
     return apply_filters('ms_addon_coupon_model_get_application', $coupon, $user_id, $membership_id);
 }
 /**
  * Prepare the HTML fields that can be displayed
  *
  * @since  1.0.0
  *
  * @return array
  */
 protected function prepare_fields($data)
 {
     // List of known Membership types; used to display the nice-name
     $ms_types = MS_Model_Membership::get_types();
     $ms_paytypes = MS_Model_Membership::get_payment_types();
     // Prepare the "Memberships" table
     $memberships = array(array(__('Membership name', 'membership2'), __('Membership Type', 'membership2'), __('Payment Type', 'membership2'), __('Description', 'membership2')));
     foreach ($data->memberships as $item) {
         if (!isset($ms_types[$item->type])) {
             $item->type = MS_Model_Membership::TYPE_STANDARD;
         }
         switch ($item->pay_type) {
             case 'recurring':
                 $payment_type = MS_Model_Membership::PAYMENT_TYPE_RECURRING;
                 break;
             case 'finite':
                 $payment_type = MS_Model_Membership::PAYMENT_TYPE_FINITE;
                 break;
             case 'date':
                 $payment_type = MS_Model_Membership::PAYMENT_TYPE_DATE_RANGE;
                 break;
             default:
                 $payment_type = MS_Model_Membership::PAYMENT_TYPE_PERMANENT;
                 break;
         }
         $memberships[] = array($item->name, $ms_types[$item->type], $ms_paytypes[$payment_type], $item->description);
     }
     // Prepare the "Members" table
     $members = array(array(__('Username', 'membership2'), __('Email', 'membership2'), __('Subscriptions', 'membership2'), __('Invoices', 'membership2')));
     foreach ($data->members as $item) {
         $inv_count = 0;
         if (isset($item->subscriptions) && is_array($item->subscriptions)) {
             foreach ($item->subscriptions as $registration) {
                 $inv_count += count($registration->invoices);
             }
         }
         $members[] = array($item->username, $item->email, count($item->subscriptions), $inv_count);
     }
     $settings = array();
     foreach ($data->settings as $setting => $value) {
         switch ($setting) {
             case 'addons':
                 $model = MS_Factory::load('MS_Model_Addon');
                 $list = $model->get_addon_list();
                 $code = '';
                 foreach ($value as $addon => $state) {
                     if ($state) {
                         $code .= __('Activate: ', 'membership2');
                     } else {
                         $code .= __('Dectivate: ', 'membership2');
                     }
                     $code .= $list[$addon]->name . '<br/>';
                 }
                 $settings[] = array(__('Add-Ons', 'membership2'), $code);
                 break;
         }
     }
     if (empty($settings)) {
         $settings[] = array('', __('(No settings are changed)', 'membership2'));
     }
     // Prepare the return value.
     $fields = array();
     // Export-Notes
     $notes = '';
     if (isset($data->notes)) {
         if (is_scalar($data->notes)) {
             $notes = array($data->notes);
         }
         $in_sub = false;
         $notes = '<ul class="ms-import-notes">';
         foreach ($data->notes as $line => $text) {
             $is_sub = strpos($text, '- ') === 0;
             if ($in_sub != $is_sub) {
                 $in_sub = $is_sub;
                 if ($is_sub) {
                     $notes .= '<ul>';
                 } else {
                     $notes .= '</ul>';
                 }
             }
             if ($in_sub) {
                 $text = substr($text, 2);
             }
             $notes .= '<li>' . $text;
         }
         $notes .= '</ul>';
     }
     $fields['details'] = array('type' => MS_Helper_Html::TYPE_HTML_TABLE, 'class' => 'ms-import-preview', 'value' => array(array(__('Data source', 'membership2'), $data->source . ' &emsp; <small>' . sprintf(__('exported on %1$s', 'membership2'), $data->export_time) . '</small>'), array(__('Content', 'membership2'), sprintf(_n('%1$s Membership', '%1$s Memberships', count($data->memberships), 'membership2'), '<b>' . count($data->memberships) . '</b>') . ' / ' . sprintf(_n('%1$s Member', '%1$s Members', count($data->members), 'membership2'), '<b>' . count($data->members) . '</b>'))), 'field_options' => array('head_col' => true, 'head_row' => false, 'col_class' => array('preview-label', 'preview-data')));
     if (!empty($notes)) {
         $fields['details']['value'][] = array(__('Please note', 'membership2'), $notes);
     }
     $batchsizes = array(10 => __('Small (10 items)'), 30 => __('Normal (30 items)'), 100 => __('Big (100 items)'));
     $fields['batchsize'] = array('id' => 'batchsize', 'type' => MS_Helper_Html::INPUT_TYPE_SELECT, 'title' => __('Batch size for import', 'membership2'), 'desc' => __('Big batches will be processed faster but may result in PHP Memory errors.', 'membership2'), 'value' => 30, 'field_options' => $batchsizes, 'class' => 'sel-batchsize');
     $fields['clear_all'] = array('id' => 'clear_all', 'type' => MS_Helper_Html::INPUT_TYPE_CHECKBOX, 'title' => __('Replace current content with import data (removes existing Memberships/Members before importing data)', 'membership2'), 'class' => 'widefat');
     $fields['memberships'] = array('type' => MS_Helper_Html::TYPE_HTML_TABLE, 'class' => 'ms-import-preview', 'value' => $memberships, 'field_options' => array('head_col' => false, 'head_row' => true, 'col_class' => array('preview-name', 'preview-type', 'preview-pay-type', 'preview-desc')));
     $fields['members'] = array('type' => MS_Helper_Html::TYPE_HTML_TABLE, 'class' => 'ms-import-preview', 'value' => $members, 'field_options' => array('head_col' => false, 'head_row' => true, 'col_class' => array('preview-name', 'preview-email', 'preview-count', 'preview-count')));
     $fields['settings'] = array('type' => MS_Helper_Html::TYPE_HTML_TABLE, 'class' => 'ms-import-preview', 'value' => $settings, 'field_options' => array('head_col' => true, 'head_row' => false));
     $fields['sep'] = array('type' => MS_Helper_Html::TYPE_HTML_SEPARATOR);
     $fields['back'] = array('type' => MS_Helper_Html::TYPE_HTML_LINK, 'class' => 'wpmui-field-button button', 'value' => __('Cancel', 'membership2'), 'url' => $_SERVER['REQUEST_URI']);
     $fields['skip'] = array('type' => MS_Helper_Html::TYPE_HTML_LINK, 'class' => 'wpmui-field-button button', 'value' => __('Skip', 'membership2'), 'url' => MS_Controller_Plugin::get_admin_url(false, array('skip_import' => 1)));
     $fields['import'] = array('id' => 'btn-import', 'type' => MS_Helper_Html::INPUT_TYPE_BUTTON, 'value' => __('Import', 'membership2'), 'button_value' => MS_Controller_Import::AJAX_ACTION_IMPORT, 'button_type' => 'submit');
     $fields['download'] = array('id' => 'btn-download', 'type' => MS_Helper_Html::INPUT_TYPE_BUTTON, 'value' => __('Download as Export File', 'membership2'), 'class' => 'button-link');
     return $fields;
 }
 /**
  * Save invoices using the invoices model.
  *
  * @since  1.0.0
  *
  * @param mixed $fields Transaction fields
  */
 private function save_invoice($fields)
 {
     $msg = MS_Helper_Billing::BILLING_MSG_NOT_UPDATED;
     if ($this->is_admin_user() && is_array($fields) && !empty($fields['user_id']) && !empty($fields['membership_id'])) {
         $member = MS_Factory::load('MS_Model_Member', $fields['user_id']);
         $membership_id = $fields['membership_id'];
         $gateway_id = 'admin';
         $subscription = MS_Model_Relationship::get_subscription($member->id, $membership_id);
         if (empty($subscription)) {
             $subscription = MS_Model_Relationship::create_ms_relationship($membership_id, $member->id, $gateway_id);
         } else {
             $subscription->gateway_id = $gateway_id;
             $subscription->save();
         }
         $invoice_id = intval($fields['invoice_id']);
         $invoice = MS_Factory::load('MS_Model_Invoice', $invoice_id);
         if (!$invoice->is_valid()) {
             $invoice = $subscription->get_current_invoice();
             $msg = MS_Helper_Billing::BILLING_MSG_ADDED;
         } else {
             $msg = MS_Helper_Billing::BILLING_MSG_UPDATED;
         }
         foreach ($fields as $field => $value) {
             $invoice->{$field} = $value;
         }
         $invoice->save();
         if (!empty($fields['execute'])) {
             $invoice->changed();
         }
     }
     return apply_filters('ms_controller_billing_save_invoice', $msg, $fields, $this);
 }
 /**
  * Add redirect settings-view callback.
  *
  * @since  1.0.0
  *
  * @param  array $callback The current function callback.
  * @param  string $tab The current membership rule tab.
  * @param  array $data The data shared to the view.
  * @return array The filtered callback.
  */
 public function manage_render_callback($callback, $tab, $data)
 {
     if (self::ID == $tab) {
         $view = MS_Factory::load('MS_Addon_Redirect_View');
         $callback = array($view, 'render_tab');
     }
     return $callback;
 }
Example #28
0
 /**
  * Returns Membership object.
  *
  * @since  1.0.0
  * @return MS_Model_Membership The membership object.
  */
 public function get_membership()
 {
     $membership = MS_Factory::load('MS_Model_Membership', $this->membership_id);
     return apply_filters('ms_rule_get_membership', $membership);
 }
 /**
  * Processes gateway IPN return.
  *
  * @since  1.0.0
  */
 public function handle_return()
 {
     $success = false;
     $ignore = false;
     $exit = false;
     $redirect = false;
     $notes = '';
     $status = null;
     $notes_pay = '';
     $notes_txn = '';
     $external_id = null;
     $invoice_id = 0;
     $subscription_id = 0;
     $amount = 0;
     $transaction_type = '';
     $payment_status = '';
     $is_m1 = false;
     $fields_set = false;
     if (!empty($_POST['txn_type'])) {
         $transaction_type = strtolower($_POST['txn_type']);
     }
     if (!empty($_POST['payment_status'])) {
         $payment_status = strtolower($_POST['payment_status']);
     }
     if ($payment_status || $transaction_type) {
         if (!empty($_POST['invoice'])) {
             // 'invoice' is set in all regular M2 subscriptions.
             $fields_set = true;
         } elseif (!empty($_POST['custom'])) {
             // First: We cannot process this payment.
             $fields_set = false;
             // But let's check if it is an M1 payment.
             $infos = explode(':', $_POST['custom']);
             if (count($infos) > 2) {
                 // $infos should contain [timestamp, user_id, sub_id, key]
                 $pay_types = array('subscr_signup', 'subscr_payment');
                 $pay_stati = array('completed', 'processed');
                 if (in_array($transaction_type, $pay_types)) {
                     $is_m1 = true;
                 } elseif (in_array($payment_status, $pay_stati)) {
                     $is_m1 = true;
                 }
             }
         }
     }
     if ($fields_set) {
         if ($this->is_live_mode()) {
             $domain = 'https://www.paypal.com';
         } else {
             $domain = 'https://www.sandbox.paypal.com';
         }
         // Paypal post authenticity verification
         $ipn_data = (array) stripslashes_deep($_POST);
         $ipn_data['cmd'] = '_notify-validate';
         $response = wp_remote_post($domain . '/cgi-bin/webscr', array('timeout' => 60, 'sslverify' => false, 'httpversion' => '1.1', 'body' => $ipn_data));
         $invoice_id = intval($_POST['invoice']);
         $currency = $_POST['mc_currency'];
         $invoice = MS_Factory::load('MS_Model_Invoice', $invoice_id);
         if (!is_wp_error($response) && 200 == $response['response']['code'] && !empty($response['body']) && 'VERIFIED' == $response['body'] && $invoice->id == $invoice_id) {
             $subscription = $invoice->get_subscription();
             $membership = $subscription->get_membership();
             $member = $subscription->get_member();
             $subscription_id = $subscription->id;
             // Process PayPal payment status
             if ($payment_status) {
                 $amount = (double) $_POST['mc_gross'];
                 $external_id = $_POST['txn_id'];
                 switch ($payment_status) {
                     // Successful payment
                     case 'completed':
                     case 'processed':
                         if ($amount == $invoice->total) {
                             $success = true;
                             $notes .= __('Payment successful', MS_TEXT_DOMAIN);
                         } else {
                             $notes_pay = __('Payment amount differs from invoice total.', MS_TEXT_DOMAIN);
                             $status = MS_Model_Invoice::STATUS_DENIED;
                         }
                         break;
                     case 'reversed':
                         $notes_pay = __('Last transaction has been reversed. Reason: Payment has been reversed (charge back).', MS_TEXT_DOMAIN);
                         $status = MS_Model_Invoice::STATUS_DENIED;
                         $ignore = true;
                         break;
                     case 'refunded':
                         $notes_pay = __('Last transaction has been reversed. Reason: Payment has been refunded.', MS_TEXT_DOMAIN);
                         $status = MS_Model_Invoice::STATUS_DENIED;
                         $ignore = true;
                         break;
                     case 'denied':
                         $notes_pay = __('Last transaction has been reversed. Reason: Payment Denied.', MS_TEXT_DOMAIN);
                         $status = MS_Model_Invoice::STATUS_DENIED;
                         $ignore = true;
                         break;
                     case 'pending':
                         lib2()->array->strip_slashes($_POST, 'pending_reason');
                         $notes_pay = __('Last transaction is pending.', MS_TEXT_DOMAIN) . ' ';
                         switch ($_POST['pending_reason']) {
                             case 'address':
                                 $notes_pay .= __('Customer did not include a confirmed shipping address', MS_TEXT_DOMAIN);
                                 break;
                             case 'authorization':
                                 $notes_pay .= __('Funds not captured yet', MS_TEXT_DOMAIN);
                                 break;
                             case 'echeck':
                                 $notes_pay .= __('The eCheck has not cleared yet', MS_TEXT_DOMAIN);
                                 break;
                             case 'intl':
                                 $notes_pay .= __('Payment waiting for approval by service provider', MS_TEXT_DOMAIN);
                                 break;
                             case 'multi-currency':
                                 $notes_pay .= __('Payment waiting for service provider to handle multi-currency process', MS_TEXT_DOMAIN);
                                 break;
                             case 'unilateral':
                                 $notes_pay .= __('Customer did not register or confirm his/her email yet', MS_TEXT_DOMAIN);
                                 break;
                             case 'upgrade':
                                 $notes_pay .= __('Waiting for service provider to upgrade the PayPal account', MS_TEXT_DOMAIN);
                                 break;
                             case 'verify':
                                 $notes_pay .= __('Waiting for service provider to verify his/her PayPal account', MS_TEXT_DOMAIN);
                                 break;
                             default:
                                 $notes_pay .= __('Unknown reason', MS_TEXT_DOMAIN);
                                 break;
                         }
                         $status = MS_Model_Invoice::STATUS_PENDING;
                         $ignore = true;
                         break;
                     default:
                     case 'partially-refunded':
                     case 'in-progress':
                         $notes_pay = sprintf(__('Not handling payment_status: %s', MS_TEXT_DOMAIN), $payment_status);
                         MS_Helper_Debug::log($notes_pay);
                         $ignore = true;
                         break;
                 }
             }
             // Check for subscription details
             if ($transaction_type) {
                 switch ($transaction_type) {
                     case 'subscr_signup':
                     case 'subscr_payment':
                         // Payment was received
                         $notes_txn = __('Paypal subscripton profile has been created.', MS_TEXT_DOMAIN);
                         if (0 == $invoice->total) {
                             $success = true;
                         } else {
                             $ignore = true;
                         }
                         break;
                     case 'subscr_modify':
                         // Payment profile was modified
                         $notes_txn = __('Paypal subscription profile has been modified.', MS_TEXT_DOMAIN);
                         $ignore = true;
                         break;
                     case 'recurring_payment_profile_canceled':
                     case 'subscr_cancel':
                         // Subscription was manually cancelled.
                         $notes_txn = __('Paypal subscription profile has been canceled.', MS_TEXT_DOMAIN);
                         $member->cancel_membership($membership->id);
                         $member->save();
                         $ignore = true;
                         break;
                     case 'recurring_payment_suspended':
                         // Recurring subscription was manually suspended.
                         $notes_txn = __('Paypal subscription profile has been suspended.', MS_TEXT_DOMAIN);
                         $member->cancel_membership($membership->id);
                         $member->save();
                         $ignore = true;
                         break;
                     case 'recurring_payment_suspended_due_to_max_failed_payment':
                         // Recurring subscription was automatically suspended.
                         $notes_txn = __('Paypal subscription profile has failed.', MS_TEXT_DOMAIN);
                         $member->cancel_membership($membership->id);
                         $member->save();
                         $ignore = true;
                         break;
                     case 'new_case':
                         // New Dispute was filed for a payment.
                         $status = MS_Model_Invoice::STATUS_DENIED;
                         $ignore = true;
                         break;
                     case 'subscr_eot':
                         /*
                          * Meaning: Subscription expired.
                          *
                          *   - after a one-time payment was madeafter last
                          *   - after last transaction in a recurring subscription
                          *   - payment failed
                          *   - ...
                          *
                          * We do not handle this event...
                          *
                          * One time payment sends 3 messages:
                          *   1. subscr_start (new subscription starts)
                          *   2. subscr_payment (payment confirmed)
                          *   3. subscr_eot (subscription ends)
                          */
                         $notes_txn = __('No more payments will be made for this subscription.', MS_TEXT_DOMAIN);
                         $ignore = true;
                         break;
                     default:
                         // Other event that we do not have a case for...
                         $notes_txn = sprintf(__('Not handling txn_type: %s', MS_TEXT_DOMAIN), $transaction_type);
                         MS_Helper_Debug::log($notes_txn);
                         $ignore = true;
                         break;
                 }
             }
             if (!empty($notes_pay)) {
                 $invoice->add_notes($notes_pay);
             }
             if (!empty($notes_txn)) {
                 $invoice->add_notes($notes_txn);
             }
             $notes .= $notes_pay . ' | ' . $notes_txn;
             $invoice->save();
             if ($success) {
                 $invoice->pay_it($this->id, $external_id);
             } elseif (!empty($status)) {
                 $invoice->status = $status;
                 $invoice->save();
                 $invoice->changed();
             }
             do_action('ms_gateway_paypalstandard_payment_processed_' . $status, $invoice, $subscription);
         } else {
             $reason = 'Unexpected transaction response';
             switch (true) {
                 case is_wp_error($response):
                     $reason = 'PayPal did not verify this transaction: Unknown error';
                     break;
                 case 200 != $response['response']['code']:
                     $reason = sprintf('PayPal did not verify the transaction: Code %s', $response['response']['code']);
                     break;
                 case empty($response['body']):
                     $reason = 'PayPal did not verify this transaction: Empty response';
                     break;
                 case 'VERIFIED' != $response['body']:
                     $reason = sprintf('PayPal did not verify this transaction: "%s"', $response['body']);
                     break;
                 case $invoice->id != $invoice_id:
                     $reason = sprintf('PayPal gave us an invalid invoice_id: "%s"', $invoice_id);
                     break;
             }
             $notes = 'Response Error: ' . $reason;
             MS_Helper_Debug::log($notes);
             MS_Helper_Debug::log($response);
             MS_Helper_Debug::log($_POST);
             $exit = true;
         }
     } else {
         // Did not find expected POST variables. Possible access attempt from a non PayPal site.
         $u_agent = $_SERVER['HTTP_USER_AGENT'];
         if (false === strpos($u_agent, 'PayPal')) {
             // Very likely someone tried to open the URL manually. Redirect to home page
             $notes = 'Error: Missing POST variables. Redirect user to Home-URL.';
             MS_Helper_Debug::log($notes);
             $redirect = home_url();
         } elseif ($is_m1) {
             /*
              * The payment belongs to an imported M1 subscription and could
              * not be auto-matched.
              * Do not return an error code, but also do not modify any
              * invoice/subscription.
              */
             $notes = 'M1 Payment detected. Manual matching required.';
             $ignore = false;
             $success = false;
         } else {
             if (!$payment_status && !$transaction_type) {
                 $notes = 'Error: payment_status and txn_type not specified. Cannot process.';
             } elseif (empty($_POST['invoice']) && empty($_POST['custom'])) {
                 $notes = 'Error: No invoice or custom data specified.';
             } else {
                 $notes = 'Error: Missing POST variables. Identification is not possible.';
             }
             // PayPal did provide invalid details...
             status_header(404);
             MS_Helper_Debug::log($notes);
         }
         $exit = true;
     }
     if ($ignore && !$success) {
         $success = null;
     }
     do_action('ms_gateway_transaction_log', self::ID, 'handle', $success, $subscription_id, $invoice_id, $amount, $notes);
     if ($redirect) {
         wp_safe_redirect($redirect);
         exit;
     }
     if ($exit) {
         exit;
     }
     do_action('ms_gateway_paypalstandard_handle_return_after', $this);
 }
 public function column_membership_id($item, $column_name)
 {
     $membership = MS_Factory::load('MS_Model_Membership', $item->membership_id);
     $html = $membership->name;
     return $html;
 }