/**
  * Save content in wp_option table.
  *
  * Update WP cache and instance singleton.
  *
  * @since  1.0.0
  */
 public function save()
 {
     $this->before_save();
     $option_key = $this->option_key();
     $settings = array();
     $data = MS_Factory::serialize_model($this);
     foreach ($data as $field => $val) {
         $settings[$field] = $this->{$field};
     }
     MS_Factory::set_transient($option_key, $settings, DAY_IN_SECONDS);
     $this->after_save();
     wp_cache_set($option_key, $this, 'MS_Model_Transient');
 }
 /**
  * Save coupon application.
  *
  * Saving the application to keep track of the application in gateway return.
  * Using COUPON_REDEMPTION_TIME to expire coupon application.
  *
  * This is a non-static function, as it saves the current object!
  *
  * @since  1.0.0
  * @param MS_Model_Relationship $subscription The subscription to apply the coupon.
  */
 public function save_application($subscription)
 {
     // Don't save empty invitations.
     if (empty($this->code)) {
         return false;
     }
     $membership = $subscription->get_membership();
     $discount = $this->get_discount_value($subscription);
     $time = apply_filters('ms_addon_coupon_model_save_application_redemption_time', self::COUPON_REDEMPTION_TIME);
     // Grab the user account as we should be logged in by now.
     $user = MS_Model_Member::get_current_member();
     $key = self::get_transient_name($user->id, $membership->id);
     $transient = apply_filters('ms_addon_coupon_model_transient_value', array('id' => $this->id, 'user_id' => $user->id, 'membership_id' => $membership->id, 'discount' => $discount, 'message' => $this->coupon_message));
     MS_Factory::set_transient($key, $transient, $time);
     $this->save();
     do_action('ms_addon_coupon_model_save_application', $subscription, $this);
 }
 /**
  * Search for orphaned relationships and remove them.
  *
  * We write a custom SQL query for this, as solving it with a meta-query
  * structure is very performance intense and requires at least two queries
  * and a loop...
  *
  * For additional performance we will only do this check once every hour.
  *
  * Note: We cannot use the hook 'delete_user' to do this, because in
  * Multisite users are deleted via the Main network admin; however, there
  * we do not have access to the site data; especially if Plugin is not
  * network enabled...
  *
  * @todo Change this to use WP-Cron instead of own implementation...
  *
  * @since  1.0.0
  * @internal
  */
 public static function clean_db()
 {
     $timestamp = absint(MS_Factory::get_transient('ms_member_clean_db'));
     $elapsed = time() - $timestamp;
     if ($elapsed > 3600) {
         // Last check is longer than 1 hour ago. Check again.
         MS_Factory::set_transient('ms_member_clean_db', time(), 3600);
     } else {
         // Last check was within past hour. Do nothing yet...
         return;
     }
     global $wpdb;
     // Find all Relationships that have no post-author.
     $sql = "\n\t\tSELECT p.ID\n\t\tFROM {$wpdb->posts} p\n\t\tWHERE p.post_type=%s\n\t\tAND NOT EXISTS (\n\t\t\tSELECT 1\n\t\t\tFROM {$wpdb->users} u\n\t\t\tWHERE u.ID = p.post_author\n\t\t);\n\t\t";
     $sql = $wpdb->prepare($sql, MS_Model_Relationship::get_post_type());
     // Delete these Relationships!
     $items = $wpdb->get_results($sql);
     foreach ($items as $item) {
         $junk = MS_Factory::load('MS_Model_Relationship', $item->ID);
         $junk->delete();
     }
 }
 /**
  * Returns a secure token to trigger advanced admin actions like db-reset
  * or restoring a snapshot.
  *
  * - Only one token is valid at any given time.
  * - Each token has a timeout of max. 120 seconds.
  * - Each token can be used once only.
  *
  * @since  1.0.0
  * @internal
  *
  * @param  string $action Like a nonce, this is the action to execute.
  * @return array Intended usage: add_query_param( $token, $url )
  */
 public static function get_token($action)
 {
     if (!is_user_logged_in()) {
         return array();
     }
     if (!is_admin()) {
         return array();
     }
     $one_time_key = uniqid();
     MS_Factory::set_transient('ms_one_time_key-' . $action, $one_time_key, 120);
     // Token is valid for 86 seconds because of usage of date('B')
     $plain = $action . '-' . date('B') . ':' . get_current_user_id() . '-' . $one_time_key;
     $token = array('ms_token' => wp_create_nonce($plain));
     return $token;
 }
 /**
  * Creates or updates the coupon specified by the function parameter.
  *
  * @since  1.0.0
  * @internal
  *
  * @param array $coupon_data The object containing all details for Stripe.
  */
 public function create_or_update_coupon($coupon_data)
 {
     $item_id = $coupon_data['id'];
     $all_items = MS_Factory::get_transient('ms_stripeplan_plans');
     $all_items = lib2()->array->get($all_items);
     if (!isset($all_items[$item_id]) || !is_a($all_items[$item_id], 'M2_Stripe_Coupon')) {
         try {
             $item = M2_Stripe_Coupon::retrieve($item_id);
         } catch (Exception $e) {
             // If the coupon does not exist then stripe will throw an Exception.
             $item = false;
         }
         $all_items[$item_id] = $item;
     } else {
         $item = $all_items[$item_id];
     }
     /*
      * Stripe can only update the coupon-name, so we have to delete and
      * recreate the coupon manually.
      */
     if ($item && is_a($item, 'M2_Stripe_Coupon')) {
         $item->delete();
         $all_items[$item_id] = false;
     }
     $item = M2_Stripe_Coupon::create($coupon_data);
     $all_items[$item_id] = $item;
     MS_Factory::set_transient('ms_stripeplan_coupons', $all_items, HOUR_IN_SECONDS);
 }
 /**
  * Creates or updates a single coupon on Stripe.
  *
  * This function is called when the gateway is activated and after a
  * coupon was saved to database.
  *
  * @since  1.0.0
  */
 public function update_stripe_data_coupon($coupon)
 {
     if (!$this->active) {
         return false;
     }
     $this->_api->set_gateway($this);
     $settings = MS_Plugin::instance()->settings;
     $duration = 'once';
     $percent_off = null;
     $amount_off = null;
     if (MS_Addon_Coupon_Model::TYPE_VALUE == $coupon->discount_type) {
         $amount_off = absint($coupon->discount * 100);
     } else {
         $percent_off = $coupon->discount;
     }
     $coupon_data = array('id' => self::get_the_id($coupon->id, 'coupon'), 'duration' => $duration, 'amount_off' => $amount_off, 'percent_off' => $percent_off, 'currency' => $settings->currency);
     // Check if the plan needs to be updated.
     $serialized_data = json_encode($coupon_data);
     $temp_key = substr('ms-stripe-' . $coupon_data['id'], 0, 45);
     $temp_data = MS_Factory::get_transient($temp_key);
     if ($temp_data != $serialized_data) {
         MS_Factory::set_transient($temp_key, $serialized_data, HOUR_IN_SECONDS);
         $this->_api->create_or_update_coupon($coupon_data);
     }
 }