Skip to content

Commit ca46f19

Browse files
authored
Merge pull request #2072 from danburzo/master
Add PathHelper for utf8-safe pathinfo() / basename() functions
2 parents cb5df59 + 07909c7 commit ca46f19

6 files changed

Lines changed: 73 additions & 11 deletions

File tree

lib/Image.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Timber\Helper;
77
use Timber\Post;
88
use Timber\URLHelper;
9+
use Timber\PathHelper;
910

1011

1112
/**
@@ -115,7 +116,7 @@ public function __toString() {
115116
* @return array
116117
*/
117118
public function get_pathinfo() {
118-
return pathinfo($this->file);
119+
return PathHelper::pathinfo($this->file);
119120
}
120121

121122
/**
@@ -497,7 +498,7 @@ public function img_sizes( $size = "full" ) {
497498
protected function is_image() {
498499
$src = wp_get_attachment_url($this->ID);
499500
$image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' );
500-
$check = wp_check_filetype(basename($src), null);
501+
$check = wp_check_filetype(PathHelper::basename($src), null);
501502
return in_array($check['ext'], $image_exts);
502503
}
503504

lib/Image/Operation/Letterbox.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Timber\Helper;
66
use Timber\ImageHelper;
7+
use Timber\PathHelper;
78
use Timber\Image\Operation as ImageOperation;
89

910
/*
@@ -103,7 +104,7 @@ public function run( $load_filename, $save_filename ) {
103104
$result = $image->save($save_filename);
104105
$func = 'imagecreatefromjpeg';
105106
$save_func = 'imagejpeg';
106-
$ext = pathinfo($save_filename, PATHINFO_EXTENSION);
107+
$ext = PathHelper::pathinfo($save_filename, PATHINFO_EXTENSION);
107108
if ( $ext == 'gif' ) {
108109
$func = 'imagecreatefromgif';
109110
$save_func = 'imagegif';

lib/ImageHelper.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Timber\Image\Operation\Letterbox;
1111

1212
use Timber\URLHelper;
13+
use Timber\PathHelper;
1314

1415
/**
1516
* Implements the Twig image filters:
@@ -163,7 +164,7 @@ public static function is_svg( $file_path ) {
163164
* SVG images are not allowed by default in WordPress, so we have to pass a default mime
164165
* type for SVG images.
165166
*/
166-
$mime = wp_check_filetype_and_ext( $file_path, basename( $file_path ), array(
167+
$mime = wp_check_filetype_and_ext( $file_path, PathHelper::basename( $file_path ), array(
167168
'svg' => 'image/svg+xml',
168169
) );
169170

@@ -281,7 +282,7 @@ static function delete_generated_files( $local_file ) {
281282
if ( URLHelper::is_absolute($local_file) ) {
282283
$local_file = URLHelper::url_to_file_system($local_file);
283284
}
284-
$info = pathinfo($local_file);
285+
$info = PathHelper::pathinfo($local_file);
285286
$dir = $info['dirname'];
286287
$ext = $info['extension'];
287288
$filename = $info['filename'];
@@ -348,7 +349,7 @@ public static function get_sideloaded_file_loc( $file ) {
348349
$dir = $upload['path'];
349350
$filename = $file;
350351
$file = parse_url($file);
351-
$path_parts = pathinfo($file['path']);
352+
$path_parts = PathHelper::pathinfo($file['path']);
352353
$basename = md5($filename);
353354
$ext = 'jpg';
354355
if ( isset($path_parts['extension']) ) {
@@ -375,15 +376,15 @@ public static function sideload_image( $file ) {
375376
$tmp = download_url($file);
376377
preg_match('/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $file, $matches);
377378
$file_array = array();
378-
$file_array['name'] = basename($matches[0]);
379+
$file_array['name'] = PathHelper::basename($matches[0]);
379380
$file_array['tmp_name'] = $tmp;
380381
// If error storing temporarily, unlink
381382
if ( is_wp_error($tmp) ) {
382383
@unlink($file_array['tmp_name']);
383384
$file_array['tmp_name'] = '';
384385
}
385386
// do the validation and storage stuff
386-
$locinfo = pathinfo($loc);
387+
$locinfo = PathHelper::pathinfo($loc);
387388
$file = wp_upload_bits($locinfo['basename'], null, file_get_contents($file_array['tmp_name']));
388389
return $file['url'];
389390
}
@@ -432,7 +433,7 @@ public static function analyze_url( $url ) {
432433
$tmp = URLHelper::remove_url_component($tmp, WP_CONTENT_DIR);
433434
}
434435
}
435-
$parts = pathinfo($tmp);
436+
$parts = PathHelper::pathinfo($tmp);
436437
$result['subdir'] = ($parts['dirname'] === '/') ? '' : $parts['dirname'];
437438
$result['filename'] = $parts['filename'];
438439
$result['extension'] = strtolower($parts['extension']);

lib/LocationManager.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Timber;
44

5+
use Timber\PathHelper;
6+
57
class LocationManager {
68

79

@@ -81,7 +83,7 @@ public static function get_calling_script_file( $offset = 0 ) {
8183
public static function get_calling_script_dir( $offset = 0 ) {
8284
$caller = self::get_calling_script_file($offset);
8385
if ( !is_null($caller) ) {
84-
$pathinfo = pathinfo($caller);
86+
$pathinfo = PathHelper::pathinfo($caller);
8587
$dir = $pathinfo['dirname'];
8688
return $dir;
8789
}

lib/PathHelper.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace Timber;
4+
5+
/**
6+
* Useful methods for working with file paths.
7+
*/
8+
class PathHelper {
9+
10+
/**
11+
*
12+
* Unicode-friendly version of the PHP pathinfo() function.
13+
* https://www.php.net/manual/en/function.pathinfo.php
14+
*
15+
* @param string $path the path.
16+
* @param int $options the path part to extract.
17+
* @return mixed
18+
*
19+
* @package Timber
20+
*/
21+
public static function pathinfo( $path, $options = PATHINFO_DIRNAME |
22+
PATHINFO_BASENAME | PATHINFO_EXTENSION | PATHINFO_FILENAME
23+
) {
24+
$info = pathinfo(
25+
str_replace(
26+
array( '%2F', '%5C' ),
27+
array( '/', '\\' ),
28+
rawurlencode( $path )
29+
),
30+
$options
31+
);
32+
if ( is_array( $info ) ) {
33+
// decode all keys in the array.
34+
return array_map( 'rawurldecode', $info );
35+
} else {
36+
// decode the string when requesting a single path component.
37+
return rawurldecode( $info );
38+
}
39+
}
40+
41+
/**
42+
*
43+
* Unicode-friendly version of the PHP basename() function.
44+
* https://www.php.net/manual/en/function.basename.php
45+
*
46+
* @param string $path the path.
47+
* @param string $suffix optional suffix.
48+
* @return string
49+
*/
50+
public static function basename( $path, $suffix = '' ) {
51+
return rawurldecode(
52+
basename( str_replace( array( '%2F', '%5C' ), '/', rawurlencode( $path ) ), $suffix )
53+
);
54+
}
55+
}

readme.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@ _Twig is the template language powering Timber; if you need a little background
3131
= Develop (next release) =
3232
- Added tests to cover RTL languages and special characters in image file names
3333

34-
**Changes for Theme Developers**
34+
**Fixes and improvements**
35+
- Fix resizing for images with UTF-8 characters in their filename
3536

37+
**Changes for Theme Developers**
3638
- Added new `found_posts` property for `Timber\PostQuery`. Now you can check how many posts were found in a query.
3739

3840
= 1.11.0 =

0 commit comments

Comments
 (0)