PluginProbe ʕ •ᴥ•ʔ
WP Popular Posts / 5.4.1
WP Popular Posts v5.4.1
4.0.8 4.0.9 4.1.0 4.1.1 4.1.2 4.2.0 4.2.1 4.2.2 5.0.0 5.0.1 5.0.2 5.1.0 5.2.0 5.2.1 5.2.2 5.2.3 5.2.4 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 6.0.0 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.1.0 6.1.1 6.1.2 6.1.3 6.1.4 6.2.0 6.2.1 6.3.0 6.3.1 6.3.2 6.3.3 6.3.4 6.4.0 6.4.1 6.4.2 7.0.0 7.0.1 7.1.0 7.2.0 7.3.0 7.3.1 7.3.2 7.3.3 7.3.4 7.3.5 7.3.6 7.3.7 7.3.8 7.4.0 trunk 2.3.7 3.0.0 3.0.1 3.0.2 3.0.3 3.1.0 3.1.1 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 4.0.0 4.0.1 4.0.10 4.0.11 4.0.12 4.0.13 4.0.2 4.0.3 4.0.5 4.0.6
wordpress-popular-posts / src / Rest / ViewLoggerEndpoint.php
wordpress-popular-posts / src / Rest Last commit date
Controller.php 4 years ago Endpoint.php 4 years ago PostsEndpoint.php 4 years ago TaxonomiesEndpoint.php 4 years ago ThemesEndpoint.php 4 years ago ThumbnailsEndpoint.php 4 years ago ViewLoggerEndpoint.php 4 years ago WidgetEndpoint.php 4 years ago
ViewLoggerEndpoint.php
243 lines
1 <?php
2 namespace WordPressPopularPosts\Rest;
3
4 use WordPressPopularPosts\Helper;
5
6 class ViewLoggerEndpoint extends Endpoint {
7
8 /**
9 * Registers the endpoint(s).
10 *
11 * @since 5.3.0
12 */
13 public function register()
14 {
15 $version = '1';
16 $namespace = 'wordpress-popular-posts/v' . $version;
17
18 register_rest_route($namespace, '/popular-posts', [
19 [
20 'methods' => \WP_REST_Server::CREATABLE,
21 'callback' => [$this, 'update_views_count'],
22 'permission_callback' => '__return_true',
23 'args' => $this->get_tracking_params(),
24 ]
25 ]);
26 }
27
28 /**
29 * Updates the views count of a post / page.
30 *
31 * @since 4.1.0
32 *
33 * @param \WP_REST_Request $request Full details about the request.
34 * @return string
35 */
36 public function update_views_count($request){
37 global $wpdb;
38
39 $post_ID = $request->get_param('wpp_id');
40 $sampling = $request->get_param('sampling');
41 $sampling_rate = $request->get_param('sampling_rate');
42
43 $table = $wpdb->prefix . "popularposts";
44 $wpdb->show_errors();
45
46 // Get translated object ID
47 $post_ID = $this->translate->get_object_id(
48 $post_ID,
49 get_post_type($post_ID),
50 true,
51 $this->translate->get_default_language()
52 );
53
54 $now = Helper::now();
55 $curdate = Helper::curdate();
56 $views = ($sampling)
57 ? $sampling_rate
58 : 1;
59
60 // Allow WP themers / coders perform an action
61 // before updating views count
62 if ( has_action('wpp_pre_update_views') )
63 do_action('wpp_pre_update_views', $post_ID, $views);
64
65 $result1 = $result2 = false;
66
67 $exec_time = 0;
68 $start = Helper::microtime_float();
69
70 // Store views data in persistent object cache
71 if (
72 wp_using_ext_object_cache()
73 && defined('WPP_CACHE_VIEWS')
74 && WPP_CACHE_VIEWS
75 ) {
76
77 $now_datetime = new \DateTime($now, new \DateTimeZone(Helper::get_timezone()));
78 $timestamp = $now_datetime->getTimestamp();
79 $date_time = $now_datetime->format('Y-m-d H:i');
80 $date_time_with_seconds = $now_datetime->format('Y-m-d H:i:s');
81 $high_accuracy = false;
82
83 $key = $high_accuracy ? $timestamp : $date_time;
84
85 if ( ! $wpp_cache = wp_cache_get('_wpp_cache', 'transient') ) {
86 $wpp_cache = [
87 'last_updated' => $date_time_with_seconds,
88 'data' => [
89 $post_ID => [
90 $key => 1
91 ]
92 ]
93 ];
94 } else {
95 if ( ! isset($wpp_cache['data'][$post_ID][$key]) ) {
96 $wpp_cache['data'][$post_ID][$key] = 1;
97 } else {
98 $wpp_cache['data'][$post_ID][$key] += 1;
99 }
100 }
101
102 // Update cache
103 wp_cache_set('_wpp_cache', $wpp_cache, 'transient', 0);
104
105 // How long has it been since the last time we saved to the database?
106 $last_update = $now_datetime->diff(new \DateTime($wpp_cache['last_updated'], new \DateTimeZone(Helper::get_timezone())));
107 $diff_in_minutes = $last_update->days * 24 * 60;
108 $diff_in_minutes += $last_update->h * 60;
109 $diff_in_minutes += $last_update->i;
110
111 // It's been more than 2 minutes, save everything to DB
112 if ( $diff_in_minutes > 2 ) {
113
114 $query_data = "INSERT INTO {$table}data (`postid`,`day`,`last_viewed`,`pageviews`) VALUES ";
115 $query_summary = "INSERT INTO {$table}summary (`postid`,`pageviews`,`view_date`,`view_datetime`) VALUES ";
116
117 foreach( $wpp_cache['data'] as $pid => $data ) {
118 $views_count = 0;
119
120 foreach( $data as $ts => $cached_views ){
121 $views_count += $cached_views;
122 $ts = Helper::is_timestamp($ts) ? $ts : strtotime($ts);
123
124 $query_summary .= $wpdb->prepare("(%d,%d,%s,%s),", [
125 $pid,
126 $cached_views,
127 date("Y-m-d", $ts),
128 date("Y-m-d H:i:s", $ts)
129 ]);
130 }
131
132 $query_data .= $wpdb->prepare( "(%d,%s,%s,%s),", [
133 $pid,
134 $date_time_with_seconds,
135 $date_time_with_seconds,
136 $views_count
137 ]);
138 }
139
140 $query_data = rtrim($query_data, ",") . " ON DUPLICATE KEY UPDATE pageviews=pageviews+VALUES(pageviews),last_viewed=VALUES(last_viewed);";
141 $query_summary = rtrim($query_summary, ",") . ";";
142
143 // Clear cache
144 $wpp_cache['last_updated'] = $date_time_with_seconds;
145 $wpp_cache['data'] = [];
146 wp_cache_set('_wpp_cache', $wpp_cache, 'transient', 0);
147
148 // Save
149 $result1 = $wpdb->query($query_data);
150 $result2 = $wpdb->query($query_summary);
151 }
152 else {
153 $result1 = $result2 = true;
154 }
155 } // Live update to the DB
156 else {
157 // Update all-time table
158 $result1 = $wpdb->query($wpdb->prepare(
159 "INSERT INTO {$table}data
160 (postid, day, last_viewed, pageviews) VALUES (%d, %s, %s, %d)
161 ON DUPLICATE KEY UPDATE pageviews = pageviews + %d, last_viewed = %s;",
162 $post_ID,
163 $now,
164 $now,
165 $views,
166 $views,
167 $now
168 ));
169
170 // Update range (summary) table
171 $result2 = $wpdb->query($wpdb->prepare(
172 "INSERT INTO {$table}summary
173 (postid, pageviews, view_date, view_datetime) VALUES (%d, %d, %s, %s)
174 ON DUPLICATE KEY UPDATE pageviews = pageviews + %d, view_datetime = %s;",
175 $post_ID,
176 $views,
177 $curdate,
178 $now,
179 $views,
180 $now
181 ));
182 }
183
184 $end = Helper::microtime_float();
185 $exec_time += round($end - $start, 6);
186
187 $response = ['results' => ''];
188
189 if ( ! $result1 || ! $result2 ) {
190 $response['results'] = 'WPP: failed to update views count!';
191 return new \WP_REST_Response($response, 500);
192 }
193
194 // Allow WP themers / coders perform an action
195 // after updating views count
196 if ( has_action('wpp_post_update_views') )
197 do_action('wpp_post_update_views', $post_ID);
198
199 $response['results'] = "WPP: OK. Execution time: " . $exec_time . " seconds";
200 return new \WP_REST_Response($response, 201);
201 }
202
203 /**
204 * Retrieves the query params for tracking views count.
205 *
206 * @since 4.1.0
207 *
208 * @return array Query parameters for tracking views count.
209 */
210 public function get_tracking_params()
211 {
212 return [
213 'token' => [
214 'description' => __('Security nonce.'),
215 'type' => 'string',
216 'sanitize_callback' => 'sanitize_text_field',
217 'validate_callback' => 'rest_validate_request_arg',
218 ],
219 'wpp_id' => [
220 'description' => __('The post / page ID.'),
221 'type' => 'integer',
222 'default' => 0,
223 'sanitize_callback' => 'absint',
224 'validate_callback' => 'rest_validate_request_arg',
225 ],
226 'sampling' => [
227 'description' => __('Enables Data Sampling.'),
228 'type' => 'integer',
229 'default' => 0,
230 'sanitize_callback' => 'absint',
231 'validate_callback' => 'rest_validate_request_arg',
232 ],
233 'sampling_rate' => [
234 'description' => __('Sets the Sampling Rate.'),
235 'type' => 'integer',
236 'default' => 100,
237 'sanitize_callback' => 'absint',
238 'validate_callback' => 'rest_validate_request_arg',
239 ]
240 ];
241 }
242 }
243