PluginProbe
Tag, Category, and Taxonomy Manager – Autotagger Automatically Add Terms / 3.6.0
Tag, Category, and Taxonomy Manager – Autotagger Automatically Add Terms v3.6.0
3.53.0 3.52.0 3.51.0 3.50.0 3.45.0 3.38.0 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.40.0 3.40.1 3.41.0 3.42.0 3.43.0 3.44.0 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 All 177 releases
simple-tags / inc / class.client.autoterms.php

class.client.autoterms.php in Tag, Category, and Taxonomy Manager – Autotagger Automatically Add Terms 3.6.0, at inc/class.client.autoterms.php

501 lines 16.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class SimpleTags_Client_Autoterms {
4 /**
5 * Constructor
6 *
7 * @return void
8 * @author WebFactory Ltd
9 */
10 public function __construct() {
11 if ( 1 === (int) SimpleTags_Plugin::get_option_value( 'active_auto_terms' ) ) {
12 add_action( 'save_post', array( __CLASS__, 'save_post' ), 12, 2 );
13 add_action( 'post_syndicated_item', array( __CLASS__, 'save_post' ), 12, 2 );
14 }
15 }
16
17 /**
18 * Check post/page content for auto terms
19 *
20 * @param integer $post_id
21 * @param object $object
22 *
23 * @return boolean
24 */
25 public static function save_post( $post_id = null, $object = null ) {
26
27 // Get options
28 $options = get_option( STAGS_OPTIONS_NAME_AUTO );
29
30 // user preference for this post ?
31 $meta_value = isset($_POST['exclude_autotags']) ? sanitize_text_field($_POST['exclude_autotags']) : false;
32 if ( $meta_value ) {
33 return false;
34 }
35
36 if(!is_object($object)){
37 return;
38 }
39
40 if(!isset($object->post_type)){
41 return;
42 }
43
44 // Loop option for find if autoterms is actived on any taxonomy and post type
45 $current_post_type = $object->post_type;
46 $current_post_status = $object->post_status;
47 $autoterms = taxopress_get_autoterm_data();
48 $flag = false;
49 foreach($autoterms as $autoterm_key => $autoterm_data){
50 $eligible_post_status = isset($autoterm_data['post_status']) && is_array($autoterm_data['post_status']) ? $autoterm_data['post_status'] : ['publish'];
51 $eligible_post_types = isset($autoterm_data['post_types']) && is_array($autoterm_data['post_types']) ? $autoterm_data['post_types'] : [];
52 $eligible_post_types = array_filter($eligible_post_types);
53
54 if(count($eligible_post_types) === 0){
55 break;
56 }
57 if(!in_array($current_post_type, $eligible_post_types)){
58 continue;
59 }
60 if(!in_array($current_post_status, $eligible_post_status)){
61 continue;
62 }
63
64 self::auto_terms_post( $object, $autoterm_data['taxonomy'], $autoterm_data, false, 'save_posts', 'st_autoterms' );
65 $flag = true;
66 }
67
68 if ( $flag == true ) { // Clean cache ?
69 clean_post_cache( $post_id );
70 }
71
72 return true;
73 }
74
75 /**
76 * Automatically tag a post/page from the database terms for the taxonomy specified
77 *
78 * @param object $object
79 * @param string $taxonomy
80 * @param array $options
81 * @param boolean $counter
82 *
83 * @return boolean
84 * @author WebFactory Ltd
85 */
86 public static function auto_terms_post( $object, $taxonomy = 'post_tag', $options = array(), $counter = false, $action = 'save_posts', $component = 'st_autoterms' ) {
87 global $wpdb;
88
89 $terms_to_add = array();
90
91 $exclude_autotags = get_post_meta( $object->ID, '_exclude_autotags', true );
92 if ( $exclude_autotags ) {
93 return false;
94 }
95
96 // Option exists ?
97 if ( $options == false || empty( $options ) ) {
98 //update log
99 self::update_taxopress_logs( $object, $taxonomy, $options, $counter, $action, $component, $terms_to_add, 'failed', 'invalid_option');
100 return false;
101 }
102
103 if ( get_the_terms( $object->ID, $taxonomy ) != false && (int)$options['autoterm_target'] === 1 ) {
104 //update log
105 self::update_taxopress_logs( $object, $taxonomy, $options, $counter, $action, $component, $terms_to_add, 'failed', 'term_only_option');
106 return false; // Skip post with terms, if term only empty post option is checked
107 }
108
109 $autoterm_exclude = isset($options['autoterm_exclude']) ? taxopress_change_to_array($options['autoterm_exclude']) : [];
110
111
112
113 if( isset($options['autoterm_from']) && $options['autoterm_from'] === 'post_title' ){
114 $content = $object->post_title;
115 }elseif( isset($options['autoterm_from']) && $options['autoterm_from'] === 'post_content' ){
116 $content = $object->post_content;
117 }else{
118 $content = $object->post_content . ' ' . $object->post_title;
119 }
120
121 if ( isset( $object->post_excerpt ) ) {
122 $content .= ' ' . $object->post_excerpt;
123 }
124
125 $content = trim( strip_tags( $content ) );
126 if ( empty( $content ) ) {
127 //update log
128 self::update_taxopress_logs( $object, $taxonomy, $options, $counter, $action, $component, $terms_to_add, 'failed', 'empty_post_content');
129 return false;
130 }
131
132 $autoterm_use_dandelion = isset($options['autoterm_use_dandelion']) ? (int)$options['autoterm_use_dandelion'] : 0;
133 $autoterm_use_opencalais = isset($options['autoterm_use_opencalais']) ? (int)$options['autoterm_use_opencalais'] : 0;
134
135 //Autoterm with Dandelion
136 if ( $autoterm_use_dandelion > 0 && $options['terms_datatxt_access_token'] !== '' ) {
137 $request_ws_args = array();
138 $request_ws_args['text'] = $content;
139 // Custom confidence ?
140 $request_ws_args['min_confidence'] = 0.6;
141 if ( $options['terms_datatxt_min_confidence'] != "" ) {
142 $request_ws_args['min_confidence'] = $options['terms_datatxt_min_confidence'];
143 }
144 $request_ws_args['token'] = $options['terms_datatxt_access_token'];
145 // Build params
146 $response = wp_remote_post( 'https://api.dandelion.eu/datatxt/nex/v1', array(
147 'user-agent' => 'WordPress simple-tags',
148 'body' => $request_ws_args
149 ) );
150 $data = false;
151 if ( ! is_wp_error( $response ) && $response != null ) {
152 if ( wp_remote_retrieve_response_code( $response ) == 200 ) {
153 $data = wp_remote_retrieve_body( $response );
154 }
155 }
156 if($data){
157 $data = json_decode( $data );
158 $data = is_object($data) ? $data->annotations : '';
159 if ( !empty( $data ) ) {
160 foreach ( (array) $data as $term ) {
161 $term = $term->title;
162 $term = stripslashes( $term );
163
164 if ( ! is_string( $term ) ) {
165 continue;
166 }
167
168 $term = trim( $term );
169 if ( empty( $term ) ) {
170 continue;
171 }
172
173 //check if term belong to the post already
174 if(has_term( $term, $taxonomy, $object )){
175 continue;
176 }
177
178 //exclude if name found in exclude terms
179 if(in_array($term, $autoterm_exclude)){
180 continue;
181 }
182
183 // Whole word ?
184 if ( isset( $options['autoterm_word'] ) && (int) $options['autoterm_word'] == 1 ) {
185 if(strpos($content, ' '.$term.' ') !== FALSE)
186 {
187 $terms_to_add[] = $term;
188 }
189
190 //make exception for hashtag special character
191 if (substr($term, 0, strlen('#')) === '#') {
192 $trim_term = ltrim($term, '#');
193 if ( preg_match( "/\B(\#+$trim_term\b)(?!;)/i", $content ) ) {
194 $terms_to_add[] = $term;
195 }
196 }
197
198 if ( isset( $options['autoterm_hash'] ) && (int) $options['autoterm_hash'] == 1 && stristr( $content, '#' . $term ) ) {
199 $terms_to_add[] = $term;
200 }
201 } elseif ( stristr( $content, $term ) ) {
202 $terms_to_add[] = $term;
203 }
204 }
205 }
206 }
207 }
208
209 //Autoterm with OpenCalais
210 if ( $autoterm_use_opencalais > 0 && $options['terms_opencalais_key'] !== '' ) {
211 $response = wp_remote_post( 'https://api-eit.refinitiv.com/permid/calais', array(
212 'timeout' => 30,
213 'headers' => array(
214 'X-AG-Access-Token' => $options['terms_opencalais_key'],
215 'Content-Type' => 'text/html',
216 'outputFormat' => 'application/json'
217 ),
218 'body' => $content
219 ) );
220 $data = false;
221 if ( ! is_wp_error( $response ) && $response != null ) {
222 if ( wp_remote_retrieve_response_code( $response ) == 200 ) {
223 $data_raw = json_decode( wp_remote_retrieve_body( $response ), true );
224 $data = array();
225 if ( isset( $data_raw ) && is_array( $data_raw ) ) {
226 foreach ( $data_raw as $_data_raw ) {
227 if ( isset( $_data_raw['_typeGroup'] ) && $_data_raw['_typeGroup'] == 'socialTag' ) {
228 $data[] = $_data_raw['name'];
229 }
230 }
231 }
232 }
233 }
234 if($data){
235 if (!empty( $data )){
236 // Remove empty terms
237 $data = array_filter( $data, '_delete_empty_element' );
238 $data = array_unique( $data );
239
240 foreach ( (array) $data as $term ) {
241 $term = stripslashes( $term );
242
243 if ( ! is_string( $term ) ) {
244 continue;
245 }
246
247 $term = trim( $term );
248 if ( empty( $term ) ) {
249 continue;
250 }
251
252 //check if term belong to the post already
253 if(has_term( $term, $taxonomy, $object )){
254 continue;
255 }
256
257 //exclude if name found in exclude terms
258 if(in_array($term, $autoterm_exclude)){
259 continue;
260 }
261
262 // Whole word ?
263 if ( isset( $options['autoterm_word'] ) && (int) $options['autoterm_word'] == 1 ) {
264 if(strpos($content, ' '.$term.' ') !== FALSE)
265 {
266 $terms_to_add[] = $term;
267 }
268
269 //make exception for hashtag special character
270 if (substr($term, 0, strlen('#')) === '#') {
271 $trim_term = ltrim($term, '#');
272 if ( preg_match( "/\B(\#+$trim_term\b)(?!;)/i", $content ) ) {
273 $terms_to_add[] = $term;
274 }
275 }
276
277 if ( isset( $options['autoterm_hash'] ) && (int) $options['autoterm_hash'] == 1 && stristr( $content, '#' . $term ) ) {
278 $terms_to_add[] = $term;
279 }
280 } elseif ( stristr( $content, $term ) ) {
281 $terms_to_add[] = $term;
282 }
283 }
284 }
285 }
286
287 }
288
289 // Auto term with specific auto terms list
290 if ( isset( $options['specific_terms'] ) && isset( $options['autoterm_useonly'] ) && (int)$options['autoterm_useonly'] === 1 ) {
291 $terms = maybe_unserialize( $options['specific_terms'] );
292 $terms = taxopress_change_to_array($terms);
293 foreach ( $terms as $term ) {
294 if ( ! is_string( $term ) ) {
295 continue;
296 }
297
298 $term = trim( $term );
299 if ( empty( $term ) ) {
300 continue;
301 }
302
303 //check if term belong to the post already
304 if(has_term( $term, $taxonomy, $object )){
305 continue;
306 }
307
308 //exclude if name found in exclude terms
309 if(in_array($term, $autoterm_exclude)){
310 continue;
311 }
312
313 // Whole word ?
314 if ( isset( $options['autoterm_word'] ) && (int)$options['autoterm_word'] === 1 ) {
315 if(strpos($content, ' '.$term.' ') !== FALSE)
316 {
317 $terms_to_add[] = $term;
318 }
319
320 //make exception for hashtag special character
321 if (substr($term, 0, strlen('#')) === '#') {
322 $trim_term = ltrim($term, '#');
323 if ( preg_match( "/\B(\#+$trim_term\b)(?!;)/i", $content ) ) {
324 $terms_to_add[] = $term;
325 }
326 }
327
328 if ( isset( $options['autoterm_hash'] ) && (int)$options['autoterm_hash'] === 1 && stristr( $content, '#' . $term ) ) {
329 $terms_to_add[] = $term;
330 }
331 } elseif ( stristr( $content, $term ) ) {
332 $terms_to_add[] = $term;
333 }
334 }
335 unset( $terms, $term );
336 }
337
338 // Auto terms with all terms
339 if ( isset( $options['autoterm_useall'] ) && (int)$options['autoterm_useall'] === 1 ) {
340 // Get all terms
341 $terms = $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT name
342 FROM {$wpdb->terms} AS t
343 INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id
344 WHERE tt.taxonomy = %s", $taxonomy ) );
345
346 $terms = array_unique( $terms );
347
348 foreach ( $terms as $term ) {
349 $term = stripslashes( $term );
350
351 if ( ! is_string( $term ) ) {
352 continue;
353 }
354
355 $term = trim( $term );
356 if ( empty( $term ) ) {
357 continue;
358 }
359
360 //check if term belong to the post already
361 if(has_term( $term, $taxonomy, $object )){
362 continue;
363 }
364
365 //exclude if name found in exclude terms
366 if(in_array($term, $autoterm_exclude)){
367 continue;
368 }
369
370 // Whole word ?
371 if ( isset( $options['autoterm_word'] ) && (int) $options['autoterm_word'] == 1 ) {
372 if(strpos($content, ' '.$term.' ') !== FALSE)
373 {
374 $terms_to_add[] = $term;
375 }
376
377 //make exception for hashtag special character
378 if (substr($term, 0, strlen('#')) === '#') {
379 $trim_term = ltrim($term, '#');
380 if ( preg_match( "/\B(\#+$trim_term\b)(?!;)/i", $content ) ) {
381 $terms_to_add[] = $term;
382 }
383 }
384
385 if ( isset( $options['autoterm_hash'] ) && (int) $options['autoterm_hash'] == 1 && stristr( $content, '#' . $term ) ) {
386 $terms_to_add[] = $term;
387 }
388 } elseif ( stristr( $content, $term ) ) {
389 $terms_to_add[] = $term;
390 }
391 }
392 }
393
394 // Append terms if terms to add
395 if ( ! empty( $terms_to_add ) ) {
396 // Remove empty and duplicate elements
397 $terms_to_add = array_filter( $terms_to_add, '_delete_empty_element' );
398 $terms_to_add = array_unique( $terms_to_add );
399
400 //auto terms limit
401 $terms_limit = isset($options['terms_limit']) ? (int)$options['terms_limit'] : 0;
402 if($terms_limit > 0 && count($terms_to_add) > $terms_limit){
403 $terms_to_add = array_slice($terms_to_add, 0, $terms_limit);
404 }
405
406 if ( $counter == true ) {
407 // Increment counter
408 $counter = ( (int) get_option( 'tmp_auto_terms_st' ) ) + count( $terms_to_add );
409 update_option( 'tmp_auto_terms_st', $counter );
410 }
411
412 // Add terms to posts
413 wp_set_object_terms( $object->ID, $terms_to_add, $taxonomy, true );
414
415 // Clean cache
416 clean_post_cache( $object->ID );
417
418 //update log
419 self::update_taxopress_logs( $object, $taxonomy, $options, $counter, $action, $component, $terms_to_add, 'success', 'terms_added');
420
421 return true;
422 }else{
423 //update log
424 self::update_taxopress_logs( $object, $taxonomy, $options, $counter, $action, $component, $terms_to_add, 'failed', 'empty_terms');
425 }
426
427 return false;
428 }
429
430 /**
431 * Update taxopress logs
432 *
433 * Known possible values
434 *
435 * COMPONENT: (st_autoterms)
436 * ACTION: (existing_content, save_posts, daily_cron_schedule, hourly_cron_schedule)
437 * STATUS: (failed, success)
438 * STATUS MESSAGE: (invalid_option, term_only_option, empty_post_content, terms_added, empty_terms)
439 *
440 * @param object $object
441 * @param string $taxonomy
442 * @param array $options
443 * @param boolean $counter
444 * @param string $action
445 * @param string $component
446 * @param array $terms_to_add
447 * @param string $status
448 * @param string $status_message
449 *
450 * @return boolean
451 * @author olatechpro
452 */
453 public static function update_taxopress_logs( $object, $taxonomy = 'post_tag', $options = array(), $counter = false, $action = 'save_posts', $component = 'st_autoterms', $terms_to_add = [], $status = 'failed', $status_message = 'not_provided' ) {
454
455 if (get_option('taxopress_autoterms_logs_disabled')) {
456 return;
457 }
458
459 $insert_post_args = array(
460 'post_author' => get_current_user_id(),
461 'post_title' => $object->post_title,
462 'post_content' => $object->post_content,
463 'post_status' => 'publish',
464 'post_type' => 'taxopress_logs',
465 );
466 $post_id = wp_insert_post($insert_post_args);
467 update_post_meta($post_id, '_taxopress_log_post_id', $object->ID);
468 update_post_meta($post_id, '_taxopress_log_taxonomy', $taxonomy);
469 update_post_meta($post_id, '_taxopress_log_post_type', get_post_type($object->ID));
470 update_post_meta($post_id, '_taxopress_log_action', $action);
471 update_post_meta($post_id, '_taxopress_log_component', $component);
472 update_post_meta($post_id, '_taxopress_log_terms', implode (", ", $terms_to_add));
473 update_post_meta($post_id, '_taxopress_log_status', $status);
474 update_post_meta($post_id, '_taxopress_log_status_message', $status_message);
475 update_post_meta($post_id, '_taxopress_log_options', $options);
476 update_post_meta($post_id, '_taxopress_log_option_id', $options['ID']);
477
478 //for performance reason, delete only 1 posts if more than limit instead of querying all posts
479 $auto_terms_logs_limit = (int)get_option('taxopress_auto_terms_logs_limit', 1000);
480 $current_logs_count = wp_count_posts('taxopress_logs')->publish;
481
482 if((int)$current_logs_count > $auto_terms_logs_limit){
483 $posts = get_posts(array(
484 'post_type' => 'taxopress_logs',
485 'post_status' => 'publish',
486 'posts_per_page' => 1,
487 'orderby' => 'ID',
488 'order' => 'ASC',
489 'fields' => 'ids'
490 ));
491 if(count($posts) > 0){
492 foreach($posts as $post){
493 wp_delete_post($post, true);
494 }
495 }
496 }
497
498 }
499
500 }
501