class.json-api-post-base.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  1. <?php
  2. /**
  3. * This class wraps a WP_Post and proxies any undefined attributes
  4. * and methods to the wrapped class. We need to do this because at present
  5. * the WP_Post class is marked as final (in 4.5 this will change, though it's
  6. * not clear if there will be a mechanism to retrieve from the DB into the over-
  7. * ridden class dynamically).
  8. **/
  9. require_once dirname( __FILE__ ) . '/class.json-api-metadata.php';
  10. require_once dirname( __FILE__ ) . '/class.json-api-date.php';
  11. require_once ( ABSPATH . "wp-includes/post.php" );
  12. abstract class SAL_Post {
  13. public $post;
  14. public $context;
  15. public $site;
  16. function __construct( $site, $post, $context ) {
  17. $this->post = $post;
  18. $this->context = $context;
  19. $this->site = $site;
  20. }
  21. public function __set( $key, $value ) {
  22. $this->post->{ $key } = $value;
  23. }
  24. public function __get( $key ) {
  25. if ( $key === 'links' ) {
  26. require_once dirname( __FILE__ ) . '/class.json-api-links.php';
  27. return WPCOM_JSON_API_Links::getInstance();
  28. }
  29. return $this->post->{ $key };
  30. }
  31. public function __call( $name, $arguments ) {
  32. if ( is_callable( array( $this->post, $name ) ) ) {
  33. return call_user_func_array( array( $this->post, $name ), $arguments );
  34. } else {
  35. trigger_error("Call to undefined method '{$name}'");
  36. }
  37. }
  38. public function __isset ( $name ) {
  39. return isset( $this->post->{ $name } );
  40. }
  41. abstract public function get_like_count();
  42. abstract public function is_liked();
  43. abstract public function is_reblogged();
  44. abstract public function is_following();
  45. abstract public function get_global_id();
  46. abstract public function get_geo();
  47. public function get_menu_order() {
  48. return (int) $this->post->menu_order;
  49. }
  50. public function get_guid() {
  51. return (string) $this->post->guid;
  52. }
  53. public function get_type() {
  54. return (string) $this->post->post_type;
  55. }
  56. public function get_terms() {
  57. $taxonomies = get_object_taxonomies( $this->post, 'objects' );
  58. $terms = array();
  59. foreach ( $taxonomies as $taxonomy ) {
  60. if ( ! $taxonomy->public && ! current_user_can( $taxonomy->cap->assign_terms ) ) {
  61. continue;
  62. }
  63. $terms[ $taxonomy->name ] = array();
  64. $taxonomy_terms = wp_get_object_terms( $this->post->ID, $taxonomy->name, array( 'fields' => 'all' ) );
  65. foreach ( $taxonomy_terms as $term ) {
  66. $formatted_term = $this->format_taxonomy( $term, $taxonomy->name, 'display' );
  67. $terms[ $taxonomy->name ][ $term->name ] = $formatted_term;
  68. }
  69. $terms[ $taxonomy->name ] = (object) $terms[ $taxonomy->name ];
  70. }
  71. return (object) $terms;
  72. }
  73. public function get_tags() {
  74. $tags = array();
  75. $terms = wp_get_post_tags( $this->post->ID );
  76. foreach ( $terms as $term ) {
  77. if ( !empty( $term->name ) ) {
  78. $tags[$term->name] = $this->format_taxonomy( $term, 'post_tag', 'display' );
  79. }
  80. }
  81. return (object) $tags;
  82. }
  83. public function get_categories() {
  84. $categories = array();
  85. $terms = wp_get_object_terms( $this->post->ID, 'category', array( 'fields' => 'all' ) );
  86. foreach ( $terms as $term ) {
  87. if ( !empty( $term->name ) ) {
  88. $categories[$term->name] = $this->format_taxonomy( $term, 'category', 'display' );
  89. }
  90. }
  91. return (object) $categories;
  92. }
  93. public function get_attachments_and_count() {
  94. $attachments = array();
  95. $_attachments = new WP_Query( array( 'post_parent' => $this->post->ID, 'post_status' => 'inherit', 'post_type' => 'attachment', 'posts_per_page' => '20' ) );
  96. foreach ( $_attachments->posts as $attachment ) {
  97. $attachments[$attachment->ID] = $this->get_media_item_v1_1( $attachment->ID );
  98. }
  99. return array( (object) $attachments, (int) $_attachments->found_posts );
  100. }
  101. public function get_metadata() {
  102. $metadata = array();
  103. foreach ( (array) has_meta( $this->post->ID ) as $meta ) {
  104. // Don't expose protected fields.
  105. $meta_key = $meta['meta_key'];
  106. $show = !( WPCOM_JSON_API_Metadata::is_internal_only( $meta_key ) )
  107. &&
  108. (
  109. WPCOM_JSON_API_Metadata::is_public( $meta_key )
  110. ||
  111. current_user_can( 'edit_post_meta', $this->post->ID , $meta_key )
  112. );
  113. // Only business plan subscribers can view custom meta description
  114. if ( Jetpack_SEO_Posts::DESCRIPTION_META_KEY == $meta_key && ! Jetpack_SEO_Utils::is_enabled_jetpack_seo() ) {
  115. $show = false;
  116. }
  117. if ( $show ) {
  118. $metadata[] = array(
  119. 'id' => $meta['meta_id'],
  120. 'key' => $meta['meta_key'],
  121. 'value' => maybe_unserialize( $meta['meta_value'] ),
  122. );
  123. }
  124. }
  125. if ( ! empty( $metadata ) ) {
  126. return $metadata;
  127. } else {
  128. return false;
  129. }
  130. }
  131. public function get_meta() {
  132. $meta = (object) array(
  133. 'links' => (object) array(
  134. 'self' => (string) $this->get_post_link(),
  135. 'help' => (string) $this->get_post_link( 'help' ),
  136. 'site' => (string) $this->get_site_link(),
  137. 'replies' => (string) $this->get_post_link( 'replies/' ),
  138. 'likes' => (string) $this->get_post_link( 'likes/' ),
  139. ),
  140. );
  141. $amp_permalink = get_post_meta( $this->post->ID, '_jetpack_amp_permalink', true );
  142. if ( ! empty( $amp_permalink ) ) {
  143. $meta->links->amp = (string) $amp_permalink;
  144. }
  145. // add autosave link if a more recent autosave exists
  146. if ( 'edit' === $this->context ) {
  147. $autosave = wp_get_post_autosave( $this->post->ID );
  148. if ( $autosave && $autosave->post_modified > $this->post->post_modified )
  149. $meta->links->autosave = (string) $this->get_post_link() . '/autosave';
  150. }
  151. return $meta;
  152. }
  153. public function get_current_user_capabilities() {
  154. return array(
  155. 'publish_post' => current_user_can( 'publish_post', $this->post ),
  156. 'delete_post' => current_user_can( 'delete_post', $this->post ),
  157. 'edit_post' => current_user_can( 'edit_post', $this->post )
  158. );
  159. }
  160. public function get_revisions() {
  161. if ( 'edit' !== $this->context ) {
  162. return false;
  163. }
  164. $revisions = array();
  165. $post_revisions = wp_get_post_revisions( $this->post->ID );
  166. foreach ( $post_revisions as $_post ) {
  167. $revisions[] = $_post->ID;
  168. }
  169. return $revisions;
  170. }
  171. public function get_other_urls() {
  172. $other_urls = array();
  173. if ( 'publish' !== $this->post->post_status ) {
  174. $other_urls = $this->get_permalink_suggestions( $this->post->post_title );
  175. }
  176. return (object) $other_urls;
  177. }
  178. protected function get_site_link() {
  179. return $this->links->get_site_link( $this->site->get_id() );
  180. }
  181. protected function get_post_link( $path = null ) {
  182. return $this->links->get_post_link( $this->site->get_id(), $this->post->ID, $path );
  183. }
  184. public function get_publicize_urls() {
  185. $publicize_URLs = array();
  186. $publicize = get_post_meta( $this->post->ID, 'publicize_results', true );
  187. if ( $publicize ) {
  188. foreach ( $publicize as $service => $data ) {
  189. switch ( $service ) {
  190. case 'twitter' :
  191. foreach ( $data as $datum ) {
  192. $publicize_URLs[] = esc_url_raw( "https://twitter.com/{$datum['user_id']}/status/{$datum['post_id']}" );
  193. }
  194. break;
  195. case 'fb' :
  196. foreach ( $data as $datum ) {
  197. $publicize_URLs[] = esc_url_raw( "https://www.facebook.com/permalink.php?story_fbid={$datum['post_id']}&id={$datum['user_id']}" );
  198. }
  199. break;
  200. }
  201. }
  202. }
  203. return (array) $publicize_URLs;
  204. }
  205. public function get_page_template() {
  206. return (string) get_post_meta( $this->post->ID, '_wp_page_template', true );
  207. }
  208. // note this is overridden in jetpack-shadow
  209. public function get_featured_image() {
  210. $image_attributes = wp_get_attachment_image_src( get_post_thumbnail_id( $this->post->ID ), 'full' );
  211. if ( is_array( $image_attributes ) && isset( $image_attributes[0] ) ) {
  212. return (string) $image_attributes[0];
  213. } else {
  214. return '';
  215. }
  216. }
  217. public function get_post_thumbnail() {
  218. $thumb = null;
  219. $thumb_id = get_post_thumbnail_id( $this->post->ID );
  220. if ( ! empty( $thumb_id ) ) {
  221. $attachment = get_post( $thumb_id );
  222. if ( ! empty( $attachment ) )
  223. $featured_image_object = $this->get_attachment( $attachment );
  224. if ( ! empty( $featured_image_object ) ) {
  225. $thumb = (object) $featured_image_object;
  226. }
  227. }
  228. return $thumb;
  229. }
  230. public function get_format() {
  231. $format = (string) get_post_format( $this->post->ID );
  232. if ( !$format ) {
  233. $format = 'standard';
  234. }
  235. return $format;
  236. }
  237. private function get_attachment( $attachment ) {
  238. $metadata = wp_get_attachment_metadata( $attachment->ID );
  239. $result = array(
  240. 'ID' => (int) $attachment->ID,
  241. 'URL' => (string) wp_get_attachment_url( $attachment->ID ),
  242. 'guid' => (string) $attachment->guid,
  243. 'mime_type' => (string) $attachment->post_mime_type,
  244. 'width' => (int) isset( $metadata['width'] ) ? $metadata['width'] : 0,
  245. 'height' => (int) isset( $metadata['height'] ) ? $metadata['height'] : 0,
  246. );
  247. if ( isset( $metadata['duration'] ) ) {
  248. $result['duration'] = (int) $metadata['duration'];
  249. }
  250. /** This filter is documented in class.jetpack-sync.php */
  251. return (object) apply_filters( 'get_attachment', $result );
  252. }
  253. public function get_date() {
  254. return (string) WPCOM_JSON_API_Date::format_date( $this->post->post_date_gmt, $this->post->post_date );
  255. }
  256. public function get_modified_date() {
  257. return (string) WPCOM_JSON_API_Date::format_date( $this->post->post_modified_gmt, $this->post->post_modified );
  258. }
  259. public function get_title() {
  260. if ( 'display' === $this->context ) {
  261. return (string) get_the_title( $this->post->ID );
  262. } else {
  263. return (string) htmlspecialchars_decode( $this->post->post_title, ENT_QUOTES );
  264. }
  265. }
  266. public function get_url() {
  267. if ( 'revision' === $this->post->post_type ) {
  268. return (string) esc_url_raw( get_permalink( $this->post->post_parent ) );
  269. } else {
  270. return (string) esc_url_raw( get_permalink( $this->post->ID ) );
  271. }
  272. }
  273. public function get_shortlink() {
  274. return (string) esc_url_raw( wp_get_shortlink( $this->post->ID ) );
  275. }
  276. public function get_content() {
  277. if ( 'display' === $this->context ) {
  278. // TODO: move this WPCOM-specific hack
  279. add_filter( 'the_password_form', array( $this, 'the_password_form' ) );
  280. $content = (string) $this->get_the_post_content_for_display();
  281. remove_filter( 'the_password_form', array( $this, 'the_password_form' ) );
  282. return $content;
  283. } else {
  284. return (string) $this->post->post_content;
  285. }
  286. }
  287. public function get_excerpt() {
  288. if ( 'display' === $this->context ) {
  289. add_filter( 'the_password_form', array( $this, 'the_password_form' ) );
  290. ob_start();
  291. the_excerpt();
  292. $response = (string) ob_get_clean();
  293. remove_filter( 'the_password_form', array( $this, 'the_password_form' ) );
  294. } else {
  295. $response = htmlspecialchars_decode( (string) $this->post->post_excerpt, ENT_QUOTES );
  296. }
  297. return $response;
  298. }
  299. public function get_status() {
  300. return (string) get_post_status( $this->post->ID );
  301. }
  302. public function is_sticky() {
  303. return (bool) is_sticky( $this->post->ID );
  304. }
  305. public function get_slug() {
  306. return (string) $this->post->post_name;
  307. }
  308. public function get_password() {
  309. $password = (string) $this->post->post_password;
  310. if ( 'edit' === $this->context ) {
  311. $password = htmlspecialchars_decode( (string) $password, ENT_QUOTES );
  312. }
  313. return $password;
  314. }
  315. public function get_parent() {
  316. if ( $this->post->post_parent ) {
  317. $parent = get_post( $this->post->post_parent );
  318. if ( 'display' === $this->context ) {
  319. $parent_title = (string) get_the_title( $parent->ID );
  320. } else {
  321. $parent_title = (string) htmlspecialchars_decode( $this->post->post_title, ENT_QUOTES );
  322. }
  323. return (object) array(
  324. 'ID' => (int) $parent->ID,
  325. 'type' => (string) $parent->post_type,
  326. 'link' => (string) $this->links->get_post_link( $this->site->get_id(), $parent->ID ),
  327. 'title' => $parent_title,
  328. );
  329. } else {
  330. return false;
  331. }
  332. }
  333. function the_password_form() {
  334. return __( 'This post is password protected.', 'jetpack' );
  335. }
  336. public function get_discussion() {
  337. return array(
  338. 'comments_open' => (bool) comments_open( $this->post->ID ),
  339. 'comment_status' => (string) $this->post->comment_status,
  340. 'pings_open' => (bool) pings_open( $this->post->ID ),
  341. 'ping_status' => (string) $this->post->ping_status,
  342. 'comment_count' => (int) $this->post->comment_count,
  343. );
  344. }
  345. public function is_likes_enabled() {
  346. /** This filter is documented in modules/likes.php */
  347. $sitewide_likes_enabled = (bool) apply_filters( 'wpl_is_enabled_sitewide', ! get_option( 'disabled_likes' ) );
  348. $post_likes_switched = (bool) get_post_meta( $this->post->ID, 'switch_like_status', true );
  349. $post_likes_enabled = $sitewide_likes_enabled;
  350. if ( $post_likes_switched ) {
  351. $post_likes_enabled = ! $post_likes_enabled;
  352. }
  353. return (bool) $post_likes_enabled;
  354. }
  355. public function is_sharing_enabled() {
  356. $show = true;
  357. /** This filter is documented in modules/sharedaddy/sharing-service.php */
  358. $show = apply_filters( 'sharing_show', $show, $this->post );
  359. $switched_status = get_post_meta( $this->post->ID, 'sharing_disabled', false );
  360. if ( !empty( $switched_status ) )
  361. $show = false;
  362. return (bool) $show;
  363. }
  364. // No Blog ID parameter. No Post ID parameter. Depends on globals.
  365. // Expects setup_postdata() to already have been run
  366. function get_the_post_content_for_display() {
  367. global $pages, $page;
  368. $old_pages = $pages;
  369. $old_page = $page;
  370. $content = join( "\n\n", $pages );
  371. $content = preg_replace( '/<!--more(.*?)?-->/', '', $content );
  372. $pages = array( $content );
  373. $page = 1;
  374. ob_start();
  375. the_content();
  376. $return = ob_get_clean();
  377. $pages = $old_pages;
  378. $page = $old_page;
  379. return $return;
  380. }
  381. public function get_author() {
  382. if ( 0 == $this->post->post_author )
  383. return null;
  384. $show_email = $this->context === 'edit' && current_user_can( 'edit_post', $this->post );
  385. $user = get_user_by( 'id', $this->post->post_author );
  386. if ( ! $user || is_wp_error( $user ) ) {
  387. trigger_error( 'Unknown user', E_USER_WARNING );
  388. return null;
  389. }
  390. // TODO factor this out
  391. if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
  392. $active_blog = get_active_blog_for_user( $user->ID );
  393. $site_id = $active_blog->blog_id;
  394. $profile_URL = "http://en.gravatar.com/{$user->user_login}";
  395. } else {
  396. $profile_URL = 'http://en.gravatar.com/' . md5( strtolower( trim( $user->user_email ) ) );
  397. $site_id = -1;
  398. }
  399. $author = array(
  400. 'ID' => (int) $user->ID,
  401. 'login' => (string) $user->user_login,
  402. 'email' => $show_email ? (string) $user->user_email : false, // (string|bool)
  403. 'name' => (string) $user->display_name,
  404. 'first_name' => (string) $user->first_name,
  405. 'last_name' => (string) $user->last_name,
  406. 'nice_name' => (string) $user->user_nicename,
  407. 'URL' => (string) esc_url_raw( $user->user_url ),
  408. 'avatar_URL' => (string) esc_url_raw( $this->get_avatar_url( $user->user_email ) ),
  409. 'profile_URL' => (string) esc_url_raw( $profile_URL )
  410. );
  411. if ($site_id > -1) {
  412. $author['site_ID'] = (int) $site_id;
  413. }
  414. return (object) $author;
  415. }
  416. protected function get_avatar_url( $email, $avatar_size = 96 ) {
  417. $avatar_url = wpcom_get_avatar_url( $email, $avatar_size, '', true );
  418. if ( ! $avatar_url || is_wp_error( $avatar_url ) ) {
  419. return '';
  420. }
  421. return esc_url_raw( htmlspecialchars_decode( $avatar_url[0] ) );
  422. }
  423. /**
  424. * Get extra post permalink suggestions
  425. * @return array array of permalink suggestions: 'permalink_URL', 'suggested_slug'
  426. */
  427. public function get_permalink_suggestions( $title ) {
  428. $suggestions = array();
  429. list( $suggestions['permalink_URL'], $suggestions['suggested_slug'] ) = get_sample_permalink( $this->post->ID, $title );
  430. return $suggestions;
  431. }
  432. private function format_taxonomy( $taxonomy, $taxonomy_type, $context ) {
  433. // Permissions
  434. switch ( $context ) {
  435. case 'edit' :
  436. $tax = get_taxonomy( $taxonomy_type );
  437. if ( !current_user_can( $tax->cap->edit_terms ) )
  438. return new WP_Error( 'unauthorized', 'User cannot edit taxonomy', 403 );
  439. break;
  440. case 'display' :
  441. if ( -1 == get_option( 'blog_public' ) && ! current_user_can( 'read' ) ) {
  442. return new WP_Error( 'unauthorized', 'User cannot view taxonomy', 403 );
  443. }
  444. break;
  445. default :
  446. return new WP_Error( 'invalid_context', 'Invalid API CONTEXT', 400 );
  447. }
  448. $response = array();
  449. $response['ID'] = (int) $taxonomy->term_id;
  450. $response['name'] = (string) $taxonomy->name;
  451. $response['slug'] = (string) $taxonomy->slug;
  452. $response['description'] = (string) $taxonomy->description;
  453. $response['post_count'] = (int) $taxonomy->count;
  454. if ( is_taxonomy_hierarchical( $taxonomy_type ) ) {
  455. $response['parent'] = (int) $taxonomy->parent;
  456. }
  457. $response['meta'] = (object) array(
  458. 'links' => (object) array(
  459. 'self' => (string) $this->links->get_taxonomy_link( $this->site->get_id(), $taxonomy->slug, $taxonomy_type ),
  460. 'help' => (string) $this->links->get_taxonomy_link( $this->site->get_id(), $taxonomy->slug, $taxonomy_type, 'help' ),
  461. 'site' => (string) $this->links->get_site_link( $this->site->get_id() ),
  462. ),
  463. );
  464. return (object) $response;
  465. }
  466. // TODO: factor this out into site
  467. private function get_media_item_v1_1( $media_id ) {
  468. $media_item = get_post( $media_id );
  469. if ( ! $media_item || is_wp_error( $media_item ) )
  470. return new WP_Error( 'unknown_media', 'Unknown Media', 404 );
  471. $file = basename( wp_get_attachment_url( $media_item->ID ) );
  472. $file_info = pathinfo( $file );
  473. $ext = $file_info['extension'];
  474. $response = array(
  475. 'ID' => $media_item->ID,
  476. 'URL' => wp_get_attachment_url( $media_item->ID ),
  477. 'guid' => $media_item->guid,
  478. 'date' => (string) WPCOM_JSON_API_Date::format_date( $media_item->post_date_gmt, $media_item->post_date ),
  479. 'post_ID' => $media_item->post_parent,
  480. 'author_ID' => (int) $media_item->post_author,
  481. 'file' => $file,
  482. 'mime_type' => $media_item->post_mime_type,
  483. 'extension' => $ext,
  484. 'title' => $media_item->post_title,
  485. 'caption' => $media_item->post_excerpt,
  486. 'description' => $media_item->post_content,
  487. 'alt' => get_post_meta( $media_item->ID, '_wp_attachment_image_alt', true ),
  488. 'thumbnails' => array()
  489. );
  490. if ( in_array( $ext, array( 'jpg', 'jpeg', 'png', 'gif' ) ) ) {
  491. $metadata = wp_get_attachment_metadata( $media_item->ID );
  492. if ( isset( $metadata['height'], $metadata['width'] ) ) {
  493. $response['height'] = $metadata['height'];
  494. $response['width'] = $metadata['width'];
  495. }
  496. if ( isset( $metadata['sizes'] ) ) {
  497. /**
  498. * Filter the thumbnail sizes available for each attachment ID.
  499. *
  500. * @module json-api
  501. *
  502. * @since 3.9.0
  503. *
  504. * @param array $metadata['sizes'] Array of thumbnail sizes available for a given attachment ID.
  505. * @param string $media_id Attachment ID.
  506. */
  507. $sizes = apply_filters( 'rest_api_thumbnail_sizes', $metadata['sizes'], $media_id );
  508. if ( is_array( $sizes ) ) {
  509. foreach ( $sizes as $size => $size_details ) {
  510. $response['thumbnails'][ $size ] = dirname( $response['URL'] ) . '/' . $size_details['file'];
  511. }
  512. }
  513. }
  514. if ( isset( $metadata['image_meta'] ) ) {
  515. $response['exif'] = $metadata['image_meta'];
  516. }
  517. }
  518. if ( in_array( $ext, array( 'mp3', 'm4a', 'wav', 'ogg' ) ) ) {
  519. $metadata = wp_get_attachment_metadata( $media_item->ID );
  520. $response['length'] = $metadata['length'];
  521. $response['exif'] = $metadata;
  522. }
  523. if ( in_array( $ext, array( 'ogv', 'mp4', 'mov', 'wmv', 'avi', 'mpg', '3gp', '3g2', 'm4v' ) ) ) {
  524. $metadata = wp_get_attachment_metadata( $media_item->ID );
  525. if ( isset( $metadata['height'], $metadata['width'] ) ) {
  526. $response['height'] = $metadata['height'];
  527. $response['width'] = $metadata['width'];
  528. }
  529. if ( isset( $metadata['length'] ) ) {
  530. $response['length'] = $metadata['length'];
  531. }
  532. // add VideoPress info
  533. if ( function_exists( 'video_get_info_by_blogpostid' ) ) {
  534. $info = video_get_info_by_blogpostid( $this->site->get_id(), $media_id );
  535. // Thumbnails
  536. if ( function_exists( 'video_format_done' ) && function_exists( 'video_image_url_by_guid' ) ) {
  537. $response['thumbnails'] = array( 'fmt_hd' => '', 'fmt_dvd' => '', 'fmt_std' => '' );
  538. foreach ( $response['thumbnails'] as $size => $thumbnail_url ) {
  539. if ( video_format_done( $info, $size ) ) {
  540. $response['thumbnails'][ $size ] = video_image_url_by_guid( $info->guid, $size );
  541. } else {
  542. unset( $response['thumbnails'][ $size ] );
  543. }
  544. }
  545. }
  546. $response['videopress_guid'] = $info->guid;
  547. $response['videopress_processing_done'] = true;
  548. if ( '0000-00-00 00:00:00' == $info->finish_date_gmt ) {
  549. $response['videopress_processing_done'] = false;
  550. }
  551. }
  552. }
  553. $response['thumbnails'] = (object) $response['thumbnails'];
  554. $response['meta'] = (object) array(
  555. 'links' => (object) array(
  556. 'self' => (string) $this->links->get_media_link( $this->site->get_id(), $media_id ),
  557. 'help' => (string) $this->links->get_media_link( $this->site->get_id(), $media_id, 'help' ),
  558. 'site' => (string) $this->links->get_site_link( $this->site->get_id() ),
  559. ),
  560. );
  561. // add VideoPress link to the meta
  562. if ( in_array( $ext, array( 'ogv', 'mp4', 'mov', 'wmv', 'avi', 'mpg', '3gp', '3g2', 'm4v' ) ) ) {
  563. if ( function_exists( 'video_get_info_by_blogpostid' ) ) {
  564. $response['meta']->links->videopress = (string) $this->links->get_link( '/videos/%s', $response['videopress_guid'], '' );
  565. }
  566. }
  567. if ( $media_item->post_parent > 0 ) {
  568. $response['meta']->links->parent = (string) $this->links->get_post_link( $this->site->get_id(), $media_item->post_parent );
  569. }
  570. return (object) $response;
  571. }
  572. }