├── README.md └── pocket-to-wordpress.php /README.md: -------------------------------------------------------------------------------- 1 | # Pocket to Wordpress 2 | Working on a new WordPress plugin that will help you display your Pocket info on your WordPress site. WHen it's ready, I'll upload to the WordPress repository. 3 | 4 | This adventure into the Pocket API was inspired because I wanted to get all of my Pocket items that were tagged "reading" and display them as a reading list on my WordPress site. 5 | 6 | Kudos to [Rob Neu (@rob_neu)](https://twitter.com/rob_neu) for some helpful tweaks. 7 | 8 | You'll need a Pocket consumer key and access token in order to use their API. Visit https://getpocket.com/developer/ to register an app and get a key. 9 | 10 | You can then use https://github.com/jshawl/pocket-oauth-php to get your access token. 11 | 12 | If you don't mind trusting some random site, you can use http://reader.fxneumann.de/plugins/oneclickpocket/auth.php to get your access token a lot quicker. 13 | 14 | Then use the shortcode [pocket_items] or the function get_pocket_items_html() to display your pocket items. 15 | 16 | You can also use get_pocket_items() to retrieve the item data and display as you like. 17 | -------------------------------------------------------------------------------- /pocket-to-wordpress.php: -------------------------------------------------------------------------------- 1 | null, 77 | 'token' => null, 78 | 'tag' => NULL, 79 | 'store_items' => '7200' // Will cache the item for 2 hours by default. Set to false for no cache. 80 | ); 81 | extract( wp_parse_args( $args, $defaults ), EXTR_OVERWRITE ); 82 | 83 | // Build html 84 | $pocket_html = NULL; 85 | 86 | // Get the items 87 | $pocket_items = get_pocket_items( shortcode_atts( $defaults, $args ) ); 88 | 89 | // If we have no items 90 | if ( ! ( isset( $pocket_items ) && is_array( $pocket_items ) ) ) 91 | return NULL; 92 | 93 | // Start building the HTML 94 | $pocket_html .= '
'; 95 | 96 | // Loop through each item 97 | foreach( $pocket_items as $item ) { 98 | $pocket_html .= get_pocket_item_html( $item ); 99 | } 100 | 101 | $pocket_html .= '
'; 102 | 103 | return $pocket_html; 104 | 105 | } 106 | 107 | /** 108 | * Returns markup for individual pocket items. 109 | * 110 | * @access public 111 | * @param array - $item - the data for the item to be displayed 112 | * @return string - $pocket_html - the item's markup 113 | */ 114 | function get_pocket_item_html( $item ) { 115 | 116 | // Make sure the item is formatted 117 | if ( ! isset( $item->is_formatted ) ) 118 | $item = get_pocket_item_formatted_data( $item ); 119 | 120 | // Make sure we at least have an item ID and a title 121 | if ( ! ( isset( $item->item_id ) && isset( $item->title ) ) ) 122 | return null; 123 | 124 | // Start the item 125 | $pocket_html = '
'; 126 | 127 | // Add image 128 | $pocket_html .= $item->has_image && $item->image_src ? '
' : NULL; 129 | 130 | // Add the main stuff 131 | $pocket_html .= '
'; 132 | 133 | // Add the title 134 | $pocket_html .= '

'; 135 | 136 | // Add the URL 137 | if ( $item->url ) { 138 | $pocket_html .= '' . esc_html( $item->title ) . ''; 139 | } else { 140 | $pocket_html .= esc_html( $item->title ); 141 | } 142 | 143 | // Close the title 144 | $pocket_html .= '

'; 145 | 146 | // Add meta data 147 | $pocket_html .= '
'; 148 | 149 | // Show when it was added 150 | $pocket_html .= ! empty( $item->time_added ) ? '' . date( 'M\. j, Y', esc_attr( $item->time_added ) ) . '' : NULL; 151 | 152 | // Only add the first author 153 | if ( $item->authors ) { 154 | 155 | foreach( $item->authors as $author ) { 156 | 157 | if ( isset( $author[ 'name' ] ) ) { 158 | 159 | $pocket_html .= ''; 160 | 161 | // If we have a URL 162 | if ( isset( $author[ 'url' ] ) ) { 163 | $pocket_html .= '' . esc_html( $author[ 'name' ] ) . ''; 164 | } else { 165 | $pocket_html .= esc_html( $author[ 'name' ] ); 166 | } 167 | 168 | $pocket_html .= ''; 169 | 170 | break; 171 | 172 | } 173 | 174 | } 175 | 176 | } 177 | 178 | // Show the word count 179 | $pocket_html .= $item->word_count > 0 ? '' . $item->word_count . ' words' : NULL; 180 | 181 | $pocket_html .= '
'; 182 | 183 | $pocket_html .= '
'; 184 | 185 | // Add excerpt 186 | if ( isset( $item->excerpt ) && ! empty( $item->excerpt ) ) 187 | $pocket_html .= wpautop( $item->excerpt, false ); 188 | 189 | $pocket_html .= '
'; 190 | 191 | // Add tag list 192 | if ( isset( $item->tags ) && ! empty( $item->tags ) ) { 193 | 194 | // Start the list 195 | $pocket_html .= ''; 203 | 204 | } 205 | 206 | $pocket_html .= '
'; 207 | 208 | $pocket_html .= '
'; 209 | 210 | return $pocket_html; 211 | } 212 | 213 | /** 214 | * Inserts a Pocket item into a WordPress post. 215 | * 216 | * @access public 217 | * @param array - $item - the item which holds the data we need to format 218 | * @param array - $args - the arguments for creating the post 219 | * @return boolean - whether or not the post was created 220 | */ 221 | function insert_pocket_item_to_post( $item, $args = array() ) { 222 | global $wpdb; 223 | 224 | // Handle the arguments 225 | $defaults = array( 226 | 'post_type' => 'post', 227 | 'post_author' => null, 228 | 'post_status' => 'publish', 229 | 'tags_taxonomy_name'=> 'post_tag', 230 | ); 231 | $args = wp_parse_args( $args, $defaults ); 232 | 233 | // Make sure the item is formatted 234 | if ( ! isset( $item->is_formatted ) ) 235 | $item = get_pocket_item_formatted_data( $item ); 236 | 237 | // See if a post with this item ID already exists 238 | $current_post_id = $wpdb->get_var( "SELECT posts.ID FROM {$wpdb->postmeta} pmeta INNER JOIN {$wpdb->posts} posts ON posts.ID = pmeta.post_id and posts.post_type = '{$args['post_type']}' AND posts.post_status = 'publish' WHERE pmeta.meta_key = '_pocket_item_id' AND pmeta.meta_value = '{$item->item_id}'" ); 239 | 240 | // If it already exists, get out of here 241 | if ( $current_post_id > 0 ) 242 | return false; 243 | 244 | // Create the post args 245 | $post_args = array( 246 | 'post_type' => $args[ 'post_type' ], 247 | 'post_author' => $args[ 'post_author' ], 248 | 'post_status' => $args[ 'post_status' ], 249 | 'post_title' => apply_filters( 'pocket_item_post_title', $item->title, $item, $args ), 250 | 'post_name' => apply_filters( 'pocket_item_post_name', '', $item, $args ), 251 | 'post_content' => apply_filters( 'pocket_item_post_content', $item->excerpt, $item, $args ), 252 | ); 253 | 254 | // When was the post added? - They send GMT 255 | if ( isset( $item->time_added ) ) { 256 | $post_args[ 'post_date_gmt' ] = date( 'Y-m-d H:i:s', $item->time_added ); 257 | } 258 | 259 | // Filter the tags taxonomy name 260 | $tags_taxonomy_name = apply_filters( 'pocket_item_tags_taxonomy_name', $args[ 'tags_taxonomy_name' ], $item, $args ); 261 | 262 | // Store the tags 263 | if ( isset( $item->tags ) && is_array( $item->tags ) ) { 264 | 265 | // Build tags array 266 | $tags_array = array(); 267 | 268 | // Collect the tags 269 | foreach( $item->tags as $tag ) { 270 | $tags_array[] = $tag[ 'tag' ]; 271 | } 272 | 273 | // Add tags 274 | if ( ! empty( $tags_array ) ) { 275 | $post_args[ 'tax_input' ] = array( 276 | $tags_taxonomy_name => $tags_array, 277 | ); 278 | } 279 | 280 | } 281 | 282 | // Insert the post 283 | if ( $new_post_id = wp_insert_post( $post_args ) ) { 284 | 285 | // @TODO 286 | // Store authors separately? 287 | 288 | // Store item post meta 289 | $item_post_meta = array( 290 | '_pocket_item_id' => $item->item_id, 291 | '_pocket_item_url' => $item->url, 292 | '_pocket_item_word_count' => $item->word_count, 293 | '_pocket_item_time_read' => $item->time_read, 294 | '_pocket_item_is_article' => $item->is_article ? true : false, 295 | '_pocket_item_is_favorite' => $item->favorite ? true : false, 296 | '_pocket_item_has_video' => $item->has_video ? true : false, 297 | '_pocket_item_is_video' => $item->is_video ? true : false, 298 | '_pocket_item_has_image' => $item->has_image ? true : false, 299 | '_pocket_item_is_image' => $item->is_image ? true : false, 300 | '_pocket_item_image_src' => $item->image_src, 301 | '_pocket_item_data' => $item, 302 | ); 303 | 304 | foreach( $item_post_meta as $meta_key => $meta_value ) { 305 | add_post_meta( $new_post_id, $meta_key, $meta_value, true ); 306 | } 307 | 308 | return true; 309 | 310 | } 311 | 312 | return false; 313 | } 314 | 315 | /** 316 | * Returns a formatted array of data about a given Pocket item. 317 | * 318 | * @access public 319 | * @param array - $item - the item which holds the data we need to format 320 | * @return array - $data - the item's data attributes 321 | */ 322 | function get_pocket_item_formatted_data( $item ) { 323 | 324 | // Convert to object 325 | $item = (object) $item; 326 | 327 | // Create the data 328 | $data = (object) array( 329 | 'item_id' => ! empty( $item->item_id ) ? $item->item_id : null, 330 | 'resolved_id' => ! empty( $item->resolved_id ) ? $item->resolved_id : null, 331 | 'url' => ! empty( $item->given_url ) ? $item->given_url : null, 332 | 'resolved_url' => ! empty( $item->resolved_url ) ? $item->resolved_url : null, 333 | 'title' => ! empty( $item->given_title ) ? $item->given_title : null, 334 | 'resolved_title'=> ! empty( $item->resolved_title ) ? $item->resolved_title : null, 335 | 'time_added' => ! empty( $item->time_added ) ? $item->time_added : false, 336 | 'time_updated' => ! empty( $item->time_updated ) ? $item->time_updated : false, 337 | 'time_read' => ! empty( $item->time_read ) ? $item->time_read : false, 338 | 'time_favorited'=> ! empty( $item->time_favorited ) ? $item->time_favorited : false, 339 | 'favorite' => ! empty( $item->favorite ) ? $item->favorite : null, 340 | 'status' => ! empty( $item->status ) ? $item->status : null, 341 | 'word_count' => ! empty( $item->word_count ) ? $item->word_count : false, 342 | 'authors' => ! empty( $item->authors ) ? $item->authors : false, 343 | 'is_article' => ! empty( $item->is_article ) ? $item->is_article : false, 344 | 'has_video' => ! empty( $item->has_video ) ? $item->has_video : false, 345 | 'is_video' => ! empty( $item->has_video ) && 2 == $item->has_video ? true : false, 346 | 'has_image' => ! empty( $item->has_image ) ? $item->has_image : false, 347 | 'is_image' => ! empty( $item->has_image ) && 2 == $item->has_image ? true : false, 348 | 'excerpt' => ! empty( $item->excerpt ) ? $item->excerpt : null, 349 | 'tags' => ! empty( $item->tags ) ? $item->tags : false, 350 | 'image_src' => false, 351 | 'images' => false, 352 | 'is_formatted' => true, 353 | ); 354 | 355 | // Make sure we have a title 356 | if ( empty( $data->title ) ) { 357 | if ( isset( $data->url ) ) { 358 | $data->title = $data->url; 359 | } else if ( isset( $data->resolved_url ) ) { 360 | $data->title = $data->resolved_url; 361 | } 362 | } 363 | 364 | // If we has_image, get the image src 365 | if ( $data->has_image && ! empty( $item->image['src'] ) ) { 366 | 367 | // Store image src 368 | $data->image_src = $item->image[ 'src' ]; 369 | 370 | // Store images 371 | if ( ! empty( $item->images ) ) 372 | $data->images = $item->images; 373 | } 374 | 375 | return $data; 376 | } 377 | 378 | /** 379 | * Get Pocket items using Pocket's API. 380 | * 381 | * @TODO: Get your Pocket authentication info. 382 | * 383 | * You'll need a Pocket consumer key and access token 384 | * in order to use their API. Visit https://getpocket.com/developer/ 385 | * to register an app and get a key. 386 | * 387 | * You can then use https://github.com/jshawl/pocket-oauth-php 388 | * to get your access token. 389 | * 390 | * You can get more info in their docs: https://getpocket.com/developer/docs/authentication 391 | * 392 | * @access public 393 | * @param $args - array - arguments to be passed to the API 394 | * @return array - the items, false if something went wrong 395 | */ 396 | function get_pocket_items( $args = array() ) { 397 | 398 | // Handle the arguments 399 | $defaults = array( 400 | 'key' => null, 401 | 'token' => null, 402 | 'tag' => NULL, // Pass a tag to get category-specific Pocket items. It seems they only allow one tag at a time. 403 | 'count' => 10, 404 | 'store_items' => '7200' // Will cache the item for 2 hours by default. Set to false for no cache. 405 | ); 406 | $args = wp_parse_args( $args, $defaults ); 407 | 408 | // Bail if we don't have the required access token and consumer key data. 409 | if ( ! isset( $args[ 'key' ], $args[ 'token' ] ) ) { 410 | return false; 411 | } 412 | 413 | // Build request args 414 | $pocket_request_args = array( 415 | 'consumer_key' => $args[ 'key' ], 416 | 'access_token' => $args[ 'token' ], 417 | 'tag' => $args[ 'tag' ], 418 | 'detailType' => 'complete', 419 | 'state' => 'all', 420 | 'count' => $args[ 'count' ], 421 | ); 422 | 423 | // If we're set to store the items... 424 | if ( $args[ 'store_items' ] !== false && $args[ 'store_items' ] > 0 ) { 425 | 426 | // See if we have data in our transient data and that it matches our args 427 | $pocket_transient_name = 'my_pocket_reading_list'; 428 | $pocket_transient_args_name = 'my_pocket_reading_list_args'; 429 | 430 | // If we have cached Pocket items... 431 | if ( ( $transient_pocket_items = get_transient( $pocket_transient_name ) ) 432 | && $transient_pocket_items !== false ) { 433 | 434 | // Check the args to see if they match... 435 | if ( ( $transient_pocket_item_args = get_transient( $pocket_transient_args_name ) ) 436 | && $transient_pocket_item_args == $pocket_request_args ) { 437 | 438 | // Return the cached Pocket items 439 | return $transient_pocket_items; 440 | 441 | } 442 | 443 | } 444 | 445 | } 446 | 447 | // Make our Pocket request 448 | $pocket_request = get_pocket_response( 'https://getpocket.com/v3/get', $pocket_request_args ); 449 | 450 | // Bail if something went wrong with the request. 451 | if ( ! $pocket_request || empty( $pocket_request['list'] ) ) { 452 | return false; 453 | } 454 | 455 | // If we're set to store items, store the data and args for the set transient time 456 | if ( $args[ 'store_items' ] !== false && $args[ 'store_items' ] > 0 ) { 457 | 458 | set_transient( $pocket_transient_name, $pocket_request[ 'list' ], $args[ 'store_items' ] ); 459 | set_transient( $pocket_transient_args_name, $pocket_request_args, $args[ 'store_items' ] ); 460 | 461 | } 462 | 463 | // Return the items 464 | return $pocket_request[ 'list' ]; 465 | } 466 | 467 | /** 468 | * Get a response from the Pocket API. 469 | * 470 | * @access public 471 | * @param $url - string - the API endpoint URL 472 | * @param $post - array - data to be passed to the API 473 | * @return mixed false if there's an error, otherwise an array of API data 474 | */ 475 | function get_pocket_response( $url, $post ) { 476 | 477 | // Get the response 478 | $response = wp_safe_remote_post( $url, array( 'body' => $post ) ); 479 | 480 | // Check for an error 481 | if ( is_wp_error( $response ) ) { 482 | return false; 483 | } 484 | 485 | // Return the response 486 | return json_decode( wp_remote_retrieve_body( $response ), true ); 487 | } --------------------------------------------------------------------------------