PluginProbe
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI / trunk
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI vtrunk
8.0.1 8.0.2 8.0.0 7.9.9.7 7.9.9.6 7.9.9.5 7.9.9.4 7.9.9.3 7.9.9.2 7.9.9.1 7.9.9 7.9.8 7.9.7 7.9.6 7.9.5 7.9.4 7.9.3 7.9.2 7.9.1 7.9.0 7.8.9 7.8.8 7.8.7 7.8.6 7.8.5 All 44 releases
gamipress / includes / admin / tools / recount-activity.php

recount-activity.php in GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI trunk, at includes/admin/tools/recount-activity.php

329 lines 13.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Recount Activity Tool
4 *
5 * @package GamiPress\Admin\Tools\Recount_Activity
6 * @author GamiPress <contact@gamipress.com>, Ruben Garcia <rubengcdev@gmail.com>
7 * @since 1.1.8
8 */
9 // Exit if accessed directly
10 if( !defined( 'ABSPATH' ) ) exit;
11
12 /**
13 * Register Recount Activity Tool meta boxes
14 *
15 * @since 1.1.8
16 *
17 * @param array $meta_boxes
18 *
19 * @return array
20 */
21 function gamipress_recount_activity_tool_meta_boxes( $meta_boxes ) {
22
23 /**
24 * Hook to add recountable activity triggers (login or daily visits are not recountable because they aren't stored in database)
25 *
26 * @since 1.1.8
27 *
28 * @param array $activity_triggers Activity triggers that can be recounted
29 *
30 * @return array
31 */
32 $recountable_activity_triggers = apply_filters( 'gamipress_recountable_activity_triggers',
33 array(
34 '' => __( 'Choose the activity to recount', 'gamipress' ),
35 // WordPress
36 __( 'WordPress', 'gamipress' ) => array(
37 'comments' => __( 'Recount comments', 'gamipress' ),
38 'published_content' => __( 'Recount content publishing', 'gamipress' ),
39 ),
40 )
41 );
42
43 $meta_boxes['recount-activity'] = array(
44 'title' => gamipress_dashicon( 'backup' ) . __( 'Recount Activity', 'gamipress' ),
45 'fields' => apply_filters( 'gamipress_recount_activity_tool_fields', array(
46 'recount_activity_desc' => array(
47 'content' => __( 'This tool will try to sync old activity with your already configured GamiPress install. GamiPress logs will be updated with all the activity stored in the database and the already configured points awards and deducts and achievements will be awarded or deducted too.', 'gamipress' )
48 . '<br>' . __( '<strong>Note:</strong> Some activity may not be possible to recount (like user log ins or daily visits) because there are not registries stored in the database.', 'gamipress' )
49 . '<br>' . __( '<strong>Important:</strong> If emails to notify users about new earnings are enabled is possible that users will receive a lot of emails so is recommendable to deactivate them temporally.', 'gamipress' ),
50 'type' => 'html',
51 ),
52 'activity_to_recount' => array(
53 'name' => __( 'Activity to recount', 'gamipress' ),
54 'tooltip' => __( 'Choose the activity to recount.', 'gamipress' ),
55 'label_cb' => 'cmb_tooltip_label_cb',
56 'type' => 'advanced_select',
57 'options' => $recountable_activity_triggers,
58 ),
59 'entries_per_loop' => array(
60 'name' => __( 'Entries per loop', 'gamipress' ),
61 'tooltip' => __( 'To prevent block your site, this tool performs the recount in small groups of entries. Set the number of entries to recount in each loop (by default, 100).', 'gamipress' ),
62 'label_cb' => 'cmb_tooltip_label_cb',
63 'desc' => __( '<strong>Note:</strong> If the recount process fails, try to reduce this setting to a lower number to 50, 20 or 10 entries per loop.', 'gamipress' ),
64 'type' => 'text',
65 'attributes' => array(
66 'type' => 'number',
67 'min' => '10',
68 'step' => '5'
69 ),
70 'default' => '100'
71 ),
72 'recount_activity' => array(
73 'label' => __( 'Recount Activity', 'gamipress' ),
74 'type' => 'button',
75 'button' => 'primary'
76 ),
77 ) )
78 );
79
80 return $meta_boxes;
81
82 }
83 add_filter( 'gamipress_tools_general_meta_boxes', 'gamipress_recount_activity_tool_meta_boxes' );
84
85 /**
86 * AJAX handler for the recount activity tool
87 *
88 * @since 1.1.8
89 * @updated 1.4.2 Added the run again utility
90 */
91 function gamipress_ajax_recount_activity_tool() {
92 // Security check, forces to die if not security passed
93 check_ajax_referer( 'gamipress_admin', 'nonce' );
94
95 // Check user capabilities
96 if( ! current_user_can( gamipress_get_manager_capability() ) ) {
97 wp_send_json_error( __( 'You are not allowed to perform this action.', 'gamipress' ) );
98 }
99
100 // Check parameters received
101 if( ! isset( $_POST['activity'] ) || empty( $_POST['activity'] ) ) {
102 wp_send_json_error( __( 'You need to choose an activity to recount.', 'gamipress' ) );
103 }
104
105 ignore_user_abort( true );
106
107 if ( ! gamipress_is_function_disabled( 'set_time_limit' ) ) {
108 set_time_limit( 0 );
109 }
110
111 // Setup a global var to make other functions meet that next awards comes from recount activity tool
112 define( 'GAMIPRESS_DOING_ACTIVITY_RECOUNT', true );
113
114 $response = array(
115 'success' => true,
116 'run_again' => false,
117 'message' => __( 'Activity recount process has been done successfully.', 'gamipress' ),
118 'log' => '',
119 );
120
121 $activity = sanitize_text_field( $_POST['activity'] );
122 $loop = ( isset( $_POST['loop'] ) ? absint( $_POST['loop'] ) : 0 );
123 $limit = ( isset( $_POST['limit'] ) ? absint( $_POST['limit'] ) : 100 );
124 $offset = $limit * $loop;
125
126 /**
127 * Hook to process activity recount
128 *
129 * @since 1.1.8
130 * @updated 1.4.2 Added $loop parameter
131 * @updated 1.8.2 Added $limit and $offset parameters
132 *
133 * @param array $response Response to return. Response format: array(
134 * success => true|false,
135 * run_again => true|false,
136 * message => string,
137 * log => string,
138 * )
139 * @param int $loop Parameter to meet in which loop is the tool (just increased if run_again is set to true).
140 * Important: First loop will be 0.
141 *
142 * @param int $limit Limit per loop, by default 100
143 * @param int $offset Current offset
144 */
145 $response = apply_filters( "gamipress_activity_recount_$activity", $response, $loop, $limit, $offset );
146
147 if( ! is_array( $response ) ) {
148 wp_send_json_error( 'Activity recount process has failed!', 'gamipress' );
149 }
150
151 // Return the full response
152 if( $response['run_again'] ) {
153 wp_send_json_success( $response );
154 }
155
156 // Return the process response
157 if( $response['success'] === true ) {
158 wp_send_json_success( $response['message'] );
159 } else {
160 wp_send_json_error( $response['message'] );
161 }
162
163 }
164 add_action( 'wp_ajax_gamipress_recount_activity_tool', 'gamipress_ajax_recount_activity_tool' );
165
166 /**
167 * Recount comments activity
168 *
169 * @since 1.1.8
170 * @updated 1.4.2 Added $loop parameter
171 *
172 * @param array $response
173 * @param int $loop
174 * @param int $limit
175 * @param int $offset
176 *
177 * @return array $response
178 */
179 function gamipress_activity_recount_comments( $response, $loop, $limit, $offset ) {
180
181 global $wpdb;
182
183 // Get all approved comments count
184 $comments_count = absint( $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->comments} WHERE comment_approved = '1'" ) );
185
186 // On first loop send an informational text
187 if( $loop === 0 && $comments_count > $limit ) {
188 $response['run_again'] = true;
189 $response['message'] = sprintf( __( '%d comments found, recounting...', 'gamipress' ), $comments_count );
190 $response['log'] = sprintf( __( '%d comments found, recounting...', 'gamipress' ), $comments_count ) . "<br>\n";
191
192 // Return early to inform
193 return $response;
194 }
195
196 // Get all approved comments
197 $comments = $wpdb->get_results( "SELECT * FROM {$wpdb->comments} WHERE comment_approved = '1' LIMIT {$offset}, {$limit}" );
198
199 foreach( $comments as $comment ) {
200
201 $comment_id = (int) $comment->comment_ID;
202 $user_id = (int) $comment->user_id;
203 $post_id = (int) $comment->comment_post_ID;
204 $post_type = get_post_type( $post_id );
205
206 // Skip wrong comments
207 if( $comment_id === 0 ) continue;
208
209 // Skip not user assigned comments
210 if( $user_id === 0 ) continue;
211
212 // Trigger comment actions to user
213 do_action( 'gamipress_new_comment', $comment_id, $user_id, $post_id, $comment );
214 do_action( 'gamipress_specific_new_comment', $comment_id, $user_id, $post_id, $comment );
215 do_action( 'gamipress_new_comment_post_type', $comment_id, $user_id, $post_id, $post_type, $comment );
216
217 $response['log'] .= sprintf( __( '[Comment on a post] Comment: %s User: %s Post: %s', 'gamipress' ),
218 $comment_id,
219 '<a href="' . get_edit_user_link( $user_id ) . '" target="_blank">' . $user_id . '</a>',
220 '<a href="' . get_edit_post_link( $post_id ) . '" target="_blank">' . $post_id . '</a>'
221 ) . "<br>\n";
222
223 if( $post_id !== 0 ) {
224
225 $post_author = absint( get_post_field( 'post_author', $post_id ) );
226
227 // Trigger comment actions to author
228 do_action( 'gamipress_user_post_comment', $comment_id, $post_author, $post_id, $comment );
229 do_action( 'gamipress_user_specific_post_comment', $comment_id, $post_author, $post_id, $comment );
230 do_action( 'gamipress_user_post_comment_post_type', $comment_id, $post_author, $post_id, $post_type, $comment );
231
232 $response['log'] .= sprintf( __( '[Get a comment on a post] Comment: %s User: %s Post: %s', 'gamipress' ),
233 $comment_id,
234 '<a href="' . get_edit_user_link( $post_author ) . '" target="_blank">' . $post_author . '</a>',
235 '<a href="' . get_edit_post_link( $post_id ) . '" target="_blank">' . $post_id . '</a>'
236 ) . "<br>\n";
237 }
238 }
239
240 $recounted_comments = $limit * ( $loop + 1 );
241
242 // Check remaining comments
243 if( $recounted_comments < $comments_count ) {
244 $response['run_again'] = true;
245 $response['message'] = sprintf( __( '%d remaining comments to finish recount', 'gamipress' ), ( $comments_count - $recounted_comments ) );
246 }
247
248 return $response;
249
250 }
251 add_filter( 'gamipress_activity_recount_comments', 'gamipress_activity_recount_comments', 10, 4 );
252
253 /**
254 * Recount published content
255 *
256 * @since 1.1.8
257 * @updated 1.4.2 Added $loop parameter
258 *
259 * @param array $response
260 * @param int $loop
261 * @param int $limit
262 * @param int $offset
263 *
264 * @return array $response
265 */
266 function gamipress_activity_recount_published_content( $response, $loop, $limit, $offset ) {
267
268 global $wpdb;
269
270 // Get all public post types which means they are visitable
271 $public_post_types = get_post_types( array( 'public' => true ) );
272
273 // Remove attachment from public post types
274 if( isset( $public_post_types['attachment'] ) )
275 unset( $public_post_types['attachment'] );
276
277 // Get all published posts
278 $posts_count = absint( $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_status = 'publish' AND post_type IN ( '" . implode( "', '", $public_post_types ) . "' )" ) );
279
280 // On first loop send an informational text
281 if( $loop === 0 && $posts_count > $limit ) {
282 $response['run_again'] = true;
283 $response['message'] = sprintf( __( '%d posts found, recounting...', 'gamipress' ), $posts_count );
284 $response['log'] = sprintf( __( '%d posts found, recounting...', 'gamipress' ), $posts_count ) . "<br>\n";
285
286 // Return early to inform
287 return $response;
288 }
289
290 // Get all published posts
291 $posts = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} WHERE post_status = 'publish' AND post_type IN ( '" . implode( "', '", $public_post_types ) . "' ) LIMIT {$offset}, {$limit}" );
292
293 foreach( $posts as $post ) {
294 // Trigger content publishing action for each post
295 gamipress_trigger_event( array(
296 'event' => "gamipress_publish_{$post->post_type}",
297 'post_id' => $post->ID,
298 'user_id' => $post->post_author,
299 'post' => $post,
300 ) );
301
302 // Trigger post type publishing actions
303 gamipress_trigger_event( array(
304 'event' => 'gamipress_publish_post_type',
305 'post_id' => $post->ID,
306 'user_id' => $post->post_author,
307 'post_type' => $post->post_type,
308 'post' => $post,
309 ) );
310
311 $response['log'] .= sprintf( __( '[Publish a post] Post: %s User: %s Post Type: %s', 'gamipress' ),
312 '<a href="' . get_edit_post_link( $post->ID ) . '" target="_blank">' . $post->ID . '</a>',
313 '<a href="' . get_edit_user_link( $post->post_author ) . '" target="_blank">' . $post->post_author . '</a>',
314 $post->post_type
315 ) . "<br>\n";
316 }
317
318 $recounted_posts = $limit * ( $loop + 1 );
319
320 // Check remaining posts
321 if( $recounted_posts < $posts_count ) {
322 $response['run_again'] = true;
323 $response['message'] = sprintf( __( '%d remaining posts to finish recount', 'gamipress' ), ( $posts_count - $recounted_posts ) );
324 }
325
326 return $response;
327
328 }
329 add_filter( 'gamipress_activity_recount_published_content', 'gamipress_activity_recount_published_content', 10, 4 );