/**
  * Load coupon using coupon code.
  *
  * @since  1.0.0
  *
  * @param string $code The coupon code used to load model
  * @return MS_Addon_Coupon_Model The coupon model, or null if not found.
  */
 public static function load_by_code($code)
 {
     $code = sanitize_text_field($code);
     $args = array('post_type' => self::get_post_type(), 'posts_per_page' => 1, 'post_status' => 'any', 'fields' => 'ids', 'meta_query' => array(array('key' => 'code', 'value' => $code)));
     MS_Factory::select_blog();
     $query = new WP_Query($args);
     $item = $query->posts;
     $coupon_id = 0;
     MS_Factory::revert_blog();
     if (!empty($item[0])) {
         $coupon_id = $item[0];
     }
     $coupon = MS_Factory::load('MS_Addon_Coupon_Model', $coupon_id);
     $coupon->_empty = false;
     return apply_filters('ms_addon_coupon_model_load_by_code', $coupon, $code);
 }
 /**
  * Get Membership2 membership.
  *
  * Create a new membership if membership does not exist.
  *
  * @since  1.0.0
  * @internal
  *
  * @param  string $type The membership to load [protected_content|role]
  * @param  book $create_missing If set to false then missing special
  *           memberships are not created.
  * @return MS_Model_Membership The Membership2.
  */
 public static function _get_system_membership($type, $create_missing = true)
 {
     static $Special_Membership = array();
     $comp_key = $type;
     $membership = false;
     if (!isset($Special_Membership[$comp_key])) {
         $membership = false;
         global $wpdb;
         MS_Factory::select_blog();
         /*
          * We are using a normal SQL query instead of using the WP_Query object
          * here, because the WP_Query object does some strange things sometimes:
          * In some cases new Membership2 memberships were created when a
          * guest accessed the page.
          *
          * By using a manual query we are very certain that only one
          * base-membership exists on the database.
          */
         $sql = "\n\t\t\t\tSELECT ID\n\t\t\t\tFROM {$wpdb->posts} p\n\t\t\t\tINNER JOIN {$wpdb->postmeta} m_type ON m_type.post_id = p.ID\n\t\t\t\tWHERE\n\t\t\t\t\tp.post_type = %s\n\t\t\t\t\tAND m_type.meta_key = %s\n\t\t\t\t\tAND m_type.meta_value = %s\n\t\t\t";
         $values = array(self::get_post_type(), 'type', $type);
         $sql = $wpdb->prepare($sql, $values);
         $item = $wpdb->get_results($sql);
         $base = array_shift($item);
         // Remove the base membership from the results
         MS_Factory::revert_blog();
         if (!empty($base)) {
             $membership = MS_Factory::load('MS_Model_Membership', $base->ID);
         } elseif ($create_missing) {
             $names = self::get_types();
             $description = __('Membership2 Core Membership', 'membership2');
             $membership = MS_Factory::create('MS_Model_Membership');
             $membership->name = $names[$type];
             $membership->title = $names[$type];
             $membership->description = $description;
             $membership->type = $type;
             $membership->save();
         }
         $Special_Membership[$comp_key] = $membership;
     }
     return apply_filters('ms_model_membership_get_system_membership', $Special_Membership[$comp_key], $type);
 }
 /**
  * Creates any missing Membership pages.
  *
  * @since  1.0.0
  * @return array|false Titles of the created pages
  */
 public static function create_missing_pages()
 {
     static $Done = false;
     $res = false;
     if ($Done) {
         return $res;
     }
     $Done = true;
     $user_id = get_current_user_id();
     if (empty($user_id)) {
         return $res;
     }
     $types = self::get_page_types();
     $res = array();
     $site_id = self::get_setting('site_id');
     MS_Factory::select_blog($site_id);
     foreach ($types as $type => $title) {
         $page_id = self::get_setting($type);
         $status = get_post_status($page_id);
         if (!$status || 'trash' == $status) {
             // Page does not exist or was deleted. Create new page.
             $page_id = 0;
         } elseif ('publish' != $status) {
             // The page exists but is not published. Publish now.
             wp_publish_post($page_id);
         }
         // If the post_id does not exist then create a new page
         if (empty($page_id)) {
             $data = array('post_title' => $title, 'post_name' => $type, 'post_content' => self::get_default_content($type), 'post_type' => 'page', 'post_status' => 'publish', 'post_author' => $user_id);
             $new_id = wp_insert_post($data);
             /**
              * Filter the new page_id
              *
              * @since  1.0.0
              */
             $new_id = apply_filters('ms_model_pages_create_missing_page', $new_id, $type, $data);
             if (is_numeric($new_id)) {
                 self::set_setting($type, $new_id);
                 $res[$new_id] = $title;
                 /**
                  * Trigger action to allow modifications to the page
                  *
                  * @since  1.0.0
                  */
                 do_action('ms_model_pages_create_wp_page', $new_id);
             }
         }
     }
     MS_Factory::revert_blog();
     return apply_filters('ms_model_pages_create_missing_page', $res);
 }
    /**
     * Display the full settings form, used either by first membership
     * "completed" popup and also by the general settings tab.
     *
     * @since  1.0.0
     * @return string HTML code
     */
    public function html_full_form()
    {
        $fields = $this->prepare_fields();
        ob_start();
        ?>
		<div class="ms-setup-form">
			<?php 
        if (!MS_Plugin::is_network_wide()) {
            ?>
			<div class="ms-setup-nav">
				<div class="ms-title">
					<i class="ms-icon dashicons dashicons-menu"></i>
					<?php 
            _e('Please select pages you want to appear in your Navigation', MS_TEXT_DOMAIN);
            ?>
				</div>
				<div class="ms-description">
					<?php 
            printf(__('You can always change those later by going to %1$s in your admin sidebar.', MS_TEXT_DOMAIN), sprintf('<a href="%1$s" target="_blank">%2$s</a>', admin_url('nav-menus.php'), __('Appearance') . ' &raquo; ' . __('Menus')));
            ?>
				</div>
				<?php 
            echo $this->show_menu_controls();
            ?>
			</div>
			<?php 
        }
        ?>
			<div class="ms-setup-pages">
				<div class="ms-title">
					<i class="ms-icon dashicons dashicons-admin-page"></i>
					<?php 
        _e('Membership 2 Pages', MS_TEXT_DOMAIN);
        ?>
				</div>
				<div class="ms-description">
					<?php 
        _e('Set Up Membership 2 Pages that will be displayed on your website.', MS_TEXT_DOMAIN);
        ?>
				</div>
				<?php 
        if (is_array($fields['pages'])) {
            $page_types = array_keys($fields['pages']);
            $page_types_menu = array('memberships', 'register', 'account');
            $page_types_rest = array_diff($page_types, $page_types_menu);
            $groups = array('in-menu' => $page_types_menu, 'no-menu' => $page_types_rest);
            $pages_site_id = MS_Model_Pages::get_site_info('id');
            MS_Factory::select_blog($pages_site_id);
            foreach ($groups as $group_key => $group_items) {
                printf('<div class="ms-pages-group %1$s">', esc_attr($group_key));
                foreach ($group_items as $key) {
                    $field = $fields['pages'][$key];
                    ?>
							<div class="ms-settings-page-wrapper">
								<?php 
                    MS_Helper_Html::html_element($field);
                    ?>
								<div class="ms-action">
									<?php 
                    MS_Helper_Html::html_link(array('id' => 'url_page_' . $field['value'], 'url' => '', 'value' => __('View Page', MS_TEXT_DOMAIN), 'target' => '_blank', 'data_ms' => array('base' => get_home_url($pages_site_id, 'index.php?page_id='))));
                    ?>
									<span> | </span>
									<?php 
                    MS_Helper_Html::html_link(array('id' => 'edit_url_page_' . $field['value'], 'url' => '', 'value' => __('Edit Page', MS_TEXT_DOMAIN), 'target' => '_blank', 'data_ms' => array('base' => get_admin_url($pages_site_id, 'post.php?action=edit&post='))));
                    ?>
								</div>
							</div>
							<?php 
                }
                echo '</div>';
            }
        } else {
            echo $fields['pages'];
        }
        MS_Factory::revert_blog();
        ?>
			</div>
		</div>
		<?php 
        $html = ob_get_clean();
        return apply_filters('ms_view_settings_page_setup_to_html', $html);
    }
 /**
  * Get transaction log items.
  *
  * @since  1.0.1.0
  *
  * @param  $args The query post args.
  *         @see @link http://codex.wordpress.org/Class_Reference/WP_Query
  * @return array List of transaction log items.
  */
 public static function get_items($args = null)
 {
     MS_Factory::select_blog();
     $args = self::get_query_args($args);
     $query = new WP_Query($args);
     MS_Factory::revert_blog();
     $items = array();
     foreach ($query->posts as $post_id) {
         $items[] = MS_Factory::load('MS_Model_Transactionlog', $post_id);
     }
     return apply_filters('ms_model_transactionlog_get_items', $items, $args);
 }
 /**
  * Retrieve membership relationship.
  *
  * @since  1.0.0
  * @internal
  *
  * @param int $user_id The user id
  * @return int $membership_id The membership id.
  */
 public static function get_subscription($user_id, $membership_id)
 {
     $args = apply_filters('ms_model_relationship_get_subscription_args', self::get_query_args(array('user_id' => $user_id, 'membership_id' => $membership_id, 'status' => 'all')));
     MS_Factory::select_blog();
     $query = new WP_Query($args);
     $post = $query->posts;
     MS_Factory::revert_blog();
     $subscription = null;
     if (!empty($post[0])) {
         $subscription = MS_Factory::load('MS_Model_Relationship', $post[0]);
     }
     return apply_filters('ms_model_relationship_get_subscription', $subscription, $args);
 }
 /**
  * Get transaction log items.
  *
  * @since  1.0.1.0
  *
  * @param  $args The query post args.
  *         @see @link http://codex.wordpress.org/Class_Reference/WP_Query
  * @return array List of transaction log items.
  */
 public static function get_items($args = null)
 {
     MS_Factory::select_blog();
     $args = self::get_query_args($args);
     $query = new WP_Query($args);
     MS_Factory::revert_blog();
     $items = array();
     foreach ($query->posts as $post_id) {
         if (!get_post_meta($post_id, 'method', true) && !get_post_meta($post_id, 'method', true)) {
             // The log entry is incomplete. Do not load it.
             continue;
         }
         $items[] = MS_Factory::load('MS_Model_Transactionlog', $post_id);
     }
     return apply_filters('ms_model_transactionlog_get_items', $items, $args);
 }
 /**
  * Returns the membership-ID that matches the specified Membership name or
  * slug.
  *
  * If multiple memberships have the same name then the one with the lowest
  * ID (= the oldest) will be returned.
  *
  * Name or slug are case-IN-sensitive ('slug' and 'SLUG' are identical)
  * Wildcards are not allowed, the string must match exactly.
  *
  * @since  1.0.1.2
  * @param  string $name_or_slug The Membership name or slug to search.
  * @return int|false The membership ID or false.
  */
 public function get_membership_id($name_or_slug)
 {
     global $wpdb;
     $res = false;
     $sql = "\n\t\tSELECT ID\n\t\tFROM {$wpdb->posts} p\n\t\tINNER JOIN {$wpdb->postmeta} m ON m.post_id = p.ID AND m.meta_key = %s\n\t\tWHERE\n\t\t\tp.post_type = %s\n\t\t\tAND ( m.meta_value = %s OR p.post_name = %s )\n\t\tORDER BY ID\n\t\t;";
     MS_Factory::select_blog();
     $sql = $wpdb->prepare($sql, 'name', MS_Model_Membership::get_post_type(), $name_or_slug, $name_or_slug);
     $ids = $wpdb->get_col($sql);
     MS_Factory::revert_blog();
     if (is_array($ids) && count($ids)) {
         $res = reset($ids);
     }
     return $res;
 }
 /**
  * Get specific invoice.
  *
  * Get invoice of a user and membership.
  *
  * @since  1.0.0
  *
  * @param int $subscription_id The membership relationship id.
  * @param int $invoice_number Optional. The invoice number. Get the current number if null.
  * @param string $status Optional. The invoice status.
  * @return MS_Model_Invoice The found invoice or null if not found.
  */
 public static function get_invoice($subscription_id, $invoice_number = null, $status = null)
 {
     $args = array('post_type' => self::get_post_type(), 'post_status' => 'any', 'fields' => 'ids', 'order' => 'DESC');
     $args['meta_query']['ms_relationship_id'] = array('key' => 'ms_relationship_id', 'value' => $subscription_id);
     if (!empty($status)) {
         $args['meta_query']['status'] = array('key' => 'status', 'value' => $status);
     }
     if (!empty($invoice_number)) {
         $args['meta_query']['invoice_number'] = array('key' => 'invoice_number', 'value' => $invoice_number);
     }
     MS_Factory::select_blog();
     $args = apply_filters('ms_model_invoice_get_invoice_args', $args);
     $query = new WP_Query($args);
     $item = $query->posts;
     MS_Factory::revert_blog();
     $invoice = null;
     if (!empty($item[0])) {
         $invoice = MS_Factory::load('MS_Model_Invoice', $item[0]);
     }
     return apply_filters('ms_model_invoice_get_invoice', $invoice, $subscription_id, $invoice_number, $status);
 }
 /**
  * Get communication type object.
  *
  * Load from DB if exists, create a new one if not.
  *
  * @since  1.0.0
  *
  * @param  string $type The type of the communication.
  * @param  MS_Model_Membership $membership Optional. If defined then we try
  *         to load the overridden template for that membership with fallback
  *         to the default template.
  * @param  bool $no_fallback Optional. Default value is false.
  *         True: Always return a communication for specified membership_id
  *         False: Fallback to default message if membership_id does not
  *         override the requested message.
  * @return MS_Model_Communication The communication object.
  */
 public static function get_communication($type, $membership = null, $no_fallback = false)
 {
     $comm = null;
     $key = 'all';
     $comm_id = 0;
     /*
      * If the Membership specific communication is not defined or it
      * is configured to use the default communication then fetch the
      * default communication object!
      */
     $can_fallback = $membership && !$no_fallback;
     if (self::is_valid_communication_type($type)) {
         $membership_id = 0;
         if ($membership) {
             if ($membership instanceof MS_Model_Membership) {
                 $membership_id = $membership->id;
             } elseif (is_scalar($membership)) {
                 $membership_id = $membership;
             }
             if ($membership_id) {
                 $key = $membership_id;
             }
         }
         if (empty(self::$Communication_IDs[$key])) {
             self::$Communication_IDs[$key] = array();
         }
         if (!empty(self::$Communication_IDs[$key][$type])) {
             $comm_id = self::$Communication_IDs[$key][$type];
         } else {
             $args = array('post_type' => self::get_post_type(), 'post_status' => 'any', 'fields' => 'ids', 'posts_per_page' => 1, 'post_parent' => $membership_id, 'meta_query' => array(array('key' => 'type', 'value' => $type, 'compare' => '=')));
             $args = apply_filters('ms_model_communication_get_communications_args', $args);
             MS_Factory::select_blog();
             $query = new WP_Query($args);
             $items = $query->posts;
             MS_Factory::revert_blog();
             if (1 == count($items)) {
                 $comm_id = $items[0];
             }
         }
         $comm_classes = self::get_communication_type_classes();
         $comm_class = $comm_classes[$type];
         if ($comm_id) {
             $comm = MS_Factory::load($comm_class, $comm_id);
         } elseif (!$can_fallback) {
             $comm = MS_Factory::create($comm_class);
             $comm->reset_to_default();
             $comm->membership_id = $membership_id;
         }
         if ($comm) {
             self::$Communication_IDs[$comm->membership_id][$type] = $comm->id;
         }
         // If no template found or defined then fallback to default template.
         $should_fallback = !$comm || !$comm->override;
         if ($can_fallback && $should_fallback) {
             $comm = self::get_communication($type, null);
         }
     }
     return apply_filters('ms_model_communication_get_communication_' . $type, $comm, $membership, $no_fallback);
 }
    /**
     * Display the full settings form, used either by first membership
     * "completed" popup and also by the general settings tab.
     *
     * @since  1.0.0
     * @return string HTML code
     */
    public function html_full_form()
    {
        $fields = $this->prepare_fields();
        ob_start();
        ?>
		<div class="ms-setup-form">
			<?php 
        if (!MS_Plugin::is_network_wide()) {
            ?>
			<div class="ms-setup-nav">
				<div class="ms-title">
					<i class="ms-icon dashicons dashicons-menu"></i>
					<?php 
            _e('Please select pages you want to appear in your Navigation', MS_TEXT_DOMAIN);
            ?>
				</div>
				<div class="ms-description">
					<?php 
            printf(__('You can always change those later by going to %1$s in your admin sidebar.', MS_TEXT_DOMAIN), sprintf('<a href="%1$s" target="_blank">%2$s</a>', admin_url('nav-menus.php'), __('Appearance') . ' &raquo; ' . __('Menus')));
            ?>
				</div>
				<?php 
            echo '' . $this->show_menu_controls();
            ?>
			</div>
			<?php 
        } else {
            ?>
			<div class="ms-setup-site">
				<div class="ms-title">
					<i class="ms-icon dashicons dashicons-admin-network"></i>
					<?php 
            _e('Select the Site that hosts Membership 2 Pages', MS_TEXT_DOMAIN);
            ?>
				</div>
				<div class="ms-description">
					<?php 
            _e('When you change the site new Membership 2 Pages are created on the selected site. You can customize or replace these pages at any time.', MS_TEXT_DOMAIN);
            ?>
				</div>
				<?php 
            $site_options = MS_Helper_Settings::get_blogs();
            $site_fields = array(array('type' => MS_Helper_Html::INPUT_TYPE_SELECT, 'id' => 'network_site', 'title' => __('Select the site that hosts the Membership 2 Pages', MS_TEXT_DOMAIN), 'value' => MS_Model_Pages::get_site_info('id'), 'field_options' => $site_options, 'class' => 'ms-site-options'), array('type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'name' => 'action', 'value' => 'network_site'), array('type' => MS_Helper_Html::INPUT_TYPE_HIDDEN, 'name' => '_wpnonce', 'value' => wp_create_nonce('network_site')), array('type' => MS_Helper_Html::INPUT_TYPE_SUBMIT, 'value' => __('Save', MS_TEXT_DOMAIN)), array('type' => MS_Helper_Html::INPUT_TYPE_BUTTON, 'class' => 'ms-setup-pages-cancel', 'value' => __('Cancel', MS_TEXT_DOMAIN)));
            ?>
				<div class="ms-setup-pages-site">
					<div class="ms-setup-pages-site-info"><?php 
            printf(__('Membership pages are located on site %s', MS_TEXT_DOMAIN), '<strong>' . MS_Model_Pages::get_site_info('title') . '</strong>');
            ?>
					<a href="#change-site" class="ms-setup-pages-change-site"><?php 
            _e('Change site...', MS_TEXT_DOMAIN);
            ?>
</a></div>
					<div class="ms-setup-pages-site-form cf" style="display:none;">
						<?php 
            foreach ($site_fields as $field) {
                MS_Helper_Html::html_element($field);
            }
            ?>
					</div>
				</div>
			</div>
			<?php 
        }
        ?>
			<div class="ms-setup-pages">
				<div class="ms-title">
					<i class="ms-icon dashicons dashicons-admin-page"></i>
					<?php 
        _e('Membership 2 Pages', MS_TEXT_DOMAIN);
        ?>
				</div>
				<div class="ms-description">
					<?php 
        _e('Set Up Membership 2 Pages that will be displayed on your website.', MS_TEXT_DOMAIN);
        ?>
				</div>
				<?php 
        if (is_array($fields['pages'])) {
            $page_types = array_keys($fields['pages']);
            $page_types_menu = array('memberships', 'register', 'account');
            $page_types_rest = array_diff($page_types, $page_types_menu);
            $groups = array('in-menu' => $page_types_menu, 'no-menu' => $page_types_rest);
            $pages_site_id = MS_Model_Pages::get_site_info('id');
            MS_Factory::select_blog($pages_site_id);
            foreach ($groups as $group_key => $group_items) {
                printf('<div class="ms-pages-group %1$s">', esc_attr($group_key));
                foreach ($group_items as $key) {
                    $field = $fields['pages'][$key];
                    ?>
							<div class="ms-settings-page-wrapper">
								<?php 
                    MS_Helper_Html::html_element($field);
                    ?>
								<div class="ms-action">
									<?php 
                    MS_Helper_Html::html_link(array('id' => 'url_page_' . $field['value'], 'url' => '', 'value' => __('View Page', MS_TEXT_DOMAIN), 'target' => '_blank', 'data_ms' => array('base' => get_home_url($pages_site_id, 'index.php?page_id='))));
                    ?>
									<span> | </span>
									<?php 
                    MS_Helper_Html::html_link(array('id' => 'edit_url_page_' . $field['value'], 'url' => '', 'value' => __('Edit Page', MS_TEXT_DOMAIN), 'target' => '_blank', 'data_ms' => array('base' => get_admin_url($pages_site_id, 'post.php?action=edit&post='))));
                    ?>
								</div>
							</div>
							<?php 
                }
                echo '</div>';
            }
        } else {
            echo $fields['pages'];
        }
        MS_Factory::revert_blog();
        ?>
			</div>
		</div>
		<?php 
        $html = ob_get_clean();
        return apply_filters('ms_view_settings_page_setup_to_html', $html);
    }
 /**
  * Delete object lock.
  *
  * @since  1.0.0
  */
 public function delete_object_lock()
 {
     MS_Factory::select_blog();
     if ($this->is_valid()) {
         update_post_meta($this->id, '_ms_edit_lock', '');
     }
     do_action('MS_Model_CustomPostType_delete_object_lock', $this);
     MS_Factory::revert_blog();
 }
 /**
  * Get invitations.
  *
  * @since  1.0.0
  *
  * @param $args The query post args
  *        @see @link http://codex.wordpress.org/Class_Reference/WP_Query
  * @return MS_Model_Invitation[] The found invitation objects.
  */
 public static function get_invitations($args = null)
 {
     $defaults = array('post_type' => self::get_post_type(), 'posts_per_page' => 10, 'post_status' => 'any', 'order' => 'DESC');
     $args = wp_parse_args($args, $defaults);
     MS_Factory::select_blog();
     $query = new WP_Query($args);
     $items = $query->posts;
     MS_Factory::revert_blog();
     $invitations = array();
     foreach ($items as $item) {
         $invitations[] = MS_Factory::load('MS_Addon_Invitation_Model', $item->ID);
     }
     return apply_filters('ms_addon_invitation_model_get_invitations', $invitations, $args);
 }
 /**
  * Get events.
  *
  * @since  1.0.0
  *
  * @param $args The query post args
  *				@see @link http://codex.wordpress.org/Class_Reference/WP_Query
  * @return MS_Model_Event[] The events found.
  */
 public static function get_events($args = null)
 {
     MS_Factory::select_blog();
     $args = self::get_query_args($args);
     $query = new WP_Query($args);
     $items = $query->posts;
     $events = array();
     MS_Factory::revert_blog();
     foreach ($items as $item) {
         $events[] = MS_Factory::load('MS_Model_Event', $item);
     }
     return apply_filters('ms_model_event_get_events', $events, $args);
 }