/**
     * Returns the HTML code of the view.
     *
     * @since  1.0.0
     * @api
     *
     * @return string
     */
    public function to_html()
    {
        $model = MS_Factory::create('MS_Model_Import_Membership');
        $model->prepare();
        $view = MS_Factory::create('MS_View_Settings_Import');
        $view->data = array('model' => $model, 'compact' => true);
        $msg = __('Tip: You can also import your data later by visiting the Admin page <b>Membership2 > Settings > Import Tool</b>.', 'membership2');
        ob_start();
        // Render tabbed interface.
        ?>
		<div class="ms-wrap wrap">
			<h2>
				<?php 
        _e('Import Your Membership Data To Membership2', 'membership2');
        ?>
			</h2>
			<?php 
        if (MS_Plugin::is_network_wide()) {
            $msg .= '<br><br>' . __('You have enabled Network Wide Protection. We will import Membership data from your main blog.', 'membership2');
        }
        lib3()->ui->admin_message($msg, 'info');
        ?>
			<div class="ms-settings-import">
				<?php 
        echo $view->to_html();
        ?>
			</div>
		</div>
		<?php 
        return ob_get_clean();
    }
 public function get_columns()
 {
     $currency = MS_Plugin::instance()->settings->currency;
     $columns = apply_filters('ms_helper_listtable_billing_columns', array('cb' => '<input type="checkbox" />', 'invoice' => __('Invoice #', 'membership2'), 'user' => __('User', 'membership2'), 'membership' => __('Membership', 'membership2'), 'status' => __('Status', 'membership2'), 'total' => __('Total', 'membership2'), 'due_date' => __('Due date', 'membership2'), 'gateway_id' => __('Gateway', 'membership2')));
     $columns = apply_filters('ms_helper_listtable_billing_get_columns', $columns, $currency);
     return $columns;
 }
 /**
  * Prepare html fields.
  *
  * @since  1.0.0
  *
  * @return array
  */
 function prepare_fields()
 {
     $invoice = $this->data['invoice'];
     $currency = MS_Plugin::instance()->settings->currency;
     $user_name = '';
     $transaction_link = '';
     $user_id = 0;
     $user_list = array();
     if ($invoice->id) {
         $member = $invoice->get_member();
         $user_id = $member->id;
         $user_name = $member->name;
         $transaction_link = sprintf('<a href="%s" target="_blank">%s</a>', MS_Controller_Plugin::get_admin_url('billing', array('show' => 'logs', 'invoice' => $invoice->id)), __('Show Transactions', 'membership2'));
     } else {
         $user_list = MS_Model_Member::get_usernames(null, MS_Model_Member::SEARCH_ALL_USERS);
     }
     $fields = array('link_transactions' => array('id' => 'link_transactions', 'title' => $transaction_link, 'type' => MS_Helper_Html::TYPE_HTML_TEXT, 'wrapper_class' => 'ms-transactions-link'), 'txt_user' => array('id' => 'txt_user', 'title' => __('Invoice for member', 'membership2'), 'type' => MS_Helper_Html::TYPE_HTML_TEXT, 'value' => sprintf('<a href="%s">%s</a>', MS_Controller_Plugin::get_admin_url('add-member', array('user_id' => $user_id)), $user_name)), 'txt_membership' => array('id' => 'txt_membership', 'title' => __('Payment for membership', 'membership2'), 'type' => MS_Helper_Html::TYPE_HTML_TEXT), 'txt_created' => array('id' => 'txt_created', 'title' => __('Invoice created on', 'membership2'), 'type' => MS_Helper_Html::TYPE_HTML_TEXT), 'txt_separator' => array('type' => MS_Helper_Html::TYPE_HTML_SEPARATOR), 'status' => array('id' => 'status', 'title' => __('Invoice status', 'membership2'), 'type' => MS_Helper_Html::INPUT_TYPE_SELECT, 'field_options' => MS_Model_Invoice::get_status_types(true), 'value' => $invoice->status), 'user_id' => array('id' => 'user_id', 'title' => __('Invoice for member', 'membership2'), 'type' => MS_Helper_Html::INPUT_TYPE_SELECT, 'value' => $invoice->user_id, 'field_options' => $user_list), 'membership_id' => array('id' => 'membership_id', 'title' => __('Payment for membership', 'membership2'), 'type' => MS_Helper_Html::INPUT_TYPE_SELECT, 'value' => $invoice->membership_id, 'field_options' => $this->data['memberships']), 'amount' => array('id' => 'amount', 'title' => sprintf(__('Amount (%s)', 'membership2'), $currency), 'type' => MS_Helper_Html::INPUT_TYPE_NUMBER, 'value' => MS_Helper_Billing::format_price($invoice->amount), 'config' => array('step' => 'any', 'min' => 0)), 'discount' => array('id' => 'discount', 'title' => sprintf(__('Discount (%s)', 'membership2'), $currency), 'type' => MS_Helper_Html::INPUT_TYPE_NUMBER, 'value' => MS_Helper_Billing::format_price($invoice->discount), 'config' => array('step' => 'any', 'min' => 0)), 'due_date' => array('id' => 'due_date', 'title' => __('Due date', 'membership2'), 'type' => MS_Helper_Html::INPUT_TYPE_DATEPICKER, 'value' => $invoice->due_date), 'description' => array('id' => 'description', 'title' => __('Description', 'membership2'), 'type' => MS_Helper_Html::INPUT_TYPE_TEXT, 'class' => 'widefat', 'value' => $invoice->description), 'notes' => array('id' => 'notes', 'title' => __('Notes', 'membership2'), 'type' => MS_Helper_Html::INPUT_TYPE_TEXT_AREA, 'class' => 'widefat', 'value' => $invoice->get_notes_desc()), 'invoice_id' => array('id' => 'invoice_id', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => $invoice->id), '_wpnonce' => array('id' => '_wpnonce', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => wp_create_nonce($this->data['action'])), 'action' => array('id' => 'action', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => $this->data['action']), 'separator' => array('type' => MS_Helper_Html::TYPE_HTML_SEPARATOR), 'execute' => array('id' => 'execute', 'title' => __('Execute status change actions on Save (add/remove membership)', 'membership2'), 'type' => MS_Helper_Html::INPUT_TYPE_CHECKBOX, 'value' => true), 'cancel' => array('id' => 'cancel', 'type' => MS_Helper_Html::TYPE_HTML_LINK, 'title' => __('Cancel', 'membership2'), 'value' => __('Cancel', 'membership2'), 'url' => esc_url_raw(remove_query_arg(array('action', 'invoice_id'))), 'class' => 'wpmui-field-button button'), 'submit' => array('id' => 'submit', 'type' => MS_Helper_Html::INPUT_TYPE_SUBMIT, 'value' => __('Save Changes', 'membership2')));
     if ($invoice->id > 0) {
         $fields['user_id']['type'] = MS_Helper_Html::INPUT_TYPE_HIDDEN;
         $fields['membership_id']['type'] = MS_Helper_Html::INPUT_TYPE_HIDDEN;
         $fields['txt_membership']['value'] = $this->data['memberships'][$invoice->membership_id];
         $fields['txt_created']['value'] = MS_Helper_Period::format_date($invoice->invoice_date);
     } else {
         unset($fields['txt_user']);
         unset($fields['txt_membership']);
         unset($fields['txt_created']);
         unset($fields['txt_separator']);
     }
     return apply_filters('ms_view_billing_edit_prepare_fields', $fields, $this);
 }
 /**
  * Defines the columns of the list table
  *
  * @since  1.0.0
  * @return array
  */
 public function get_columns()
 {
     $currency = MS_Plugin::instance()->settings->currency;
     $columns = apply_filters('ms_helper_listtable_transactionlog_columns', array('id' => __('ID', 'membership2'), 'date' => __('Time', 'membership2'), 'status' => '', 'method' => '', 'gateway' => __('Gateway', 'membership2'), 'amount' => __('Amount', 'membership2'), 'invoice' => __('Invoice', 'membership2'), 'note' => __('Details', 'membership2')));
     $columns = apply_filters('ms_helper_listtable_transactionlog_get_columns', $columns, $currency);
     return $columns;
 }
    public function to_html()
    {
        $settings = $this->data['settings'];
        $fields = array('plugin_enabled' => array('id' => 'plugin_enabled', 'type' => MS_Helper_Html::INPUT_TYPE_RADIO_SLIDER, 'title' => __('Content Protection', 'membership2'), 'desc' => __('This setting toggles the content protection on this site.', 'membership2'), 'value' => MS_Plugin::is_enabled(), 'data_ms' => array('action' => MS_Controller_Settings::AJAX_ACTION_TOGGLE_SETTINGS, 'setting' => 'plugin_enabled')), 'hide_admin_bar' => array('id' => 'hide_admin_bar', 'type' => MS_Helper_Html::INPUT_TYPE_RADIO_SLIDER, 'title' => __('Hide admin toolbar', 'membership2'), 'desc' => __('Hide the admin toolbar for non administrator users.', 'membership2'), 'value' => $settings->hide_admin_bar, 'data_ms' => array('action' => MS_Controller_Settings::AJAX_ACTION_TOGGLE_SETTINGS, 'setting' => 'hide_admin_bar')));
        $fields = apply_filters('ms_view_settings_prepare_general_fields', $fields);
        $setup = MS_Factory::create('MS_View_Settings_Page_Setup');
        $action_url = esc_url_raw(remove_query_arg(array('msg')));
        ob_start();
        MS_Helper_Html::settings_tab_header();
        ?>

		<form action="<?php 
        echo esc_url($action_url);
        ?>
" method="post" class="cf">
			<div class="cf">
				<div class="ms-half">
					<?php 
        MS_Helper_Html::html_element($fields['plugin_enabled']);
        ?>
				</div>
				<div class="ms-half">
					<?php 
        MS_Helper_Html::html_element($fields['hide_admin_bar']);
        ?>
				</div>
			</div>
			<?php 
        MS_Helper_Html::html_separator();
        MS_Helper_Html::html_element($setup->html_full_form());
        ?>
		</form>
		<?php 
        return ob_get_clean();
    }
 /**
  * validates and prepares the option key before it is used to read/write
  * a value in the database.
  *
  * @since  1.0.0
  * @api Used by MS_Factory
  *
  * @return string
  */
 public function option_key()
 {
     // Option key should be all lowercase.
     $key = strtolower(get_class($this));
     // Network-wide mode uses different options then single-site mode.
     if (MS_Plugin::is_network_wide()) {
         $key .= '-network';
     }
     return substr($key, 0, 64);
 }
 /**
  * Sets the parent gateway of the API object.
  *
  * The parent gateway object is used to fetch the API keys.
  *
  * @since 1.0.1.0
  * @param MS_Gateway $gateway The parent gateway.
  */
 public function set_gateway($gateway)
 {
     static $Stripe_Loaded = false;
     if (!$Stripe_Loaded) {
         require_once MS_Plugin::instance()->dir . '/lib/stripe-php/lib/Stripe.php';
         do_action('ms_gateway_stripe_load_stripe_lib_after', $this);
         $Stripe_Loaded = true;
     }
     $this->_gateway = $gateway;
     $secret_key = $this->_gateway->get_secret_key();
     M2_Stripe::setApiKey($secret_key);
 }
 public function column_discount($item)
 {
     $html = '';
     if (MS_Addon_Coupon_Model::TYPE_VALUE == $item->discount_type) {
         $html = sprintf('%s %s', MS_Plugin::instance()->settings->currency, MS_Helper_Billing::format_price($item->discount));
     } elseif (MS_Addon_Coupon_Model::TYPE_PERCENT == $item->discount_type) {
         $html = $item->discount . ' %';
     } else {
         $html = apply_filters('ms_addon_coupon_helper_listtable_column_discount', $item->discount);
     }
     return $html;
 }
 /**
  * Processes a single import command.
  *
  * @since  1.0.0
  * @param  array $item The import command.
  */
 protected function process_item($item, $source)
 {
     $res = false;
     lib2()->array->equip($item, 'task', 'data');
     $task = $item['task'];
     $data = $item['data'];
     $model = MS_Factory::create('MS_Model_Import');
     $model->source_key = $source;
     // Set MS_STOP_EMAILS modifier to suppress any outgoing emails.
     MS_Plugin::set_modifier('MS_STOP_EMAILS', true);
     // Possible tasks are defined in ms-view-settings-import.js
     switch ($task) {
         case 'start':
             lib2()->array->equip($item, 'clear');
             $clear = lib2()->is_true($item['clear']);
             $model->start($clear);
             $res = true;
             break;
         case 'import-membership':
             // Function expects an object, not an array!
             $data = (object) $data;
             $model->import_membership($data);
             $res = true;
             break;
         case 'import-member':
             // Function expects an object, not an array!
             $data = (object) $data;
             $model->import_member($data);
             $res = true;
             break;
         case 'import-settings':
             lib2()->array->equip($item, 'setting', 'value');
             $setting = $item['setting'];
             $value = $item['value'];
             $model->import_setting($setting, $value);
             $res = true;
             break;
         case 'done':
             $model->done();
             $res = true;
             break;
     }
     /**
      * After the import action was complated notify other objects and
      * add-ons.
      *
      * @since  1.0.0
      */
     do_action('ms_import_action_' . $task, $item);
     return $res;
 }
 /**
  * Prepare the metabox.
  *
  * @since  1.0.0
  */
 public function __construct()
 {
     parent::__construct();
     $this->metabox_title = __('Membership Access', 'membership2');
     $post_types = array_merge(array('page', 'post', 'attachment'), array());
     $this->post_types = apply_filters('ms_controller_membership_metabox_add_meta_boxes_post_types', $post_types);
     if (!MS_Plugin::is_enabled()) {
         return $this;
     }
     $this->add_action('add_meta_boxes', 'add_meta_boxes', 10);
     $this->add_action('admin_enqueue_scripts', 'admin_enqueue_scripts');
     $this->add_ajax_action(self::AJAX_ACTION_TOGGLE_ACCESS, 'ajax_action_toggle_metabox_access');
     // Populates the WP editor with default contents of a page
     $this->add_action('the_editor_content', 'show_default_content');
 }
 /**
  * Prepare html fields.
  *
  * @since  1.0.0
  *
  * @return array
  */
 function prepare_fields()
 {
     $invoice = $this->data['invoice'];
     $currency = MS_Plugin::instance()->settings->currency;
     $fields = array('txt_user' => array('id' => 'txt_user', 'title' => __('Username', MS_TEXT_DOMAIN), 'type' => MS_Helper_Html::TYPE_HTML_TEXT, 'value' => $this->data['users'][$invoice->user_id]), 'txt_membership' => array('id' => 'txt_membership', 'title' => __('Membership', MS_TEXT_DOMAIN), 'type' => MS_Helper_Html::TYPE_HTML_TEXT), 'txt_separator' => array('type' => MS_Helper_Html::TYPE_HTML_SEPARATOR), 'status' => array('id' => 'status', 'title' => __('Status', MS_TEXT_DOMAIN), 'type' => MS_Helper_Html::INPUT_TYPE_SELECT, 'field_options' => MS_Model_Invoice::get_status_types(), 'value' => $invoice->status), 'user_id' => array('id' => 'user_id', 'title' => __('Username', MS_TEXT_DOMAIN), 'type' => MS_Helper_Html::INPUT_TYPE_SELECT, 'value' => $invoice->user_id, 'field_options' => $this->data['users']), 'membership_id' => array('id' => 'membership_id', 'title' => __('Membership', MS_TEXT_DOMAIN), 'type' => MS_Helper_Html::INPUT_TYPE_SELECT, 'value' => $invoice->membership_id, 'field_options' => $this->data['memberships']), 'description' => array('id' => 'description', 'title' => __('Description', MS_TEXT_DOMAIN), 'type' => MS_Helper_Html::INPUT_TYPE_TEXT, 'value' => $invoice->description), 'amount' => array('id' => 'amount', 'title' => sprintf(__('Amount (%s)', MS_TEXT_DOMAIN), $currency), 'type' => MS_Helper_Html::INPUT_TYPE_TEXT, 'value' => $invoice->amount), 'discount' => array('id' => 'discount', 'title' => sprintf(__('Discount (%s)', MS_TEXT_DOMAIN), $currency), 'type' => MS_Helper_Html::INPUT_TYPE_TEXT, 'value' => $invoice->discount), 'due_date' => array('id' => 'due_date', 'title' => __('Due date', MS_TEXT_DOMAIN), 'type' => MS_Helper_Html::INPUT_TYPE_DATEPICKER, 'value' => $invoice->due_date), 'notes' => array('id' => 'notes', 'title' => __('Notes', MS_TEXT_DOMAIN), 'type' => MS_Helper_Html::INPUT_TYPE_TEXT_AREA, 'value' => $invoice->get_notes_desc()), 'invoice_id' => array('id' => 'invoice_id', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => $invoice->id), '_wpnonce' => array('id' => '_wpnonce', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => wp_create_nonce($this->data['action'])), 'action' => array('id' => 'action', 'type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'value' => $this->data['action']), 'separator' => array('type' => MS_Helper_Html::TYPE_HTML_SEPARATOR), 'execute' => array('id' => 'execute', 'title' => __('Execute status change actions on Save (add/remove membership)', MS_TEXT_DOMAIN), 'type' => MS_Helper_Html::INPUT_TYPE_CHECKBOX, 'value' => true), 'cancel' => array('id' => 'cancel', 'type' => MS_Helper_Html::TYPE_HTML_LINK, 'title' => __('Cancel', MS_TEXT_DOMAIN), 'value' => __('Cancel', MS_TEXT_DOMAIN), 'url' => esc_url_raw(remove_query_arg(array('action', 'invoice_id'))), 'class' => 'wpmui-field-button button'), 'submit' => array('id' => 'submit', 'type' => MS_Helper_Html::INPUT_TYPE_SUBMIT, 'value' => __('Save Changes', MS_TEXT_DOMAIN)));
     if ($invoice->id > 0) {
         $fields['user_id']['type'] = MS_Helper_Html::INPUT_TYPE_HIDDEN;
         $fields['membership_id']['type'] = MS_Helper_Html::INPUT_TYPE_HIDDEN;
         $fields['txt_membership']['value'] = $this->data['memberships'][$invoice->membership_id];
     } else {
         unset($fields['txt_user']);
         unset($fields['txt_membership']);
         unset($fields['txt_separator']);
     }
     return apply_filters('ms_view_billing_edit_prepare_fields', $fields, $this);
 }
 /**
  * Get available tabs.
  *
  * @since  1.0.0
  *
  * @return array The tabs configuration.
  */
 public function get_tabs()
 {
     $tabs = array('general' => array('title' => __('General', MS_TEXT_DOMAIN)), 'shortcodes' => array('title' => __('Shortcodes', MS_TEXT_DOMAIN)), 'network' => array('title' => __('Network-Wide Protection', MS_TEXT_DOMAIN)), 'advanced' => array('title' => __('Advanced Settings', MS_TEXT_DOMAIN)), 'api' => array('title' => __('API Docs', MS_TEXT_DOMAIN), 'url' => MS_Plugin::instance()->url . 'docs/namespaces/default.html', 'target' => '_blank'));
     if (!is_multisite()) {
         unset($tabs['network']);
     }
     lib2()->array->equip_get('page');
     $def_key = MS_Controller_Plugin::MENU_SLUG . '-help';
     $page = sanitize_html_class($_GET['page'], $def_key);
     foreach ($tabs as $key => $tab) {
         if (empty($tabs[$key]['url'])) {
             $tabs[$key]['url'] = sprintf('admin.php?page=%1$s&tab=%2$s', esc_attr($page), esc_attr($key));
         }
     }
     return apply_filters('ms_controller_help_get_tabs', $tabs, $this);
 }
Example #13
0
    /**
     * Overrides parent's to_html() method.
     *
     * Creates an output buffer, outputs the HTML and grabs the buffer content before releasing it.
     * Creates a wrapper 'ms-wrap' HTML element to contain content and navigation. The content inside
     * the navigation gets loaded with dynamic method calls.
     * e.g. if key is 'settings' then render_settings() gets called, if 'bob' then render_bob().
     *
     * @since  1.0.0
     * @api
     *
     * @return string
     */
    public function to_html()
    {
        $form_fields = $this->prepare_fields();
        $setup_url = MS_Controller_Plugin::get_admin_url('setup');
        ob_start();
        // Render tabbed interface.
        ?>
		<div class="ms-wrap wrap">
			<form class="ms-welcome-box" action="<?php 
        echo esc_url($setup_url);
        ?>
" method="POST">
				<h2 class="ms-welcome-title">
					<?php 
        _e('Welcome!', MS_TEXT_DOMAIN);
        ?>
				</h2>

				<div class="ms-welcome-text">
					<?php 
        _e('Hello and welcome to <strong>Membership2</strong> by WPMU DEV. Please follow this simple set-up<br />wizard to help us determine the settings that are most relevant to your needs. Don\'t worry, you<br />can always change these settings in the future.', MS_TEXT_DOMAIN);
        ?>
				</div>

				<div class="ms-welcome-image-box">
					<img src="<?php 
        echo esc_attr(MS_Plugin::instance()->url);
        ?>
app/assets/images/welcome.png" class="ms-welcome-image" />
				</div>

				<?php 
        foreach ($form_fields as $field) {
            MS_Helper_Html::html_element($field);
        }
        ?>
			</form>
		</div>
		<?php 
        return ob_get_clean();
    }
Example #14
0
 /**
  * Adds the hooks to integrate with Membership2.
  *
  * This function is called when Membership2 is active and initializtion
  * is done.
  *
  * @since  1.0.0
  * @param  MS_Controller_Api $api The API instance.
  */
 public function init($api)
 {
     $this->api = $api;
     if (MS_Plugin::is_network_wide()) {
         $affiliate_plugin = 'affiliate/affiliate.php';
         if (!function_exists('is_plugin_active_for_network')) {
             require_once ABSPATH . '/wp-admin/includes/plugin.php';
         }
         if (!is_plugin_active_for_network($affiliate_plugin) && current_user_can('manage_options')) {
             lib2()->ui->admin_message(__('Membership2 uses network-wide protection.<br>Please network activate the Affiliate plugin to avoid problems with the Membership2 integration for Affiliates.', 'affiliate'), 'err');
         }
     }
     // -- Frontend integration
     // Reward for the referrer of the member.
     add_action('ms_invoice_paid', array($this, 'payment_processed'), 10, 2);
     // -- Admin integration
     // Display Affiliate settings on the Membership payment options page.
     add_action('ms_view_membership_payment_form', array($this, 'form'), 10, 2);
     // Save Affiliate settings via Ajax request.
     add_action('wp_ajax_' . self::AJAX_ACTION, array($this, 'save'));
 }
Example #15
0
 /**
  * Checks if the specified rule-key defines a rule that is relevant for the
  * current site in the network.
  *
  * If network-wide protection is disabled this function always returns true.
  *
  * @since  1.0.0
  * @param  string $key
  * @return bool
  */
 public static function is_current_site($key)
 {
     $res = true;
     $site_id = 0;
     if (MS_Plugin::is_network_wide()) {
         $parts = explode(':', $key);
         // Some rules have no site_id prefix (like URL rules)
         if (2 == count($parts)) {
             list($site_id, $type) = $parts;
             $site_id = intval($site_id);
             $res = MS_Factory::current_blog_id() == $site_id;
         }
     }
     return $res;
 }
 /**
  * Get a simple array of capabilties (e.g. for display in select lists)
  *
  * @since  1.0.0
  * @global array $menu
  *
  * @return array {
  *      @type string $id The id.
  *      @type string $name The name.
  * }
  */
 public function get_capabilities($args = null)
 {
     if (null === $this->_content_array) {
         $this->_content_array = array();
         $member = MS_Model_Member::get_current_member();
         $capslist = $member->wp_user->allcaps;
         $ignored_caps = array('level_10' => 1, 'level_9' => 1, 'level_8' => 1, 'level_7' => 1, 'level_6' => 1, 'level_5' => 1, 'level_4' => 1, 'level_3' => 1, 'level_2' => 1, 'level_1' => 1, 'level_0' => 1, 'administrator' => 1);
         $capslist = array_diff_assoc($capslist, $ignored_caps);
         $capslist = array_keys($capslist);
         /**
          * Exclude certain capabilities for security reasons.
          *
          * @since  1.0.0
          * @var array
          */
         $exclude = apply_filters('ms_rule_membercaps_model_exclude', array(MS_Plugin::instance()->controller->capability, 'edit_plugins', 'delete_plugins', 'edit_files', 'edit_users', 'delete_users', 'remove_users', 'promote_users', 'list_users'));
         $capslist = array_diff($capslist, $exclude);
         $this->_content_array = array_combine($capslist, $capslist);
         // Make sure the rule_value only contains valid items.
         $rule_value = array_intersect_key($this->rule_value, $this->_content_array);
         $this->rule_value = lib2()->array->get($rule_value);
         // If not visitor membership, just show Membership2
         if (!$this->get_membership()->is_base()) {
             $this->_content_array = array_intersect_key($this->_content_array, $this->rule_value);
         }
         $this->_content_array = apply_filters('ms_rule_membercaps_model_get_content_array', $this->_content_array, $this);
     }
     $contents = $this->_content_array;
     // Search the shortcode-tag...
     if (!empty($args['s'])) {
         foreach ($contents as $key => $name) {
             if (false === stripos($name, $args['s'])) {
                 unset($contents[$key]);
             }
         }
     }
     $filter = self::get_exclude_include($args);
     if (is_array($filter->include)) {
         $contents = array_intersect($contents, $filter->include);
     } elseif (is_array($filter->exclude)) {
         $contents = array_diff($contents, $filter->exclude);
     }
     // Pagination
     if (!empty($args['posts_per_page'])) {
         $total = $args['posts_per_page'];
         $offset = !empty($args['offset']) ? $args['offset'] : 0;
         $contents = array_slice($contents, $offset, $total);
     }
     return $contents;
 }
 /**
  * Returns the Taxamo REST API object.
  *
  * Important: All calls to `taxamo()->` functions must be wrapped in
  * try..catch because an invalid API token will result in a fatal error.
  *
  * @since  1.0.0
  * @return Taxamo
  */
 protected static function taxamo()
 {
     static $Taxamo = null;
     if (null === $Taxamo) {
         if (!class_exists('Taxamo')) {
             require_once MS_Plugin::instance()->dir . '/lib/taxamo/Taxamo.php';
         }
         // Initialize the Taxamo API connection
         $connection = new APIClient(MS_Addon_Taxamo::model()->get('private_key'), 'https://api.taxamo.com');
         // Initialize the Taxamo REST API wrapper.
         $Taxamo = new Taxamo($connection);
         // Initialize the API object.
         self::init();
     }
     return $Taxamo;
 }
    /**
     * Returns the contens of the dialog
     *
     * @since  1.0.0
     *
     * @return object
     */
    public function get_contents($data)
    {
        $member = $data['model'];
        $currency = MS_Plugin::instance()->settings->currency;
        $show_trial = MS_Model_Addon::is_enabled(MS_Model_Addon::ADDON_TRIAL);
        $all_subscriptions = MS_Model_Relationship::get_subscriptions(array('user_id' => $member->id, 'status' => 'all', 'meta_key' => 'expire_date', 'orderby' => 'meta_value', 'order' => 'DESC'));
        // Prepare the form fields.
        $inp_dialog = array('type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'name' => 'dialog', 'value' => 'View_Member_Dialog');
        $inp_id = array('type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'name' => 'member_id', 'value' => $member->id);
        $inp_nonce = array('type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'name' => '_wpnonce', 'value' => wp_create_nonce(self::ACTION_SAVE));
        $inp_action = array('type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'name' => 'dialog_action', 'value' => self::ACTION_SAVE);
        $inp_save = array('type' => MS_Helper_Html::INPUT_TYPE_SUBMIT, 'value' => __('Save', 'membership2'), 'class' => 'ms-submit-form', 'data' => array('form' => 'ms-edit-member'));
        $inp_cancel = array('type' => MS_Helper_Html::INPUT_TYPE_BUTTON, 'value' => __('Close', 'membership2'), 'class' => 'close');
        ob_start();
        ?>
		<div>
			<form class="ms-form wpmui-ajax-update ms-edit-member" data-wpmui-ajax="<?php 
        echo esc_attr('save');
        ?>
">
				<div class="ms-form wpmui-form wpmui-grid-8">
					<table class="widefat">
					<thead>
						<tr>
							<th class="column-membership">
								<?php 
        _e('Membership', 'membership2');
        ?>
							</th>
							<th class="column-status">
								<?php 
        _e('Status', 'membership2');
        ?>
							</th>
							<th class="column-start">
								<?php 
        _e('Subscribed on', 'membership2');
        ?>
							</th>
							<th class="column-expire">
								<?php 
        _e('Expires on', 'membership2');
        ?>
							</th>
							<?php 
        if ($show_trial) {
            ?>
							<th class="column-trialexpire">
								<?php 
            _e('Trial until', 'membership2');
            ?>
							</th>
							<?php 
        }
        ?>
							<th class="column-payments">
								<?php 
        _e('Payments', 'membership2');
        ?>
							</th>
						</tr>
					</thead>
					<tbody>
					<?php 
        foreach ($all_subscriptions as $subscription) {
            $membership = $subscription->get_membership();
            $payments = $subscription->get_payments();
            $num_payments = count($payments);
            $amount_payments = 0;
            foreach ($payments as $payment) {
                $amount_payments += $payment['amount'];
            }
            $subscription_info = array('subscription_id' => $subscription->id);
            $update_info = array('subscription_id' => $subscription->id, 'statuscheck' => 'yes');
            ?>
						<tr>
							<td class="column-membership">
								<?php 
            $membership->name_tag();
            ?>
							</td>
							<td class="column-status">
								<?php 
            printf('<a href="#" data-ms-dialog="View_Member_Subscription" data-ms-data="%2$s">%1$s</a>
									<a href="#" data-ms-dialog="View_Member_Subscription" data-ms-data="%3$s" title="%5$s">%4$s</a>', $subscription->status, esc_attr(json_encode($subscription_info)), esc_attr(json_encode($update_info)), '<i class="dashicons dashicons-update"></i>', __('Check and update subscription status', 'membership2'));
            ?>
							</td>
							<td class="column-start">
								<?php 
            echo $subscription->start_date;
            ?>
							</td>
							<td class="column-expire">
								<?php 
            echo $subscription->expire_date;
            ?>
							</td>
							<?php 
            if ($show_trial) {
                ?>
							<td class="column-trialexpire">
								<?php 
                if ($subscription->start_date == $subscription->trial_expire_date) {
                    echo '-';
                } else {
                    echo $subscription->trial_expire_date;
                }
                ?>
							</td>
							<?php 
            }
            ?>
							<td class="column-payments">
								<?php 
            $total = sprintf('<b>%1$s</b> (%3$s %2$s)', $num_payments, MS_Helper_Billing::format_price($amount_payments), $currency);
            printf('<a href="#" data-ms-dialog="View_Member_Payment" data-ms-data="%1$s">%2$s</a>', esc_attr(json_encode($subscription_info)), $total);
            ?>
							</td>
						</tr>
					<?php 
        }
        ?>
					</tbody>
					</table>
				</div>
				<?php 
        MS_Helper_Html::html_element($inp_id);
        MS_Helper_Html::html_element($inp_dialog);
        MS_Helper_Html::html_element($inp_nonce);
        MS_Helper_Html::html_element($inp_action);
        ?>
			</form>
			<div class="buttons">
				<?php 
        MS_Helper_Html::html_element($inp_cancel);
        // MS_Helper_Html::html_element( $inp_save );
        ?>
			</div>
		</div>
		<?php 
        $html = ob_get_clean();
        return apply_filters('ms_view_member_dialog_to_html', $html);
    }
    public function to_html()
    {
        ob_start();
        ?>
		<div class="ms-account-wrapper">
			<?php 
        if (MS_Model_Member::is_logged_in()) {
            ?>
				<h2>
					<?php 
            _e('Invoice', MS_TEXT_DOMAIN);
            ?>
				</h2>
				<table>
					<thead>
						<tr>
							<th class="ms-col-invoice-no"><?php 
            _e('Invoice #', MS_TEXT_DOMAIN);
            ?>
</th>
							<th class="ms-col-invoice-status"><?php 
            _e('Status', MS_TEXT_DOMAIN);
            ?>
</th>
							<th class="ms-col-invoice-total"><?php 
            printf('%s (%s)', __('Total', MS_TEXT_DOMAIN), MS_Plugin::instance()->settings->currency);
            ?>
</th>
							<th class="ms-col-invoice-title"><?php 
            _e('Membership', MS_TEXT_DOMAIN);
            ?>
</th>
							<th class="ms-col-invoice-due"><?php 
            _e('Due date', MS_TEXT_DOMAIN);
            ?>
</th>
						</tr>
					</thead>
					<tbody>
					<?php 
            foreach ($this->data['invoices'] as $invoice) {
                $inv_membership = MS_Factory::load('MS_Model_Membership', $invoice->membership_id);
                $inv_classes = array('ms-invoice-' . $invoice->id, 'ms-subscription-' . $invoice->ms_relationship_id, 'ms-invoice-' . $invoice->status, 'ms-gateway-' . $invoice->gateway_id, 'ms-membership-' . $invoice->membership_id, 'ms-type-' . $inv_membership->type, 'ms-payment-' . $inv_membership->payment_type);
                ?>
						<tr class="<?php 
                echo esc_attr(implode(' ', $inv_classes));
                ?>
">
							<td class="ms-col-invoice-no"><?php 
                printf('<a href="%s">%s</a>', get_permalink($invoice->id), $invoice->get_invoice_number());
                ?>
</td>
							<td class="ms-col-invoice-status"><?php 
                echo esc_html($invoice->status_text());
                ?>
</td>
							<td class="ms-col-invoice-total"><?php 
                echo esc_html(MS_Helper_Billing::format_price($invoice->total));
                ?>
</td>
							<td class="ms-col-invoice-title"><?php 
                echo esc_html($inv_membership->name);
                ?>
</td>
							<td class="ms-col-invoice-due"><?php 
                echo esc_html(MS_Helper_Period::format_date($invoice->due_date, __('F j', MS_TEXT_DOMAIN)));
                ?>
</td>
						</tr>
					<?php 
            }
            ?>
					</tbody>
				</table>
			<?php 
        } else {
            ?>
				<?php 
            $redirect = esc_url_raw(add_query_arg(array()));
            $title = __('Your account', MS_TEXT_DOMAIN);
            echo do_shortcode("[ms-membership-login redirect='{$redirect}' title='{$title}']");
            ?>
			<?php 
        }
        ?>
		</div>
		<?php 
        $html = ob_get_clean();
        $html = apply_filters('ms_compact_code', $html);
        return $html;
    }
 /**
  * Appends classes to the HTML body that identify all memberships that the
  * current user is registered to. This allows webdesigners to adjust layout
  * or hide elements based on the membership a user has.
  *
  * @since  1.0.0
  *
  * @param  array $class Class-names to attach to the body.
  * @return array Modified class-names to attach to the body.
  */
 public function body_class($classes)
 {
     $member = MS_Model_Member::get_current_member();
     if (!$member->is_logged_in()) {
         $classes[] = 'ms-guest';
     } else {
         $classes[] = 'ms-member';
         $classes[] = 'ms-member-' . $member->id;
     }
     $info = MS_Plugin::instance()->controller->get_access_info();
     foreach ($info['memberships'] as $membership_id) {
         $classes[] = 'ms-' . absint($membership_id);
     }
     return $classes;
 }
 /**
  * Track wizard step.
  *
  * Save current step.
  *
  * since 1.0.0
  *
  * @param string $step Optional. The step to save. Default to current step.
  * @param boolean $end_wizard Optional. Whether end the wizard mode.
  * @return string The current step.
  */
 public function wizard_tracker($step = null, $end_wizard = false)
 {
     $settings = MS_Plugin::instance()->settings;
     if (empty($step)) {
         $step = $this->get_step();
     }
     if (MS_Plugin::is_wizard()) {
         $settings->wizard_step = $step;
         if ($end_wizard) {
             $settings->initial_setup = false;
         }
         $settings->save();
     }
     do_action('ms_controller_membership_wizard_tracker', $step, $end_wizard, $settings, $this);
 }
Example #22
0
 /**
  * This funciton initializes the api property for easy access to the plugin
  * API. This function is *only* called by MS_Controller_Api::__construct()!
  *
  * @since  1.0.0
  * @internal
  * @param MS_Controller_Api $controller The initialized API controller.
  */
 public static function set_api($controller)
 {
     self::$api = $controller;
 }
 /**
  * Verify is user is Admin user.
  *
  * @since  1.0.0
  * @api
  *
  * @param  int|false $user_id Optional. The user ID. Default to current user.
  * @param  bool $deprecated Do not use.
  * @return boolean True if user is admin.
  */
 public static function is_admin_user($user_id = false)
 {
     $cache_result = true;
     if (!isset(self::$_is_admin_user[$user_id])) {
         $is_admin = false;
         $default_user_id = null;
         if (empty($user_id)) {
             $default_user_id = $user_id;
             $user_id = self::get_user_id();
         }
         if (is_super_admin($user_id)) {
             // Superadmin always is considered admin user, no discussion...
             $is_admin = true;
         } else {
             /**
              * Use the capability defined by the main plugin controller.
              *
              * This capability defines which user is considered admin user.
              * An Admin user has full permissions to edit M2 settings.
              *
              * To modify the capability:
              *   Use filter `ms_admin_user_capability`  or
              *   define( 'MS_ADMIN_CAPABILITY', '...' )
              *
              * @var string|bool A WordPress capability or boolean false.
              */
             $controller = MS_Plugin::instance()->controller;
             if ($controller) {
                 $capability = $controller->capability;
             } else {
                 // This is used in case the function is called too early.
                 $capability = 'manage_options';
                 $cache_result = false;
             }
             if (!empty($capability)) {
                 if (empty($user_id)) {
                     $is_admin = current_user_can($capability);
                 } else {
                     $is_admin = user_can($user_id, $capability);
                 }
             }
             $is_admin = apply_filters('ms_model_member_is_admin_user', $is_admin, $user_id, $capability);
         }
         if ($cache_result) {
             self::$_is_admin_user[$user_id] = $is_admin;
             if (null !== $default_user_id) {
                 self::$_is_admin_user[$default_user_id] = $is_admin;
             }
         }
     } else {
         $is_admin = self::$_is_admin_user[$user_id];
     }
     return $is_admin;
 }
 /**
  * Creates a new WordPress menu and adds all top level pages to this menu.
  *
  * @since  1.0.0
  */
 public static function create_default_menu()
 {
     if (MS_Plugin::is_network_wide()) {
         return;
     }
     $menu_id = wp_create_nav_menu(__('Default Menu', MS_TEXT_DOMAIN));
     if (!is_numeric($menu_id) || $menu_id <= 0) {
         return;
     }
     // Use the new menu in the menu-location of the theme.
     $locations = get_theme_mod('nav_menu_locations');
     if (is_array($locations) && count($locations) > 0) {
         reset($locations);
         $first = key($locations);
         $locations[$first] = $menu_id;
         set_theme_mod('nav_menu_locations', $locations);
     }
     // Enable the Auto-Add-New-Pages option.
     // Code snippet from wp-admin/includes/nav-menu.php
     $nav_menu_option = (array) get_option('nav_menu_options');
     if (!isset($nav_menu_option['auto_add'])) {
         $nav_menu_option['auto_add'] = array();
     }
     if (!in_array($menu_id, $nav_menu_option['auto_add'])) {
         $nav_menu_option['auto_add'][] = $menu_id;
     }
     update_option('nav_menu_options', $nav_menu_option);
     // Get a list of all published top-level pages.
     $top_pages = get_pages(array('parent' => 0));
     // List of pages that should not be displayed in the menu.
     $skip_pages = array(self::MS_PAGE_PROTECTED_CONTENT, self::MS_PAGE_REG_COMPLETE);
     foreach ($top_pages as $page) {
         // Skip pages that should not appear in menu.
         $ms_type = self::is_membership_page($page->ID);
         if (in_array($ms_type, $skip_pages)) {
             continue;
         }
         // Add the page to our new menu!
         $item = array('menu-item-object-id' => $page->ID, 'menu-item-object' => $page->post_type, 'menu-item-type' => 'post_type', 'menu-item-status' => $page->post_status);
         wp_update_nav_menu_item($menu_id, 0, $item);
     }
 }
 /**
  * Ajax action handler used by the transaction logs list to change a
  * transaction log entry.
  *
  * Returns a list of requested items
  *
  * @since  1.0.1.0
  */
 public function ajax_link_data_transaction()
 {
     $resp = array();
     $fields = array('get', 'for');
     if (self::validate_required($fields) && $this->verify_nonce()) {
         $type = $_POST['get'];
         $id = intval($_POST['for']);
         $settings = MS_Plugin::instance()->settings;
         if ('subscriptions' == $type) {
             $member = MS_Factory::load('MS_Model_Member', $id);
             $resp[0] = __('Select a subscription', 'membership2');
             $active = array();
             $inactive = array();
             foreach ($member->subscriptions as $subscription) {
                 if ($subscription->is_system()) {
                     continue;
                 }
                 $membership = $subscription->get_membership();
                 if ($membership->is_free()) {
                     $price = __('Free', 'membership2');
                 } else {
                     $price = sprintf('%s %s', $settings->currency, MS_Helper_Billing::format_price($membership->price));
                 }
                 $line = sprintf(__('Membership: %s, Base price: %s', 'membership2'), $membership->name, $price);
                 if ($subscription->is_expired()) {
                     $inactive[$subscription->id] = $line;
                 } else {
                     $active[$subscription->id] = $line;
                 }
             }
             if (!count($active) && !count($inactive)) {
                 $resp[0] = __('No subscriptions found', 'membership2');
             } else {
                 if (count($active)) {
                     $resp[__('Active Subscriptions', 'membership2')] = $active;
                 }
                 if (count($inactive)) {
                     $resp[__('Expired Subscriptions', 'membership2')] = $inactive;
                 }
             }
         } elseif ('invoices' == $type) {
             $subscription = MS_Factory::load('MS_Model_Relationship', $id);
             $invoices = $subscription->get_invoices();
             $resp[0] = __('Select an invoice', 'membership2');
             $unpaid = array();
             $paid = array();
             foreach ($invoices as $invoice) {
                 $line = sprintf(__('Invoice: %s from %s (%s)', 'membership2'), $invoice->get_invoice_number(), $invoice->due_date, $invoice->currency . ' ' . MS_Helper_Billing::format_price($invoice->total));
                 if ($invoice->is_paid()) {
                     $paid[$invoice->id] = $line;
                 } else {
                     $unpaid[$invoice->id] = $line;
                 }
             }
             if (!count($unpaid) && !count($paid)) {
                 $resp[0] = __('No invoices found', 'membership2');
             } else {
                 if (count($unpaid)) {
                     $resp[__('Unpaid Invoices', 'membership2')] = $unpaid;
                 }
                 if (count($paid)) {
                     $resp[__('Paid Invoices', 'membership2')] = $paid;
                 }
             }
         }
     }
     echo json_encode($resp);
     exit;
 }
 /**
  * Show no access image.
  *
  * @since  1.0.0
  */
 private function show_no_access_image()
 {
     $no_access_file = apply_filters('ms_rule_media_model_show_no_access_image_path', MS_Plugin::instance()->dir . 'app/assets/images/no-access.png');
     $this->output_file($no_access_file);
     do_action('ms_rule_show_no_access_image_after', $this);
 }
 /**
  * Associate a javascript file with the new TinyMCE button.
  *
  * Hooks Filters:
  * - mce_external_plugins
  *
  * @since  1.0.0
  *
  * @param  array $plugin_array List of default TinyMCE plugin scripts.
  * @return array Updated list of TinyMCE plugin scripts.
  */
 public static function add_variables_plugin($plugin_array)
 {
     $plugin_url = MS_Plugin::instance()->url;
     // This is a dummy reference (ms-admin.js is always loaded)!
     // Actually this line would not be needed, but WordPress will not show
     // our button when this is missing...
     $plugin_array['ms_variable'] = $plugin_url . 'app/assets/js/ms-admin.js';
     return $plugin_array;
 }
 /**
  * Load Membership admin scripts.
  *
  * @since  1.0.0
  */
 public function enqueue_scripts()
 {
     $active_tab = $this->get_active_tab();
     do_action('ms_controller_settings_enqueue_scripts_' . $active_tab);
     $plugin_url = MS_Plugin::instance()->url;
     $version = MS_Plugin::instance()->version;
     $initial_url = MS_Controller_Plugin::get_admin_url();
     $data = array('ms_init' => array(), 'initial_url' => $initial_url);
     $data['ms_init'][] = 'view_settings';
     switch ($active_tab) {
         case self::TAB_PAYMENT:
             add_thickbox();
             $data['ms_init'][] = 'view_settings_payment';
             break;
         case self::TAB_MESSAGES:
             $data['ms_init'][] = 'view_settings_protection';
             break;
         case self::TAB_EMAILS:
             $data['ms_init'][] = 'view_settings_automated_msg';
             break;
         case self::TAB_GENERAL:
             $data['ms_init'][] = 'view_settings_setup';
             break;
     }
     lib3()->ui->data('ms_data', $data);
     wp_enqueue_script('ms-admin');
 }
    public function to_html()
    {
        /**
         * Provide a customized invoice.
         *
         * @since  1.0.0
         */
        $html = apply_filters('ms_shortcode_custom_invoice', '', $this->data);
        if (!empty($html)) {
            return $html;
        } else {
            $html = '';
        }
        $invoice = $this->data['invoice'];
        $member = $this->data['member'];
        $subscription = $this->data['ms_relationship'];
        $membership = $this->data['membership'];
        $gateway = $this->data['gateway'];
        $is_free = false;
        $invoice_number = $invoice->get_invoice_number();
        $inv_title = sprintf('<a href="%s">%s</a>', get_permalink($invoice->id), esc_html(__('Invoice ', MS_TEXT_DOMAIN) . $invoice_number));
        if ($invoice->amount > 0) {
            $inv_amount = sprintf('%1$s %2$s', $invoice->currency, MS_Helper_Billing::format_price($invoice->amount));
        } else {
            $inv_amount = __('Free', MS_TEXT_DOMAIN);
            $is_free = true;
        }
        if ($invoice->tax) {
            $inv_taxes = sprintf('%s %s', $invoice->currency, MS_Helper_Billing::format_price($invoice->tax));
        } else {
            $inv_taxes = '';
        }
        if ($invoice->discount) {
            $inv_discount = sprintf('%s -%s', $invoice->currency, MS_Helper_Billing::format_price($invoice->discount));
        } else {
            $inv_discount = '';
        }
        if ($invoice->pro_rate) {
            $inv_pro_rate = sprintf('%s -%s', $invoice->currency, MS_Helper_Billing::format_price($invoice->pro_rate));
        } else {
            $inv_pro_rate = '';
        }
        $inv_total = sprintf('%s %s', $invoice->currency, MS_Helper_Billing::format_price($invoice->total));
        $inv_title = apply_filters('ms_invoice_title', $inv_title, $invoice);
        $inv_from = apply_filters('ms_invoice_sender', MS_Plugin::instance()->settings->invoice_sender_name, $invoice);
        $inv_to = apply_filters('ms_invoice_recipient', $member->username, $invoice, $member);
        $inv_status = apply_filters('ms_invoice_status', $invoice->status_text(), $invoice);
        $inv_item_name = apply_filters('ms_invoice_item_name', $membership->name, $invoice, $membership);
        $inv_amount = apply_filters('ms_invoice_amount', $inv_amount, $invoice);
        $inv_taxes = apply_filters('ms_invoice_taxes', $inv_taxes, $invoice);
        $inv_discount = apply_filters('ms_invoice_discount', $inv_discount, $invoice);
        $inv_pro_rate = apply_filters('ms_invoice_pro_rate', $inv_pro_rate, $invoice);
        $inv_total = apply_filters('ms_invoice_total', $inv_total, $invoice);
        $inv_details = apply_filters('ms_invoice_description', $invoice->description, $invoice, null);
        $inv_date = apply_filters('ms_invoice_date', MS_Helper_Period::format_date($invoice->invoice_date), $invoice, null);
        $inv_due_date = apply_filters('ms_invoice_due_date', MS_Helper_Period::format_date($invoice->due_date), $invoice, null);
        if ($invoice->uses_trial) {
            $trial_date = apply_filters('ms_invoice_trial_date', MS_Helper_Period::get_period_desc($membership->trial_period, true), $trial_invoice, $invoice);
            $trial_date .= sprintf(' <small>(%s %s)</small>', __('ends on', MS_TEXT_DOMAIN), MS_Helper_Period::format_date($invoice->trial_ends));
        } else {
            $trial_date = '';
        }
        ob_start();
        ?>
		<div class="entry-content ms-invoice" id="invoice">
			<?php 
        /**
         * We hardcode the CSS styles into this file, because the shortcode
         * is also used in Emails, which usually do not load remote CSS
         * files by default...
         */
        ?>
			<style>
			#invoice table, th, td { margin: 0; font-size: 14px; }
			#invoice table { padding: 0; width: 520px; border: 1px solid #DDD; background-color: #FFF; box-shadow: 0 1px 8px #F0F0F0; }
			#invoice th, td { border: 0; padding: 8px; }
			#invoice th { font-weight: bold; text-align: left; text-transform: none; font-size: 13px; }
			#invoice tr.alt { background-color: #F9F9F9; }
			#invoice tr.sep th,
			#invoice tr.sep td { border-top: 1px solid #DDD; padding-top: 16px; }
			#invoice tr.space th,
			#invoice tr.space td { padding-bottom: 16px; }
			#invoice tr.ms-inv-sep th,
			#invoice tr.ms-inv-sep td { line-height: 1px; height: 1px; padding: 0; border-bottom: 1px solid #DDD; background-color: #F9F9F9; }
			#invoice .ms-inv-total .ms-inv-price { font-weight: bold; font-size: 18px; text-align: right; }
			#invoice h2 { text-align: right; padding: 10px 10px 0 0; }
			#invoice h2 a { color: #000; }
			<?php 
        do_action('ms_invoice_css');
        ?>
			</style>

			<div class="ms-invoice-details ms-status-<?php 
        echo esc_attr($invoice->status);
        ?>
">
				<table class="ms-purchase-table">
					<tr class="ms-inv-title">
						<td colspan="2"><h2><?php 
        echo $inv_title;
        ?>
</h2></td>
					</tr>

					<?php 
        if (!empty($inv_from)) {
            ?>
						<tr class="ms-inv-from">
							<th><?php 
            _e('Sender', MS_TEXT_DOMAIN);
            ?>
</th>
							<td class="ms-inv-text"><?php 
            echo $inv_from;
            ?>
</td>
						</tr>
					<?php 
        }
        ?>

					<tr class="ms-inv-to">
						<th><?php 
        _e('Invoice to', MS_TEXT_DOMAIN);
        ?>
</th>
						<td class="ms-inv-text"><?php 
        echo $inv_to;
        ?>
</td>
					</tr>
					<tr class="ms-inv-invoice-date">
						<th><?php 
        _e('Invoice date', MS_TEXT_DOMAIN);
        ?>
</th>
						<td class="ms-inv-date"><?php 
        echo $inv_date;
        ?>
</td>
					</tr>
					<?php 
        if (!empty($trial_date)) {
            ?>
						<tr class="ms-inv-trial-end-date">
							<th><?php 
            _e('Trial period', MS_TEXT_DOMAIN);
            ?>
</th>
							<td class="ms-inv-date"><?php 
            echo $trial_date;
            ?>
</td>
						</tr>
					<?php 
        }
        ?>
					<tr class="ms-inv-status space">
						<th><?php 
        _e('Status', MS_TEXT_DOMAIN);
        ?>
</th>
						<td class="ms-inv-text"><?php 
        echo $inv_status;
        ?>
</td>
					</tr>
					<tr class="ms-inv-item-name alt sep">
						<th><?php 
        _e('Name', MS_TEXT_DOMAIN);
        ?>
</th>
						<td class="ms-inv-text"><?php 
        echo $inv_item_name;
        ?>
</td>
					</tr>

					<?php 
        if (!empty($inv_details)) {
            ?>
					<tr class="ms-inv-description alt">
						<th><?php 
            _e('Description', MS_TEXT_DOMAIN);
            ?>
</th>
						<td class="ms-inv-text"><?php 
            echo $inv_details;
            ?>
</td>
					</tr>
					<?php 
        }
        ?>

					<tr class="ms-inv-amount alt space">
						<th><?php 
        _e('Amount', MS_TEXT_DOMAIN);
        ?>
</th>
						<td class="ms-inv-price"><?php 
        echo $inv_amount;
        ?>
</td>
					</tr>

					<?php 
        $sep = 'sep';
        ?>

					<?php 
        if (!empty($inv_discount)) {
            ?>
						<tr class="ms-inv-discount <?php 
            echo esc_attr($sep);
            $sep = '';
            ?>
">
							<th><?php 
            _e('Coupon discount', MS_TEXT_DOMAIN);
            ?>
</th>
							<td class="ms-inv-price"><?php 
            echo $inv_discount;
            ?>
</td>
						</tr>
					<?php 
        }
        ?>

					<?php 
        if (!empty($inv_pro_rate)) {
            ?>
						<tr class="ms-inv-pro-rate <?php 
            echo esc_attr($sep);
            $sep = '';
            ?>
">
							<th><?php 
            _e('Pro rate discount', MS_TEXT_DOMAIN);
            ?>
</th>
							<td class="ms-inv-price"><?php 
            echo $inv_pro_rate;
            ?>
</td>
						</tr>
					<?php 
        }
        ?>

					<?php 
        if (!empty($inv_taxes)) {
            ?>
						<tr class="ms-inv-tax <?php 
            echo esc_attr($sep);
            $sep = '';
            ?>
">
							<th><?php 
            printf(__('Taxes %s', MS_TEXT_DOMAIN), '<small>(' . $invoice->tax_name . ')</small>');
            ?>
</th>
							<td class="ms-inv-price"><?php 
            echo $inv_taxes;
            ?>
</td>
						</tr>
					<?php 
        }
        ?>

					<?php 
        if (!$is_free) {
            ?>
						<tr class="ms-inv-due-date <?php 
            echo esc_attr($sep);
            $sep = '';
            ?>
">
							<th><?php 
            _e('Payment due', MS_TEXT_DOMAIN);
            ?>
</th>
							<td class="ms-inv-date"><?php 
            echo $inv_due_date;
            ?>
</td>
						</tr>
					<?php 
        }
        ?>
					<tr class="ms-inv-total <?php 
        echo esc_attr($sep);
        $sep = '';
        ?>
">
						<th><?php 
        _e('Total', MS_TEXT_DOMAIN);
        ?>
</th>
						<td class="ms-inv-price"><?php 
        echo $inv_total;
        ?>
</td>
					</tr>

					<?php 
        $show_button = lib2()->is_true($this->data['pay_button']);
        if ($invoice->is_paid()) {
            // Invoice is already paid. We don't need a payment
            // button...
            $show_button = false;
        }
        if ($show_button) {
            ?>
						<tr class="ms-inv-sep sep"><td colspan="2"></td></tr>
						<?php 
            do_action('ms_view_shortcode_invoice_purchase_button', $subscription, $invoice);
        }
        ?>
				</table>
			</div>
		</div>
		<?php 
        $html = ob_get_clean();
        $html = apply_filters('ms_compact_code', $html);
        return apply_filters('ms_shortcode_invoice', $html, $this->data);
    }
 /**
  * Add 'Unprotected' node.
  *
  * @since  1.0.0
  *
  */
 private function add_unprotected_node()
 {
     global $wp_admin_bar;
     if (MS_Plugin::is_enabled()) {
         return;
     }
     if (MS_Plugin::is_wizard()) {
         return;
     }
     $link_url = MS_Controller_Plugin::get_admin_url('settings');
     $wp_admin_bar->add_node(apply_filters('ms_controller_adminbar_add_unprotected_node', array('id' => 'ms-unprotected', 'title' => __('Content Protection is disabled', 'membership2'), 'href' => $link_url, 'meta' => array('class' => 'ms-unprotected', 'title' => __('Content of this site is unprotected', 'membership2'), 'tabindex' => '1'))));
 }