증거물 A-2 근거: 커밋 31bc0c1
커밋 시각 · 31bc0c19328caad2ee56059d5b5c5db7c2e96313
휴대폰이 원본 크기 이미지를 내려받았습니다
저장소 자체는 비공개입니다. 이 페이지에 커밋을 기록된 그대로 옮겼습니다.
커밋 메시지
이미지를 자리 크기에 맞춰 srcset과 지연 로딩으로 제공
변경 내용
git에 기록된 텍스트 파일만 보여 줍니다. +로 시작하는 줄은 추가, −로 시작하는 줄은 삭제입니다.
바뀐 파일
---
site/wp-content/plugins/hc-team-directory/hc-team-directory.php | 13 ++++-
site/wp-content/themes/hollis-child/front-page.php | 24 ++++++++-
tests/phpunit/repair/ImagesTest.php | 79 +++++++++++++++++++++++++++++
3 files changed, 112 insertions(+), 4 deletions(-)
diff --git a/site/wp-content/plugins/hc-team-directory/hc-team-directory.php b/site/wp-content/plugins/hc-team-directory/hc-team-directory.php
index e572635..9ddb84f 100644
--- a/site/wp-content/plugins/hc-team-directory/hc-team-directory.php
+++ b/site/wp-content/plugins/hc-team-directory/hc-team-directory.php
@@ -107,7 +107,16 @@ function hc_team_directory_render( $limit = -1, $full = true ) {
$role_ko = $wpdb->get_var( "SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = $id AND meta_key = '_hollis_ko_role'" );
$bio_ko = $wpdb->get_var( "SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = $id AND meta_key = '_hollis_ko_content'" );
$photo_id = $wpdb->get_var( "SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = $id AND meta_key = '_thumbnail_id'" );
- $photo = $photo_id ? wp_get_original_image_url( (int) $photo_id ) : '';
+ $photo = $photo_id ? wp_get_attachment_image(
+ (int) $photo_id,
+ 'medium',
+ false,
+ array(
+ 'loading' => 'lazy',
+ 'sizes' => '(max-width: 600px) 45vw, 260px',
+ 'alt' => '',
+ )
+ ) : '';
$langs = $wpdb->get_col( "SELECT t.slug FROM {$wpdb->terms} t JOIN {$wpdb->term_taxonomy} tt ON tt.term_id = t.term_id JOIN {$wpdb->term_relationships} tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy = 'hc_language' AND tr.object_id = $id" );
$services = $wpdb->get_col( "SELECT p.ID FROM {$wpdb->posts} p JOIN {$wpdb->postmeta} m ON m.post_id = p.ID WHERE p.post_type = 'hc_service' AND p.post_status = 'publish' AND m.meta_key = 'hc_provider' AND m.meta_value = '$id' ORDER BY p.menu_order" );
$ko = function_exists( 'hollis_lang_is_ko' ) && hollis_lang_is_ko();
@@ -122,7 +131,7 @@ function hc_team_directory_render( $limit = -1, $full = true ) {
$html .= '<li class="team-card">';
if ( $photo ) {
- $html .= '<div class="team-photo"><img src="' . esc_url( $photo ) . '"></div>';
+ $html .= '<div class="team-photo">' . $photo . '</div>';
}
$html .= '<h3 class="team-name">' . esc_html( $member->post_title ) . '</h3>';
$html .= '<p class="team-role">' . esc_html( $ko && $role_ko ? $role_ko : $role ) . '</p>';
diff --git a/site/wp-content/themes/hollis-child/front-page.php b/site/wp-content/themes/hollis-child/front-page.php
index 83019df..79997a4 100644
--- a/site/wp-content/themes/hollis-child/front-page.php
+++ b/site/wp-content/themes/hollis-child/front-page.php
@@ -34,7 +34,18 @@ $hollis_office = (int) get_theme_mod( 'hollis_office_image' );
?>
</div>
<div class="hero-media">
- <img src="<?php echo esc_url( wp_get_original_image_url( $hollis_hero ) ); ?>">
+ <?php
+ echo hollis_child_image( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- wp_get_attachment_image() output.
+ $hollis_hero,
+ 'hollis-hero',
+ array(
+ 'loading' => 'eager',
+ 'fetchpriority' => 'high',
+ 'sizes' => '(max-width: 900px) 100vw, 560px',
+ 'alt' => __( 'Illustration of the Hollis Creek office: a white clapboard building by a creek, with a bench and two maple trees.', 'hollis-child' ),
+ )
+ );
+ ?>
</div>
</div>
</section>
@@ -77,7 +88,16 @@ $hollis_office = (int) get_theme_mod( 'hollis_office_image' );
<p><a href="<?php echo esc_url( home_url( '/insurance/' ) ); ?>"><?php esc_html_e( 'Insurance and payment', 'hollis-child' ); ?></a></p>
</div>
<div class="visit-media">
- <img src="<?php echo esc_url( wp_get_original_image_url( $hollis_office ) ); ?>">
+ <?php
+ echo hollis_child_image( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- wp_get_attachment_image() output.
+ $hollis_office,
+ 'large',
+ array(
+ 'sizes' => '(max-width: 900px) 100vw, 520px',
+ 'alt' => __( 'Illustration of the waiting room: two armchairs, a plant and a children\'s corner with books.', 'hollis-child' ),
+ )
+ );
+ ?>
</div>
</div>
</section>
diff --git a/tests/phpunit/repair/ImagesTest.php b/tests/phpunit/repair/ImagesTest.php
new file mode 100644
index 0000000..6c6047b
--- /dev/null
+++ b/tests/phpunit/repair/ImagesTest.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Exhibit A-2: the home page and team photos are served at the size of their slot.
+ *
+ * @package Hollis\Tests
+ */
+
+/**
+ * Images.
+ */
+class ImagesTest extends WP_UnitTestCase {
+
+ /**
+ * Attachment used for every image slot.
+ *
+ * @var int
+ */
+ private $image;
+
+ public function set_up() {
+ parent::set_up();
+ $this->image = self::factory()->attachment->create_upload_object( DIR_TESTDATA . '/images/33772.jpg' );
+ set_theme_mod( 'hollis_hero_image', $this->image );
+ set_theme_mod( 'hollis_office_image', $this->image );
+ $member = self::factory()->post->create(
+ array(
+ 'post_type' => 'hc_team',
+ 'post_title' => 'Test Member',
+ )
+ );
+ set_post_thumbnail( $member, $this->image );
+ }
+
+ /**
+ * Renders the home page template.
+ *
+ * @return string
+ */
+ private function home_html() {
+ $this->go_to( home_url( '/' ) );
+ ob_start();
+ include get_stylesheet_directory() . '/front-page.php';
+ return ob_get_clean();
+ }
+
+ /**
+ * All <img> tags in the markup.
+ *
+ * @param string $html Markup.
+ * @return string[]
+ */
+ private function images( $html ) {
+ preg_match_all( '/<img\b[^>]*>/', $html, $m );
+ return $m[0];
+ }
+
+ public function test_hero_has_srcset_dimensions_and_high_priority_not_the_original_upload() {
+ $imgs = $this->images( $this->home_html() );
+ $this->assertNotEmpty( $imgs );
+ $hero = $imgs[0];
+ $this->assertMatchesRegularExpression( '/\ssrcset="[^"]+\s\d+w/', $hero );
+ $this->assertMatchesRegularExpression( '/\ssizes="/', $hero );
+ $this->assertMatchesRegularExpression( '/\swidth="\d+"/', $hero );
+ $this->assertMatchesRegularExpression( '/\sheight="\d+"/', $hero );
+ $this->assertStringContainsString( 'fetchpriority="high"', $hero );
+ $this->assertStringNotContainsString( 'loading="lazy"', $hero );
+ $this->assertStringNotContainsString( wp_get_original_image_url( $this->image ) . '"', $hero );
+ }
+
+ public function test_images_below_the_fold_load_lazily_with_srcset_and_alt() {
+ $imgs = array_slice( $this->images( $this->home_html() ), 1 );
+ $this->assertNotEmpty( $imgs );
+ foreach ( $imgs as $img ) {
+ $this->assertStringContainsString( 'loading="lazy"', $img );
+ $this->assertMatchesRegularExpression( '/\ssrcset="/', $img );
+ $this->assertMatchesRegularExpression( '/\salt="/', $img );
+ }
+ }
+}
증명 테스트
tests/phpunit/repair/ImagesTest.php
tests/phpunit/repair/ImagesTest.php, 커밋된 그대로.
<?php
/**
* Exhibit A-2: the home page and team photos are served at the size of their slot.
*
* @package Hollis\Tests
*/
/**
* Images.
*/
class ImagesTest extends WP_UnitTestCase {
/**
* Attachment used for every image slot.
*
* @var int
*/
private $image;
public function set_up() {
parent::set_up();
hc_booking_install_table();
$this->image = self::factory()->attachment->create_upload_object( DIR_TESTDATA . '/images/test-image-large.jpg' /* 3000x2250, like a camera upload */ );
set_theme_mod( 'hollis_hero_image', $this->image );
set_theme_mod( 'hollis_office_image', $this->image );
$member = self::factory()->post->create(
array(
'post_type' => 'hc_team',
'post_title' => 'Test Member',
)
);
set_post_thumbnail( $member, $this->image );
}
/**
* Renders the home page template.
*
* @return string
*/
private function home_html() {
$this->go_to( home_url( '/' ) );
ob_start();
include get_stylesheet_directory() . '/front-page.php';
return ob_get_clean();
}
/**
* All <img> tags in the markup.
*
* @param string $html Markup.
* @return string[]
*/
private function images( $html ) {
preg_match_all( '/<img\b[^>]*>/', $html, $m );
return $m[0];
}
public function test_hero_has_srcset_dimensions_and_high_priority_not_the_original_upload() {
$imgs = $this->images( $this->home_html() );
$this->assertNotEmpty( $imgs );
$hero = $imgs[0];
$this->assertMatchesRegularExpression( '/\ssrcset="[^"]+\s\d+w/', $hero );
$this->assertMatchesRegularExpression( '/\ssizes="/', $hero );
$this->assertMatchesRegularExpression( '/\swidth="\d+"/', $hero );
$this->assertMatchesRegularExpression( '/\sheight="\d+"/', $hero );
$this->assertStringContainsString( 'fetchpriority="high"', $hero );
$this->assertStringNotContainsString( 'loading="lazy"', $hero );
$this->assertStringNotContainsString( wp_get_original_image_url( $this->image ) . '"', $hero );
}
public function test_images_below_the_fold_load_lazily_with_srcset_and_alt() {
$imgs = array_slice( $this->images( $this->home_html() ), 1 );
$this->assertNotEmpty( $imgs );
foreach ( $imgs as $img ) {
$this->assertStringContainsString( 'loading="lazy"', $img );
$this->assertMatchesRegularExpression( '/\ssrcset="/', $img );
$this->assertMatchesRegularExpression( '/\salt="/', $img );
}
}
}