Jetpack_Sitemap_Librarian

This object handles any database interaction required for sitemap generation.

Defined (1)

The class is defined in the following location(s).

/modules/sitemaps/sitemap-librarian.php  
  1. class Jetpack_Sitemap_Librarian { 
  2.  
  3. /** 
  4. * Retrieve a single sitemap with given name and type. 
  5. * Returns null if no such sitemap exists. 
  6. * @access public 
  7. * @since 4.8.0 
  8. * @param string $name Name of the sitemap to be retrieved. 
  9. * @param string $type Type of the sitemap to be retrieved. 
  10. * @return array $args { 
  11. * @type int $id ID number of the sitemap in the database. 
  12. * @type string $timestamp Most recent timestamp of the resources pointed to. 
  13. * @type string $name Name of the sitemap in the database. 
  14. * @type string $type Type of the sitemap in the database. 
  15. * @type string $text The content of the sitemap. 
  16. * } 
  17. */ 
  18. public function read_sitemap_data( $name, $type ) { 
  19. $the_post = get_page_by_title( $name, 'OBJECT', $type ); 
  20.  
  21. if ( null === $the_post ) { 
  22. return null; 
  23. } else { 
  24. return array( 
  25. 'id' => $the_post->ID,  
  26. 'timestamp' => $the_post->post_date,  
  27. 'name' => $the_post->post_title,  
  28. 'type' => $the_post->post_type,  
  29. 'text' => $the_post->post_content,  
  30. ); 
  31.  
  32. /** 
  33. * Store a sitemap of given type and index in the database. 
  34. * Note that the sitemap contents are run through esc_html before 
  35. * being stored, and the timestamp reencoded as 'Y-m-d H:i:s'. 
  36. * If a sitemap with that type and name does not exist, create it. 
  37. * If a sitemap with that type and name does exist, update it. 
  38. * @access public 
  39. * @since 4.8.0 
  40. * @param string $index Index of the sitemap to be stored. 
  41. * @param string $type Type of the sitemap to be stored. 
  42. * @param string $contents Contents of the sitemap to be stored. 
  43. * @param string $timestamp Timestamp of the sitemap to be stored, in 'YYYY-MM-DD hh:mm:ss' format. 
  44. */ 
  45. public function store_sitemap_data( $index, $type, $contents, $timestamp ) { 
  46. $name = jp_sitemap_filename( $type, $index ); 
  47.  
  48. $the_post = get_page_by_title( $name, 'OBJECT', $type ); 
  49.  
  50. if ( null === $the_post ) { 
  51. // Post does not exist. 
  52. wp_insert_post(array( 
  53. 'post_title' => $name,  
  54. 'post_content' => esc_html( $contents ),  
  55. 'post_type' => $type,  
  56. 'post_date' => date( 'Y-m-d H:i:s', strtotime( $timestamp ) ),  
  57. )); 
  58. } else { 
  59. // Post does exist. 
  60. wp_insert_post(array( 
  61. 'ID' => $the_post->ID,  
  62. 'post_title' => $name,  
  63. 'post_content' => esc_html( $contents ),  
  64. 'post_type' => $type,  
  65. 'post_date' => date( 'Y-m-d H:i:s', strtotime( $timestamp ) ),  
  66. )); 
  67. return; 
  68.  
  69. /** 
  70. * Delete a sitemap by name and type. 
  71. * @access public 
  72. * @since 4.8.0 
  73. * @param string $name Row name. 
  74. * @param string $type Row type. 
  75. * @return bool 'true' if a row was deleted, 'false' otherwise. 
  76. */ 
  77. public function delete_sitemap_data( $name, $type ) { 
  78. $the_post = get_page_by_title( $name, 'OBJECT', $type ); 
  79.  
  80. if ( null === $the_post ) { 
  81. return false; 
  82. } else { 
  83. wp_delete_post( $the_post->ID ); 
  84. return true; 
  85.  
  86. /** 
  87. * Retrieve the contents of a sitemap with given name and type. 
  88. * If no such sitemap exists, return the empty string. Note that the 
  89. * returned string is run through wp_specialchars_decode. 
  90. * @access public 
  91. * @since 4.8.0 
  92. * @param string $name Row name. 
  93. * @param string $type Row type. 
  94. * @return string Text of the specified sitemap, or the empty string. 
  95. */ 
  96. public function get_sitemap_text( $name, $type ) { 
  97. $row = $this->read_sitemap_data( $name, $type ); 
  98.  
  99. if ( null === $row ) { 
  100. return ''; 
  101. } else { 
  102. return wp_specialchars_decode( $row['text'], ENT_QUOTES ); 
  103.  
  104. /** 
  105. * Delete numbered sitemaps named prefix-(p+1), prefix-(p+2), ... 
  106. * until the first nonexistent sitemap is found. 
  107. * @access public 
  108. * @since 4.8.0 
  109. * @param int $position Number before the first sitemap to be deleted. 
  110. * @param string $type Sitemap type. 
  111. */ 
  112. public function delete_numbered_sitemap_rows_after( $position, $type ) { 
  113. $any_left = true; 
  114.  
  115. while ( true === $any_left ) { 
  116. $position += 1; 
  117. $name = jp_sitemap_filename( $type, $position ); 
  118. $any_left = $this->delete_sitemap_data( $name, $type ); 
  119.  
  120. return; 
  121.  
  122. /** 
  123. * Deletes all stored sitemap data. 
  124. * @access public 
  125. * @since 4.8.0 
  126. */ 
  127. public function delete_all_stored_sitemap_data() { 
  128. $this->delete_sitemap_data( 
  129. jp_sitemap_filename( JP_MASTER_SITEMAP_TYPE ),  
  130. JP_MASTER_SITEMAP_TYPE 
  131. ); 
  132.  
  133. $this->delete_numbered_sitemap_rows_after( 
  134. 0, JP_PAGE_SITEMAP_TYPE 
  135. ); 
  136.  
  137. $this->delete_numbered_sitemap_rows_after( 
  138. 0, JP_PAGE_SITEMAP_INDEX_TYPE 
  139. ); 
  140.  
  141. $this->delete_numbered_sitemap_rows_after( 
  142. 0, JP_IMAGE_SITEMAP_TYPE 
  143. ); 
  144.  
  145. $this->delete_numbered_sitemap_rows_after( 
  146. 0, JP_IMAGE_SITEMAP_INDEX_TYPE 
  147. ); 
  148.  
  149. $this->delete_numbered_sitemap_rows_after( 
  150. 0, JP_VIDEO_SITEMAP_TYPE 
  151. ); 
  152.  
  153. $this->delete_numbered_sitemap_rows_after( 
  154. 0, JP_VIDEO_SITEMAP_INDEX_TYPE 
  155. ); 
  156. return; 
  157.  
  158. /** 
  159. * Retrieve an array of sitemap rows (of a given type) sorted by ID. 
  160. * Returns the smallest $num_posts sitemap rows (measured by ID) 
  161. * of the given type which are larger than $from_id. 
  162. * @access public 
  163. * @since 4.8.0 
  164. * @param string $type Type of the sitemap rows to retrieve. 
  165. * @param int $from_id Greatest lower bound of retrieved sitemap post IDs. 
  166. * @param int $num_posts Largest number of sitemap posts to retrieve. 
  167. * @return array The sitemaps, as an array of associative arrays. 
  168. */ 
  169. public function query_sitemaps_after_id( $type, $from_id, $num_posts ) { 
  170. global $wpdb; 
  171.  
  172. return $wpdb->get_results( 
  173. $wpdb->prepare( 
  174. "SELECT * 
  175. FROM $wpdb->posts 
  176. WHERE post_type=%s 
  177. AND ID>%d 
  178. ORDER BY ID ASC 
  179. LIMIT %d;",  
  180. $type,  
  181. $from_id,  
  182. $num_posts 
  183. ),  
  184. ARRAY_A 
  185. ); // WPCS: db call ok; no-cache ok. 
  186.  
  187. /** 
  188. * Retrieve an array of posts sorted by ID. 
  189. * More precisely, returns the smallest $num_posts posts 
  190. * (measured by ID) which are larger than $from_id. 
  191. * @access public 
  192. * @since 4.8.0 
  193. * @param int $from_id Greatest lower bound of retrieved post IDs. 
  194. * @param int $num_posts Largest number of posts to retrieve. 
  195. * @return array The posts. 
  196. */ 
  197. public function query_posts_after_id( $from_id, $num_posts ) { 
  198. global $wpdb; 
  199.  
  200. // Get the list of post types to include and prepare for query. 
  201. $post_types = Jetpack_Options::get_option_and_ensure_autoload( 
  202. 'jetpack_sitemap_post_types',  
  203. array( 'page', 'post' ) 
  204. ); 
  205. foreach ( (array) $post_types as $i => $post_type ) { 
  206. $post_types[ $i ] = $wpdb->prepare( '%s', $post_type ); 
  207. $post_types_list = join( ', ', $post_types ); 
  208.  
  209. return $wpdb->get_results( 
  210. $wpdb->prepare( 
  211. "SELECT * 
  212. FROM $wpdb->posts 
  213. WHERE post_status='publish' 
  214. AND post_type IN ($post_types_list) 
  215. AND ID>%d 
  216. ORDER BY ID ASC 
  217. LIMIT %d;",  
  218. $from_id,  
  219. $num_posts 
  220. ); // WPCS: db call ok; no-cache ok. 
  221.  
  222. /** 
  223. * Get the most recent timestamp among approved comments for the given post_id. 
  224. * @access public 
  225. * @since 4.8.0 
  226. * @param int $post_id Post identifier. 
  227. * @return int Timestamp in 'Y-m-d h:i:s' format (UTC) of the most recent comment on the given post, or null if no such comments exist. 
  228. */ 
  229. public function query_latest_approved_comment_time_on_post( $post_id ) { 
  230. global $wpdb; 
  231.  
  232. return $wpdb->get_var( 
  233. $wpdb->prepare( 
  234. "SELECT MAX(comment_date_gmt) 
  235. FROM $wpdb->comments 
  236. WHERE comment_post_ID = %d AND comment_approved = '1' AND comment_type=''",  
  237. $post_id 
  238. ); 
  239.  
  240. /** 
  241. * Retrieve an array of image posts sorted by ID. 
  242. * More precisely, returns the smallest $num_posts image posts 
  243. * (measured by ID) which are larger than $from_id. 
  244. * @access public 
  245. * @since 4.8.0 
  246. * @param int $from_id Greatest lower bound of retrieved image post IDs. 
  247. * @param int $num_posts Largest number of image posts to retrieve. 
  248. * @return array The posts. 
  249. */ 
  250. public function query_images_after_id( $from_id, $num_posts ) { 
  251. global $wpdb; 
  252.  
  253. return $wpdb->get_results( 
  254. $wpdb->prepare( 
  255. "SELECT * 
  256. FROM $wpdb->posts 
  257. WHERE post_type='attachment' 
  258. AND post_mime_type IN ('image/jpeg', 'image/png', 'image/gif') 
  259. AND ID>%d 
  260. ORDER BY ID ASC 
  261. LIMIT %d;",  
  262. $from_id,  
  263. $num_posts 
  264. ); // WPCS: db call ok; no-cache ok. 
  265.  
  266. /** 
  267. * Retrieve an array of video posts sorted by ID. 
  268. * More precisely, returns the smallest $num_posts video posts 
  269. * (measured by ID) which are larger than $from_id. 
  270. * @access public 
  271. * @since 4.8.0 
  272. * @param int $from_id Greatest lower bound of retrieved video post IDs. 
  273. * @param int $num_posts Largest number of video posts to retrieve. 
  274. * @return array The posts. 
  275. */ 
  276. public function query_videos_after_id( $from_id, $num_posts ) { 
  277. global $wpdb; 
  278.  
  279. return $wpdb->get_results( 
  280. $wpdb->prepare( 
  281. "SELECT * 
  282. FROM $wpdb->posts 
  283. WHERE post_type='attachment' 
  284. AND post_mime_type IN ('video/mpeg', 'video/wmv', 'video/mov', 'video/avi', 'video/ogg') 
  285. AND ID>%d 
  286. ORDER BY ID ASC 
  287. LIMIT %d;",  
  288. $from_id,  
  289. $num_posts 
  290. ); // WPCS: db call ok; no-cache ok. 
  291.  
  292. /** 
  293. * Retrieve an array of published posts from the last 2 days. 
  294. * @access public 
  295. * @since 4.8.0 
  296. * @param int $num_posts Largest number of posts to retrieve. 
  297. * @return array The posts. 
  298. */ 
  299. public function query_most_recent_posts( $num_posts ) { 
  300. global $wpdb; 
  301.  
  302. $two_days_ago = date( 'Y-m-d', strtotime( '-2 days' ) ); 
  303.  
  304. /** 
  305. * Filter post types to be included in news sitemap. 
  306. * @module sitemaps 
  307. * @since 3.9.0 
  308. * @param array $post_types Array with post types to include in news sitemap. 
  309. */ 
  310. $post_types = apply_filters( 
  311. 'jetpack_sitemap_news_sitemap_post_types',  
  312. array( 'page', 'post' ) 
  313. ); 
  314.  
  315. foreach ( (array) $post_types as $i => $post_type ) { 
  316. $post_types[ $i ] = $wpdb->prepare( '%s', $post_type ); 
  317.  
  318. $post_types_list = join( ', ', $post_types ); 
  319.  
  320. return $wpdb->get_results( 
  321. $wpdb->prepare( 
  322. "SELECT * 
  323. FROM $wpdb->posts 
  324. WHERE post_status='publish' 
  325. AND post_date >= '%s' 
  326. AND post_type IN ($post_types_list) 
  327. ORDER BY post_date DESC 
  328. LIMIT %d;",  
  329. $two_days_ago,  
  330. $num_posts 
  331. ); // WPCS: db call ok; no-cache ok. 
  332.