Completed
Pull Request — master (#174)
by Stephanie
02:25
created

FrmReviews   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 219
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
dl 0
loc 219
rs 9.76
c 0
b 0
f 0
wmc 33
lcom 1
cbo 3

9 Methods

Rating   Name   Duplication   Size   Complexity  
B review_request() 0 22 7
A set_review_status() 0 18 2
B review() 0 47 5
B add_to_inbox() 0 34 6
A has_later_request() 0 3 2
A inbox_keys() 0 7 1
A set_inbox_dismissed() 0 6 2
A set_inbox_read() 0 6 2
B dismiss_review() 0 25 6
1
<?php
2
3
class FrmReviews {
4
5
	private $option_name = 'frm_reviewed';
6
7
	private $review_status = array();
8
9
	private $inbox_key = 'review';
10
11
	/**
12
	 * Add admin notices as needed for reviews
13
	 *
14
	 * @since 3.04.03
15
	 */
16
	public function review_request() {
17
18
		// Only show the review request to high-level users on Formidable pages
19
		if ( ! current_user_can( 'frm_change_settings' ) || ! FrmAppHelper::is_formidable_admin() ) {
20
			return;
21
		}
22
23
		// Verify that we can do a check for reviews
24
		$this->set_review_status();
25
26
		// Check if it has been dismissed or if we can ask later
27
		$dismissed = $this->review_status['dismissed'];
28
		if ( $dismissed === 'later' && $this->review_status['asked'] < 3 ) {
29
			$dismissed = false;
30
		}
31
32
		$week_ago = ( $this->review_status['time'] + WEEK_IN_SECONDS ) <= time();
33
34
		if ( empty( $dismissed ) && $week_ago ) {
35
			$this->review();
36
		}
37
	}
38
39
	/**
40
	 * When was the review request last dismissed?
41
	 *
42
	 * @since 3.04.03
43
	 */
44
	private function set_review_status() {
45
		$user_id = get_current_user_id();
46
		$review  = get_user_meta( $user_id, $this->option_name, true );
47
		$default = array(
48
			'time'      => time(),
49
			'dismissed' => false,
50
			'asked'     => 0,
51
		);
52
53
		if ( empty( $review ) ) {
54
			// Set the review request to show in a week
55
			update_user_meta( $user_id, $this->option_name, $default );
56
		}
57
58
		$review              = array_merge( $default, (array) $review );
59
		$review['asked']     = (int) $review['asked'];
60
		$this->review_status = $review;
61
	}
62
63
	/**
64
	 * Maybe show review request
65
	 *
66
	 * @since 3.04.03
67
	 */
68
	private function review() {
69
70
		// show the review request 3 times, depending on the number of entries
71
		$show_intervals = array( 50, 200, 500 );
72
		$asked          = $this->review_status['asked'];
73
74
		if ( ! isset( $show_intervals[ $asked ] ) ) {
75
			return;
76
		}
77
78
		$entries = FrmEntry::getRecordCount();
79
		$count   = $show_intervals[ $asked ];
80
		$user    = wp_get_current_user();
81
82
		// Only show review request if the site has collected enough entries
83
		if ( $entries < $count ) {
84
			// check the entry count again in a week
85
			$this->review_status['time'] = time();
86
			update_user_meta( $user->ID, $this->option_name, $this->review_status );
87
88
			return;
89
		}
90
91
		if ( $entries <= 100 ) {
92
			// round to the nearest 10
93
			$entries = floor( $entries / 10 ) * 10;
94
		} else {
95
			// round to the nearest 50
96
			$entries = floor( $entries / 50 ) * 50;
97
		}
98
		$name = $user->first_name;
99
		if ( ! empty( $name ) ) {
100
			$name = ' ' . $name;
101
		}
102
103
		$title = sprintf(
104
			/* translators: %s: User name, %2$d: number of entries */
105
			esc_html__( 'Congratulations%1$s! You have collected %2$d form submissions.', 'formidable' ),
106
			esc_html( $name ),
107
			absint( $entries )
108
		);
109
110
		$this->add_to_inbox( $title, $name, $asked );
111
112
		// We have a candidate! Output a review message.
113
		include( FrmAppHelper::plugin_path() . '/classes/views/shared/review.php' );
114
	}
115
116
	private function add_to_inbox( $title, $name, $asked ) {
117
		$message = new FrmInbox();
118
		$requests = $message->get_messages();
119
		$key      = $this->inbox_key . ( $asked ? $asked : '' );
120
121
		if ( isset( $requests[ $key ] ) ) {
122
			return;
123
		}
124
125
		// Remove previous requests.
126
		if ( $asked > 0 ) {
127
			$message->remove( $this->inbox_key );
128
		}
129
		if ( $asked > 1 ) {
130
			$message->remove( $this->inbox_key . '1' );
131
		}
132
133
		if ( $this->has_later_request( $requests, $asked ) ) {
134
			// Don't add a request that has already been passed.
135
			return;
136
		}
137
138
		$message->add_message(
139
			array(
140
				'key'     => $key,
141
				'message' => __( 'If you are enjoying Formidable, could you do me a BIG favor and give us a review to help me grow my little business and boost our motivation?', 'formidable' ) . '<br/>' .
142
					'- Steph Wells<br/>' .
143
					'<span>' . esc_html__( 'Co-Founder and CTO of Formidable Forms', 'formidable' ) . '<span>',
144
				'subject' => str_replace( $name, '', $title ),
145
				'cta'     => '<a href="https://wordpress.org/support/plugin/formidable/reviews/?filter=5#new-post" class="frm-dismiss-review-notice frm-review-out button-secondary frm-button-secondary" data-link="yes" target="_blank" rel="noopener noreferrer">' .
146
					esc_html__( 'Ok, you deserve it', 'formidable' ) . '</a>',
147
			)
148
		);
149
	}
150
151
	/**
152
	 * If there are already later requests, don't add it to the inbox again.
153
	 *
154
	 * @since 4.05.02
155
	 */
156
	private function has_later_request( $requests, $asked ) {
157
		return isset( $requests[ $this->inbox_key . ( $asked + 1 ) ] ) || isset( $requests[ $this->inbox_key . ( $asked + 2 ) ] );
158
	}
159
160
	/**
161
	 * @since 4.05.02
162
	 */
163
	private function inbox_keys() {
164
		return array(
165
			$this->inbox_key,
166
			$this->inbox_key . '1',
167
			$this->inbox_key . '2',
168
		);
169
	}
170
171
	/**
172
	 * @since 4.05.01
173
	 */
174
	private function set_inbox_dismissed() {
175
		$message = new FrmInbox();
176
		foreach ( $this->inbox_keys() as $key ) {
177
			$message->dismiss( $key );
178
		}
179
	}
180
181
	/**
182
	 * @since 4.05.01
183
	 */
184
	private function set_inbox_read() {
185
		$message = new FrmInbox();
186
		foreach ( $this->inbox_keys() as $key ) {
187
			$message->mark_read( $key );
188
		}
189
	}
190
191
	/**
192
	 * Save the request to hide the review
193
	 *
194
	 * @since 3.04.03
195
	 */
196
	public function dismiss_review() {
197
		FrmAppHelper::permission_check( 'frm_change_settings' );
198
		check_ajax_referer( 'frm_ajax', 'nonce' );
199
200
		$user_id = get_current_user_id();
201
		$review  = get_user_meta( $user_id, $this->option_name, true );
202
		if ( empty( $review ) ) {
203
			$review = array();
204
		}
205
206
		if ( isset( $review['dismissed'] ) && $review['dismissed'] === 'done' ) {
207
			// if feedback was submitted, don't update it again when the review is dismissed
208
			$this->set_inbox_dismissed();
209
			wp_die();
210
		}
211
212
		$dismissed           = FrmAppHelper::get_post_param( 'link', 'no', 'sanitize_text_field' );
213
		$review['time']      = time();
214
		$review['dismissed'] = $dismissed === 'done' ? true : 'later';
215
		$review['asked']     = isset( $review['asked'] ) ? $review['asked'] + 1 : 1;
216
217
		update_user_meta( $user_id, $this->option_name, $review );
218
		$this->set_inbox_read();
219
		wp_die();
220
	}
221
}
222