bcworkz

double-term.php

May 5th, 2017
294
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 8.04 KB | None | 0 0
  1. <?php
  2. /*
  3. Plugin Name: double-term
  4. Description: Custom code for oieniuz's auto sales installation. Sets up sitemap links using two taxonomy terms. Requires Yoast SEO plugin to be active.
  5. Author: bcworkz
  6. Version: 0.10 beta
  7. License: GPL 2.0
  8. */
  9.  
  10. /**
  11.  *  Requires Yoast WP SEO plugin to be installed and activated. This is not verified.
  12.  *  Adds custom sitemaps to Yoast sitemaps that include links with double terms. This sitemap type
  13.  *  in Yoast is 'dblterm', the sitemap URLS are something like dblterm-sitemap3.xml . The '3' could
  14.  *  be any integer. They are referenced in the root sitemap-index.xml generated by Yoast
  15.  *  Sitemap URLs are shown to be published 1/2 week ago, regardless of actual publish dates.
  16.  */
  17.  
  18. // Constants for use in custom Yoast sitemaps - adjust values as required
  19. // This plugin ignores the max. items set in Yoast. The value here is used.
  20. // To flush Yoast sitemap cache, change the Max items on Yoast's sitemap screen, then save
  21. // You must also reload the retrieved sitemap to flush browser cached versions
  22.  
  23. /**
  24.  * Max items. Per sitemap specifications, max is 50,000 minus $location_count
  25.  *  - maybe assume 48k max ?? (there may also be memory constraints)
  26.  *  - script will output more than specified to complete a full set of locations per model
  27.  */
  28. define( 'MAX_ITEMS', 1000 );
  29.  
  30. // Taxonomies for term sources
  31. define('MODELS', 'vehicle_model');
  32. define('LOCATIONS', 'vehicle_location');
  33.  
  34. // Register "dblterm" sitemap type with Yoast sitemap object
  35. //  this allows Yoast to handle redirects and sitemap caching :)
  36. add_action('init', 'dt_register_map');
  37. function dt_register_map() {
  38.     if ( array_key_exists('wpseo_sitemaps', $GLOBALS )) {
  39.         $sitemaps = $GLOBALS['wpseo_sitemaps'];
  40.         $sitemaps->register_sitemap( 'dblterm', 'dt_gen_sitemap_dbl_terms');
  41.     }
  42. }
  43.  
  44. /**
  45.  * generates XML sitemap content from 2 taxonomies/terms
  46.  * used as callback to action 'wpseo_do_sitemap_dblterm'
  47.  * ignores Yoast max. entries - The max. is hardcoded as constant MAX_ITEMS above.
  48.  * filename to request: dblterm-sitemap#.xml where # is page number (any places: #, ##, ###, ...)
  49.  */
  50. function dt_gen_sitemap_dbl_terms() {
  51.     // assign constants to local vars
  52.     $max_items = MAX_ITEMS;
  53.     $vehicle_model = MODELS;
  54.     $vehicle_location = LOCATIONS;
  55.  
  56.     $page = get_query_var( 'sitemap_n' );   //Yoast sitemap page # taken from filename requested
  57.     if ( '' == $page ) $page = 1;           // Assume page 1 if no query var
  58.     // Yoast will send headers, set <?xml version, encoding, stylesheets, templates ? >
  59.     $pages = '<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
  60.  
  61.     // get terms through SQL queries
  62.     $models = dt_alt_get_terms( $vehicle_model ); // each hides empty terms by default
  63.     $locations = dt_alt_get_terms( $vehicle_location );
  64.     $model_ct = count( $models );
  65.     $location_ct = count( $locations );
  66.  
  67.     // determine parameters so page breaks occur after full set of locations are output
  68.     $models_per_page = floor(($max_items/$location_ct) + 1 );
  69.     $offset = ($page-1) * $models_per_page;
  70.     if ( 0 > $offset ) $offset = 0;         // safety function just in case something odd happens
  71.     $limit = $offset + ($models_per_page * $location_ct);
  72.     // do not surpass number of models available
  73.     $limit = ( $model_ct < $limit ) ? $model_ct: $limit;
  74.  
  75.     $count = 0;
  76.     // Loop through all term permutaions
  77.     for ( $i=$offset; $i<$limit; $i++ ) {
  78.         $model = $models[$i];
  79.         foreach ( $locations as $location ) {
  80.             $location2 = home_url( '/used-cars/location/' . $location . '/model/' . $model .'/' );
  81.             // Assume all published 1/2 week ago
  82.             $date = date_i18n('o-m-d\TH:i:sP', current_time('timestamp')-( 3.5 * DAY_IN_SECONDS ));
  83.             $pages .= "\t<url>\n\t\t<loc>$location2</loc>\n\t\t<lastmod>$date</lastmod>\n\t</url>\n";
  84.             $count++;
  85.         }
  86.         if ( $count >= $max_items) break;
  87.     }
  88.  
  89.     // Get Yoast sitemap object and give it our sitemap
  90.     $sitemaps = $GLOBALS['wpseo_sitemaps'];
  91.     $sitemaps->set_sitemap( $pages . '</urlset>');
  92.     return;
  93. }
  94.  
  95. // Add dblterm-sitemap links to sitemap-index
  96. add_filter( 'wpseo_sitemap_index', 'dt_add_to_index' );
  97. function dt_add_to_index() {
  98.     // assign constants to local vars
  99.     $max_items = MAX_ITEMS;
  100.     $vehicle_model = MODELS;
  101.     $vehicle_location = LOCATIONS;
  102.  
  103.     // get term counts through SQL queries
  104.     $models = dt_alt_get_terms( $vehicle_model ); // each hides empty terms by default
  105.     $locations = dt_alt_get_terms( $vehicle_location );
  106.     $model_ct = count( $models );
  107.     $location_ct = count( $locations );
  108.  
  109.     // determine parameters so page breaks occur after full set of locations are output
  110.     $models_per_page = floor(( $max_items / $location_ct ) + 1 );
  111.     $max_page_idx = floor(( $model_ct / $models_per_page ) + 1 );
  112.    
  113.     $links = '';
  114.     // Assume all published 1/2 week ago
  115.     $date = date_i18n('o-m-d\TH:i:sP', current_time('timestamp')-( 3.5 * DAY_IN_SECONDS ));
  116.     for ( $i=1; $i<=$max_page_idx; $i++ ) {
  117.         $url = get_site_url( null, '/dblterm-sitemap' . (string)$i . '.xml');
  118.         $links .= "\t<sitemap>\n\t\t<loc>$url</loc>\n\t\t<lastmod>$date</lastmod>\n\t</sitemap>\n";
  119.     }
  120.     return $links;
  121. }
  122.  
  123. /**
  124.  * Gets all terms for taxonomy $tax
  125.  * Hides empty terms unless hiding algorithm is commented out (@ line 144)
  126.  * Returns an array of term slugs
  127.  */
  128. function dt_alt_get_terms( $tax ) {
  129. /*  // The original alt_get_terms(). Direct query ought to be a bit faster??
  130.     $hide_empty = true;
  131.     $term_query = new WP_Term_Query(['taxonomy'=> $tax, 'fields'=>'id=>slug', 'hide_empty'=> $hide_empty,]);
  132.     $terms = $term_query->get_terms();
  133.     $no_empties = array();
  134.     foreach ( $terms as $term ) { $no_empties[] = $term->slug; }
  135. */
  136.     global $wpdb;
  137.     $terms = $wpdb->get_results( $wpdb->prepare("SELECT t.term_id, t.slug, tt.count, tt.taxonomy FROM $wpdb->terms AS t
  138.         INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id
  139.         WHERE tt.taxonomy IN ('%s') ORDER BY t.slug ASC;",
  140.         $tax
  141.     ));
  142.     // Remove empty terms unless children are not empty (hide_empty = true)
  143.     // Algorithm copied from WordPress core code (it's OK, WP is GPL licensed)
  144.     // To show empties add astrisk between two slashes at beginning of this line
  145.     if ( is_array( $terms ) ) {
  146.         foreach ( $terms as $k => $term ) {
  147.             if ( ! $term->count ) {
  148.                 $children = get_term_children( $term->term_id, $term->taxonomy );
  149.                 if ( is_array( $children ) ) {
  150.                     foreach ( $children as $child_id ) {
  151.                         $child = get_term( $child_id, $term->taxonomy );
  152.                         if ( $child->count ) {
  153.                             continue 2;
  154.                         }
  155.                     }
  156.                 }
  157.                 // It really is empty.
  158.                 unset( $terms[ $k ] );
  159.             }
  160.         }
  161.     }
  162.     // end remove empty terms------------------------ */
  163.  
  164.     //make array indices sequential, save value of slug only
  165.     $no_empties = array();
  166.     foreach ( $terms as $term ) { $no_empties[] = $term->slug; }
  167.     return $no_empties;
  168. }
  169.  
  170. /**
  171.  * Transient Garbage Collection - WP only does this on DB upgrades
  172.  *
  173.  * Deletes all expired transients.
  174.  * The multi-table delete syntax is used to delete the transient record from table a,
  175.  * and the corresponding transient_timeout record from table b, though in fact both
  176.  * are in the same table.
  177.  */
  178.  
  179. // only setup event on activation
  180. register_activation_hook(__FILE__, 'dt_activation');
  181.  
  182. function dt_activation() {
  183.     if (! wp_next_scheduled ( 'dt_event' )) {
  184.         wp_schedule_event(time(), 'daily', 'dt_event');
  185.     }
  186. }
  187.  
  188. add_action('dt_event', 'dt_do_this_daily');
  189. function dt_do_this_daily() {
  190.     global $wpdb;
  191.     $time = time();
  192.     //from upgrade_network()
  193.     $wpdb->query("DELETE a, b FROM $wpdb->options a, $wpdb->options b WHERE
  194.         a.option_name LIKE '\_transient\_%' AND
  195.         a.option_name NOT LIKE '\_transient\_timeout\_%' AND
  196.         b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 17 ) )
  197.         AND b.option_value < $time");
  198.     return;
  199. }
  200.  
  201. // remove event hook on deactivation
  202. register_deactivation_hook(__FILE__, 'dt_deactivation');
  203. function dt_deactivation() {
  204.     wp_clear_scheduled_hook('dt_event');
  205. }
Advertisement
Add Comment
Please, Sign In to add comment