GravityView  2.17
The best, easiest way to display Gravity Forms entries on your website.
class-gravityview-field-unsubscribe.php
Go to the documentation of this file.
1 <?php
2 /**
3  * @file class-gravityview-field-unsubscribe.php
4  * @since 2.5
5  * @package GravityView
6  * @subpackage includes\fields
7  */
8 
10 
11  var $name = 'unsubscribe';
12 
13  var $group = 'pricing';
14 
15  var $is_searchable = false;
16 
17  var $contexts = array( 'single', 'multiple' );
18 
19  var $icon = 'dashicons-cart';
20 
21  public function __construct() {
22  $this->label = esc_html__( 'Unsubscribe', 'gk-gravityview' );
23  $this->description = esc_attr__( 'Unsubscribe from a Payment-based entry.', 'gk-gravityview' );
24 
25  $this->add_hooks();
26 
27  parent::__construct();
28  }
29 
30  /**
31  * Hooks called from constructor.
32  *
33  * @return void
34  */
35  public function add_hooks() {
36  add_filter( 'gravityview_entry_default_fields', array( $this, 'filter_gravityview_entry_default_field' ), 10, 3 );
37 
38  add_filter( 'gravityview/field/is_visible', array( $this, 'maybe_not_visible' ), 10, 2 );
39 
40  add_filter( 'gravityview_field_entry_value_unsubscribe', array( $this, 'modify_entry_value_unsubscribe' ), 10, 4 );
41  }
42 
43  /**
44  * Configure the field options.
45  *
46  * Called from the `gravityview_entry_default_fields` filter.
47  *
48  * Remove the logged in, new window and show as link options.
49  * Add the allow unsubscribe for all admins option.
50  *
51  * @param array $field_options The options.
52  * @param string $template_id The template ID.
53  * @param int|string|float $field_id The field ID.
54  * @param string $context The configuration context (edit, single, etc.)
55  * @param string $input_type The input type.
56  * @param int $form_id The form ID.
57  *
58  * @return array The field options.
59  */
60  public function field_options( $field_options, $template_id, $field_id, $context, $input_type, $form_id ) {
61 
62  unset( $field_options['only_loggedin'] );
63 
64  unset( $field_options['new_window'] );
65 
66  unset( $field_options['show_as_link'] );
67 
68  $add_options['unsub_all'] = array(
69  'type' => 'checkbox',
70  'label' => __( 'Allow admins to unsubscribe', 'gk-gravityview' ),
71  'desc' => __( 'Allow users with `gravityforms_edit_entries` to cancel subscriptions', 'gk-gravityview' ),
72  'value' => false,
73  'merge_tags' => false,
74  );
75 
76  return $field_options + $add_options;
77  }
78 
79  /**
80  * Hide the field from the renderer. Perhaps.
81  *
82  * Called from `gravityview/field/is_visible`
83  *
84  * Hide the field for non-logged in users for sure.
85  *
86  * @param bool $visible Consider visible or not.
87  * @param \GV\Field $field The field.
88  *
89  * @return bool Visible or not.
90  */
91  public function maybe_not_visible( $visible, $field ) {
92  if ( $this->name !== $field->ID ) {
93  return $visible;
94  }
95  return is_user_logged_in() ? $visible : false;
96  }
97  /**
98  * Add the unsubsribe to the configuration fields.
99  *
100  * Only if a subscription feed is active for the current form.
101  *
102  * Called from `gravityview_entry_default_fields`
103  *
104  * @param array $entry_default_fields An array of available for configuration
105  * @param array|int $form Form ID or array
106  * @param string $context The configuration context (edit, single, etc.)
107  *
108  * @return array The array of available default fields.
109  */
110  public function filter_gravityview_entry_default_field( $entry_default_fields, $form, $context ) {
111 
112  if ( is_array( $form ) ) {
113  return $entry_default_fields;
114  }
115 
116  $feeds = GFAPI::get_feeds( null, $form );
117 
118  if ( is_wp_error( $feeds ) ) {
119  return $entry_default_fields;
120  }
121 
122  static $subscription_addons;
123 
124  if ( is_null( $subscription_addons ) ) {
125 
126  $registered = GFAddon::get_registered_addons();
127 
128  foreach ( $registered as $addon ) {
129  if ( method_exists( $addon, 'cancel_subscription' ) && is_callable( array( $addon, 'get_instance' ) ) ) {
130  $addon = $addon::get_instance();
131  $subscription_addons[ $addon->get_slug() ] = $addon;
132  }
133  }
134  }
135 
136  if ( empty( $subscription_addons ) ) {
137  return $entry_default_fields;
138  }
139 
140  foreach ( $feeds as $feed ) {
141  if ( isset( $subscription_addons[ $feed['addon_slug'] ] ) && 'subscription' === \GV\Utils::get( $feed, 'meta/transactionType' ) ) {
142  if ( ! isset( $entry_default_fields["{$this->name}"] ) && 'edit' !== $context ) {
143  $entry_default_fields["{$this->name}"] = array(
144  'label' => $this->label,
145  'desc' => $this->description,
146  'type' => $this->name,
147  );
148 
149  break; // Feed found, field added
150  }
151  }
152  }
153 
154  return $entry_default_fields;
155  }
156 
157  /**
158  * Modify the render content.
159  *
160  * Called from `gravityview_field_entry_value_unsubscribe`
161  *
162  * @param string $output The output.
163  * @param array $entry The entry.
164  * @param array $field_settings The field settings.
165  * @param \GV\Field $field The field.
166  *
167  * @return string The content.
168  */
170 
171  if ( ! is_user_logged_in() || ! $entry ) {
172  return $output;
173  }
174 
175  $can_current_user_edit = is_numeric( $entry['created_by'] ) && ( wp_get_current_user()->ID === intval( $entry['created_by'] ) );
176 
177  if ( ! $can_current_user_edit ) {
178  if ( empty( $field_settings['unsub_all'] ) || ! \GVCommon::has_cap( 'gravityforms_edit_entries', $entry['id'] ) ) {
179  return $output;
180  }
181  }
182 
183  if ( ! $status = \GV\Utils::get( $entry, 'payment_status' ) ) {
184  return $output;
185  }
186 
187  // @todo Move to init, or AJAXify, but make sure that the entry is in the View before allowing
188  // @todo Also make sure we check caps if moved from here
189  // @todo Also make sure test_GravityView_Field_Unsubscribe_unsubscribe_permissions is rewritten
190  if ( $entry = $this->maybe_unsubscribe( $entry ) ) {
191  if ( $entry['payment_status'] !== $status ) {
192  // @todo Probably __( 'Unsubscribed', 'gravityview' );
193  return $entry['payment_status'];
194  }
195  }
196 
197  if ( 'active' !== mb_strtolower( $entry['payment_status'] ) ) {
198  return $output;
199  }
200 
201  global $wp;
202  $current_url = add_query_arg( $wp->query_string, '', home_url( $wp->request ) );
203 
204  $link = add_query_arg( 'unsubscribe', wp_create_nonce( 'unsubscribe_' . $entry['id'] ), $current_url );
205  $link = add_query_arg( 'uid', $entry['id'], $link );
206 
207  return sprintf( '<a href="%s">%s</a>', esc_url( $link ), esc_html__( 'Unsubscribe', 'gk-gravityview' ) );
208  }
209 
210  /**
211  * Try to unsubscribe from the entry.
212  *
213  * Called during a POST request. Checks nonce, feeds, entry ID.
214  * Does not check user permissions. This is left as an exercise for the caller.
215  *
216  * Entry View inclusion is checked ad-hoc during the rendering of the field.
217  * User permissions are also checked ad-hoc during the rendering process.
218  *
219  * @param array $entry The entry
220  *
221  * @return array $entry The entry
222  */
223  private function maybe_unsubscribe( $entry ) {
224 
225  if ( ! wp_verify_nonce( \GV\Utils::_REQUEST( 'unsubscribe' ), 'unsubscribe_' . $entry['id'] ) ) {
226  return $entry;
227  }
228 
229  if ( ( ! $uid = \GV\Utils::_REQUEST( 'uid' ) ) || ! is_numeric( $uid ) || ( intval( $uid ) !== intval( $entry['id'] ) ) ) {
230  return $entry;
231  }
232 
233  if ( ! $feeds = gform_get_meta( $uid, 'processed_feeds' ) ) {
234  return $entry;
235  }
236 
237  static $subscription_addons;
238 
239  if ( is_null( $subscription_addons ) ) {
240 
241  $registered = GFAddon::get_registered_addons();
242 
243  foreach ( $registered as $addon ) {
244  if ( method_exists( $addon, 'cancel_subscription' ) ) {
245  $addon = $addon::get_instance();
246  $subscription_addons[ $addon->get_slug() ] = $addon;
247  }
248  }
249  }
250 
251  if ( empty( $subscription_addons ) ) {
252  return $entry;
253  }
254 
255  foreach ( $feeds as $slug => $feed_ids ) {
256 
257  if ( ! isset( $subscription_addons[ $slug ] ) ) {
258  continue;
259  }
260 
261  foreach ( $feed_ids as $feed_id ) {
262 
263  $feed = $subscription_addons[ $slug ]->get_feed( $feed_id );
264 
265  if ( $feed && 'subscription' === \GV\Utils::get( $feed, 'meta/transactionType' ) ) {
266 
267  if ( $subscription_addons[ $slug ]->cancel( $entry, $feed ) ) {
268 
269  $subscription_addons[ $slug ]->cancel_subscription( $entry, $feed );
270 
271  return \GFAPI::get_entry( $entry['id'] );
272  }
273  }
274  }
275  }
276 
277  return $entry;
278  }
279 }
280 
Modify field settings by extending this class.
maybe_not_visible( $visible, $field)
Hide the field from the renderer.
filter_gravityview_entry_default_field( $entry_default_fields, $form, $context)
Add the unsubsribe to the configuration fields.
field_options( $field_options, $template_id, $field_id, $context, $input_type, $form_id)
Configure the field options.
$field_settings['content']
Definition: custom.php:27
if( $add_query_args) $link
if(gravityview() ->plugin->is_GF_25()) $form
add_hooks()
Hooks called from constructor.
scale description p description
if(empty( $created_by)) $form_id
static has_cap( $caps='', $object_id=null, $user_id=null)
Alias of GravityView_Roles_Capabilities::has_cap()
$entry
Definition: notes.php:27
maybe_unsubscribe( $entry)
Try to unsubscribe from the entry.
if(false !==strpos( $value, '00:00')) $field_id
string $field_id ID of the field being displayed
Definition: time.php:22
modify_entry_value_unsubscribe( $output, $entry, $field_settings, $field)
Modify the render content.