Skip to content

Commit

Permalink
[#945] Added another useful MT::Util function, `match_file_extension(…
Browse files Browse the repository at this point in the history
…)` which makes it extremely simple to see—in a cross-platform, multibyte-safe way—whether a file ends with a particular file extension or matches one of an array of patterns representing possible extensions or extensions of interest.

Includes POD docs and ample usage examples in the unit tests.
  • Loading branch information
jayallen committed Jun 27, 2011
1 parent 787e6f4 commit 525de85
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 2 deletions.
35 changes: 34 additions & 1 deletion lib/MT/Util.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2708,11 +2708,15 @@ sub to_json {
}

# Tested in t/99-utils.misc
# TODO Move this to MT::FileMgr (perhaps?)
sub file_extension {
my $fname = shift;
require File::Basename;
my @parts = split(/\./, File::Basename::basename($fname));
shift @parts while @parts > 1 and $parts[0] eq ''; # Skips empty dotfile element

shift @parts
while @parts > 1 and $parts[0] eq ''; # Skips empty dotfile element

return @parts > 1 ? pop @parts : ''
} ## end sub file_extension

Expand Down Expand Up @@ -2762,6 +2766,18 @@ sub mime_type_extension {
} ## end sub mime_type_extension


# Tested in t/99-utils.misc
# TODO Move this to MT::FileMgr (perhaps?)
sub match_file_extension {
my $filename = shift;
my $exts = ref $_[0] eq 'ARRAY' ? shift : [ @_ ];
require File::Basename;
my @exts = map { m/^\./ ? qr/$_/i : qr/\.$_/i } @$exts;
my @ret = File::Basename::fileparse( $filename, @exts );
return $ret[2] if @ret;
} ## end sub match_file_extension


1;

__END__
Expand Down Expand Up @@ -3040,6 +3056,23 @@ variant.
If no extensions are found for the specified MIME type, the function will
return an empty array;
=head2 match_file_extension( $file, \@patterns )
This function compares a file name (with or without preceding path) against an
array of one or more patterns which represent possible file extensions or
extensions of interest. For example:
match_file_extension( 'file.txt', [qw( rtf txt doc )] ) # Yields '.txt'
match_file_extension( 'file.php3', [qw( php[s\d]? )] ) # Yields '.php3'
If a pattern matches (case-insensitive, anchored to
the right side of the string), the matched portion of the file name is
returned. If no match is found, the function returns an empty string.
The array of patterns can be supplied either as an array reference or an array.
See t/99-utils-misc.t for far more examples of usage.
=head2 addbin
=head2 archive_file_for
Expand Down
40 changes: 39 additions & 1 deletion t/99-utils-misc.t
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use strict;
use warnings;

use lib 't/lib', 'lib', 'extlib';
use Test::More tests => 3;
use Test::More tests => 4;

use MT;
use MT::Util;
Expand Down Expand Up @@ -181,6 +181,44 @@ subtest "mime_type_extension()" => sub {
}
};

subtest "match_file_extension()" => sub {
my @tests = (
# FILE NAME EXTENSION SEARCH ARRAY EXPECTED RESULT
[ 'file.txt' => ['txt'] => '.txt' ],
[ 'file.txt' => [ qw( text doc rtf txt md ) ] => '.txt' ],
[ 'file.js' => [ qw( html js php ) ] => '.js' ],
[ 'file.json' => [ qw( html js php ) ] => '' ],
[ 'file.js' => [ qw( html json php ) ] => '' ],
[ 'file.json' => [ qw( html js.* php ) ] => '.json' ],
[ 'file.js' => [ qw( html js.* php ) ] => '.js' ],
[ 'file.php' => [ qw( html js.* php[s\d]? ) ] => '.php' ],
[ 'file.php3' => [ qw( html js.* php[s\d]? ) ] => '.php3' ],
[ 'file.php5' => [ qw( html js.* php[s\d]? ) ] => '.php5' ],
[ 'file.phps' => [ qw( html js.* php[s\d]? ) ] => '.phps' ],
[ '.htaccess' => [ qw( cnf conf htaccess ) ] => '.htaccess' ],
[ '.my.cnf' => [ qw( cnf conf htaccess ) ] => '.cnf' ],
[ 'file.tar.gz' => [ qw( Z bz2 gz zip ) ] => '.gz' ],
[ 'file.tar.gz' => [ qw( Z bz2 tar zip ) ] => '' ],
[ 'file.tar.gz' => [ qw( Z bz2 tar\.gz zip ) ] => '.tar.gz' ],
[ '.' => [ qw( cgi txt pl ) ] => '' ],
[ '..' => [ qw( cgi txt pl ) ] => '' ],
);
plan tests => @tests * 2;

foreach my $test ( @tests ) {
my ($fname, $exts, $expected) = @$test;
foreach my $path ( '', '/tmp/' ) {
$fname = $path . $fname;
is(
MT::Util::match_file_extension( $fname, $exts ),
$expected,
sprintf( "Matching '%s' against (%s) returns '%s'",
$fname, join(', ', @$exts), $expected )
);
}
}
};

1;
__END__
Expand Down

0 comments on commit 525de85

Please sign in to comment.