Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
96.30% |
52 / 54 |
|
83.33% |
5 / 6 |
CRAP | n/a |
0 / 0 |
|
| wpcom_podcast_feed_credit_maybe_hook | |
87.50% |
7 / 8 |
|
0.00% |
0 / 1 |
3.02 | |||
| wpcom_podcast_feed_credit_append_to_summary | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
| wpcom_podcast_feed_credit_append_to_excerpt | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
| wpcom_podcast_feed_credit_append_to_content | |
100.00% |
19 / 19 |
|
100.00% |
1 / 1 |
3 | |||
| wpcom_podcast_feed_credit_text | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
2 | |||
| wpcom_podcast_feed_credit_show_title | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
5 | |||
| 1 | <?php |
| 2 | /** |
| 3 | * Appends a "Made with Jetpack Podcast" credit to the podcast feed of sites |
| 4 | * without podcast plan access. |
| 5 | * |
| 6 | * @package automattic/jetpack-mu-wpcom |
| 7 | */ |
| 8 | |
| 9 | use Automattic\Jetpack\Podcast\Feed\Customize_Feed; |
| 10 | use Automattic\Jetpack\Podcast\Podcast_Gate; |
| 11 | |
| 12 | /** |
| 13 | * Hook the credit once the podcast package has claimed this request as the |
| 14 | * podcast feed. The package registers on `wp` at priority 10, so this runs at 11. |
| 15 | */ |
| 16 | function wpcom_podcast_feed_credit_maybe_hook() { |
| 17 | if ( ! has_action( 'rss2_head', array( Customize_Feed::class, 'output_channel_tags' ) ) ) { |
| 18 | return; |
| 19 | } |
| 20 | if ( Podcast_Gate::has_product_access() ) { |
| 21 | return; |
| 22 | } |
| 23 | // The package reads the channel summary through `get_option()`, so both |
| 24 | // `<description>` and `<itunes:summary>` pick the credit up here. |
| 25 | add_filter( 'option_podcasting_summary', 'wpcom_podcast_feed_credit_append_to_summary' ); |
| 26 | add_filter( 'default_option_podcasting_summary', 'wpcom_podcast_feed_credit_append_to_summary' ); |
| 27 | // Just below the package's `capture_item_summary()` at PHP_INT_MAX, so the |
| 28 | // item `<description>` and the `<itunes:summary>` built from it agree. |
| 29 | add_filter( 'the_excerpt_rss', 'wpcom_podcast_feed_credit_append_to_excerpt', PHP_INT_MAX - 1 ); |
| 30 | add_filter( 'the_content_feed', 'wpcom_podcast_feed_credit_append_to_content' ); |
| 31 | } |
| 32 | add_action( 'wp', 'wpcom_podcast_feed_credit_maybe_hook', 11 ); |
| 33 | |
| 34 | /** |
| 35 | * `option_podcasting_summary` filter: append the credit to the channel summary. |
| 36 | * |
| 37 | * @param mixed $summary Option value. |
| 38 | * @return string |
| 39 | */ |
| 40 | function wpcom_podcast_feed_credit_append_to_summary( $summary ) { |
| 41 | $summary = rtrim( (string) $summary ); |
| 42 | return '' === $summary ? wpcom_podcast_feed_credit_text() : $summary . "\n\n" . wpcom_podcast_feed_credit_text(); |
| 43 | } |
| 44 | |
| 45 | /** |
| 46 | * `the_excerpt_rss` filter: append the credit to the episode `<description>`. |
| 47 | * The template wraps it in CDATA, so `]]>` gets the escape core gives |
| 48 | * generated excerpts. |
| 49 | * |
| 50 | * @param string $excerpt Item excerpt. |
| 51 | * @return string |
| 52 | */ |
| 53 | function wpcom_podcast_feed_credit_append_to_excerpt( $excerpt ) { |
| 54 | $excerpt = rtrim( (string) $excerpt ); |
| 55 | $credit = str_replace( ']]>', ']]>', wpcom_podcast_feed_credit_text() ); |
| 56 | return '' === $excerpt ? $credit : $excerpt . "\n\n" . $credit; |
| 57 | } |
| 58 | |
| 59 | /** |
| 60 | * `the_content_feed` filter: append the linked credit to `<content:encoded>`. |
| 61 | * Empty content stays empty so core falls back to the excerpt, which already |
| 62 | * carries the credit. |
| 63 | * |
| 64 | * @param string $content Item content. |
| 65 | * @return string |
| 66 | */ |
| 67 | function wpcom_podcast_feed_credit_append_to_content( $content ) { |
| 68 | if ( '' === (string) $content ) { |
| 69 | return $content; |
| 70 | } |
| 71 | $site_url = home_url( '/' ); |
| 72 | $title = wpcom_podcast_feed_credit_show_title(); |
| 73 | $product = '<a href="https://wordpress.com/podcast/">Jetpack Podcast</a>'; |
| 74 | $link = '<a href="' . esc_url( $site_url ) . '">' . esc_html( $site_url ) . '</a>'; |
| 75 | |
| 76 | if ( '' === $title ) { |
| 77 | $credit = sprintf( |
| 78 | /* translators: 1: HTML link to "Jetpack Podcast", 2: HTML link to site URL */ |
| 79 | esc_html__( 'This podcast is made with %1$s. Full show notes and every episode at %2$s', 'jetpack-mu-wpcom' ), |
| 80 | $product, |
| 81 | $link |
| 82 | ); |
| 83 | } else { |
| 84 | $credit = sprintf( |
| 85 | /* translators: 1: podcast title, 2: HTML link to "Jetpack Podcast", 3: HTML link to site URL */ |
| 86 | esc_html__( '%1$s is made with %2$s. Full show notes and every episode at %3$s', 'jetpack-mu-wpcom' ), |
| 87 | esc_html( $title ), |
| 88 | $product, |
| 89 | $link |
| 90 | ); |
| 91 | } |
| 92 | return (string) $content . "\n<p>" . $credit . '</p>'; |
| 93 | } |
| 94 | |
| 95 | /** |
| 96 | * Plain-text credit, for `<description>` and `<itunes:summary>`. |
| 97 | * |
| 98 | * @return string |
| 99 | */ |
| 100 | function wpcom_podcast_feed_credit_text(): string { |
| 101 | $title = wpcom_podcast_feed_credit_show_title(); |
| 102 | |
| 103 | if ( '' === $title ) { |
| 104 | return sprintf( |
| 105 | /* translators: 1: "Jetpack Podcast", 2: site URL */ |
| 106 | __( 'This podcast is made with %1$s. Full show notes and every episode at %2$s', 'jetpack-mu-wpcom' ), |
| 107 | 'Jetpack Podcast', |
| 108 | home_url( '/' ) |
| 109 | ); |
| 110 | } |
| 111 | |
| 112 | return sprintf( |
| 113 | /* translators: 1: podcast title, 2: "Jetpack Podcast", 3: site URL */ |
| 114 | __( '%1$s is made with %2$s. Full show notes and every episode at %3$s', 'jetpack-mu-wpcom' ), |
| 115 | $title, |
| 116 | 'Jetpack Podcast', |
| 117 | home_url( '/' ) |
| 118 | ); |
| 119 | } |
| 120 | |
| 121 | /** |
| 122 | * The show title for the credit: `podcasting_title`, else the site name. |
| 123 | * A site name that is just the site's slug or host is no title at all, so |
| 124 | * it yields '' and the credit goes subjectless rather than reading |
| 125 | * "example78687615498 is made with". |
| 126 | * |
| 127 | * @return string '' when there is nothing worth calling the show. |
| 128 | */ |
| 129 | function wpcom_podcast_feed_credit_show_title(): string { |
| 130 | $host = strtolower( (string) wp_parse_url( home_url(), PHP_URL_HOST ) ); |
| 131 | $slug = strstr( $host, '.', true ); |
| 132 | $junk = array_filter( array( $host, false === $slug ? '' : $slug ) ); |
| 133 | |
| 134 | foreach ( array( get_option( 'podcasting_title', '' ), get_bloginfo( 'name' ) ) as $candidate ) { |
| 135 | $candidate = trim( wp_strip_all_tags( (string) $candidate ) ); |
| 136 | if ( '' !== $candidate && ! in_array( strtolower( $candidate ), $junk, true ) ) { |
| 137 | return $candidate; |
| 138 | } |
| 139 | } |
| 140 | return ''; |
| 141 | } |