Skip to content

Commit 67662cb

Browse files
committed
Media: Introduce wp_get_attachment_link_attributes filter.
This changeset introduces the `wp_get_attachment_link_attributes` hook to allow developers to filter the link attributes when getting the attachment link. Props NathanAtmoz, aaroncampbell, antpb, costdev. Fixes #41574. git-svn-id: https://develop.svn.wordpress.org/trunk@55262 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 3ba96e2 commit 67662cb

2 files changed

Lines changed: 124 additions & 1 deletion

File tree

src/wp-includes/post-template.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1666,7 +1666,24 @@ function wp_get_attachment_link( $post = 0, $size = 'thumbnail', $permalink = fa
16661666
$link_text = esc_html( pathinfo( get_attached_file( $_post->ID ), PATHINFO_FILENAME ) );
16671667
}
16681668

1669-
$link_html = "<a href='" . esc_url( $url ) . "'>$link_text</a>";
1669+
/**
1670+
* Filters the list of attachment link attributes.
1671+
*
1672+
* @since 6.2.0
1673+
*
1674+
* @param array $attributes An array of attributes for the link markup,
1675+
* keyed on the attribute name.
1676+
* @param int $id Post ID.
1677+
*/
1678+
$attributes = apply_filters( 'wp_get_attachment_link_attributes', array( 'href' => $url ), $_post->ID );
1679+
1680+
$link_attributes = '';
1681+
foreach ( $attributes as $name => $value ) {
1682+
$value = 'href' === $name ? esc_url( $value ) : esc_attr( $value );
1683+
$link_attributes .= ' ' . esc_attr( $name ) . "='" . $value . "'";
1684+
}
1685+
1686+
$link_html = "<a$link_attributes>$link_text</a>";
16701687

16711688
/**
16721689
* Filters a retrieved attachment page link.
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<?php
2+
3+
/**
4+
* @group post
5+
* @group media
6+
* @group upload
7+
*
8+
* @covers ::wp_get_attachment_link
9+
*/
10+
class Tests_Post_WpGetAttachmentLink extends WP_UnitTestCase {
11+
12+
/**
13+
* The ID of an attachment for testing.
14+
*
15+
* @var int $attachment
16+
*/
17+
private static $attachment;
18+
19+
/**
20+
* Creates an attachment for testing before any tests run.
21+
*/
22+
public static function set_up_before_class() {
23+
parent::set_up_before_class();
24+
25+
self::$attachment = self::factory()->attachment->create();
26+
}
27+
28+
/**
29+
* Tests that wp_get_attachment_link() applies the
30+
* wp_get_attachment_link_attributes filter.
31+
*
32+
* @ticket 41574
33+
*
34+
* @dataProvider data_should_apply_attributes_filter
35+
*
36+
* @param array $attributes Attributes to return from the callback.
37+
* @param string $expected The substring expected to be in the attachment link.
38+
*/
39+
public function test_should_apply_attributes_filter( $attributes, $expected ) {
40+
$expected = str_replace( 'ATTACHMENT_ID', self::$attachment, $expected );
41+
42+
add_filter(
43+
'wp_get_attachment_link_attributes',
44+
static function( $attr ) use ( $attributes ) {
45+
return array_merge( $attr, $attributes );
46+
}
47+
);
48+
49+
$this->assertStringContainsString(
50+
$expected,
51+
wp_get_attachment_link( self::$attachment )
52+
);
53+
}
54+
55+
/**
56+
* Data provider for test_should_apply_attributes_filter().
57+
*
58+
* @return array[]
59+
*/
60+
public function data_should_apply_attributes_filter() {
61+
return array(
62+
'no new attributes' => array(
63+
'attributes' => array(),
64+
'expected' => "<a href='http://example.org/?attachment_id=ATTACHMENT_ID'>",
65+
),
66+
'one new attribute' => array(
67+
'attributes' => array(
68+
'class' => 'test-attribute-filter',
69+
),
70+
'expected' => " class='test-attribute-filter'",
71+
),
72+
'two new attributes' => array(
73+
'attributes' => array(
74+
'class' => 'test-attribute-filter',
75+
'id' => 'test-attribute-filter-1',
76+
),
77+
'expected' => " class='test-attribute-filter' id='test-attribute-filter-1'",
78+
),
79+
'an existing attribute' => array(
80+
'attributes' => array(
81+
'href' => 'http://test-attribute-filter.org',
82+
),
83+
'expected' => " href='http://test-attribute-filter.org'",
84+
),
85+
'an existing attribute and a new attribute' => array(
86+
'attributes' => array(
87+
'href' => 'http://test-attribute-filter.org',
88+
'class' => 'test-attribute-filter',
89+
),
90+
'expected' => " href='http://test-attribute-filter.org' class='test-attribute-filter'",
91+
),
92+
'an attribute name with unsafe characters' => array(
93+
'attributes' => array(
94+
"> <script>alert('Howdy, admin!')</script> <a href=''></a" => '',
95+
),
96+
'expected' => " &gt; &lt;script&gt;alert(&#039;Howdy, admin!&#039;)&lt;/script&gt; &lt;a href=&#039;&#039;&gt;&lt;/a=''",
97+
),
98+
'an attribute value with unsafe characters' => array(
99+
'attributes' => array(
100+
'class' => "'> <script>alert('Howdy, admin!')</script> <a href=''></a",
101+
),
102+
'expected' => '&#039;&gt; &lt;script&gt;alert(&#039;Howdy, admin!&#039;)&lt;/script&gt; &lt;a href=&#039;&#039;&gt;&lt;/a',
103+
),
104+
);
105+
}
106+
}

0 commit comments

Comments
 (0)