php get content image folder svg - php

I'm trying to get the svg files from a folder.
Tried the following ways but none of them seems to work:
<?php
$directory = get_bloginfo('template_directory').'/images/myImages/';
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory));
while ($it->valid()) { //Check the file exist
if (!$it->isDot()) { //if not parent ".." or current "."
if (strpos($it->key(), '.php') !== false
|| strpos($it->key(), '.css') !== false
|| strpos($it->key(), '.js') !== false
) {
echo $it->key() . '<br>';
}
}
}
?>
And:
global $wp_filesystem;
$path = get_bloginfo('template_directory').'/images/myImages/';
$filelist = $wp_filesystem->dirlist( $path );
echo $filelist;
And:
$path = get_bloginfo('template_directory').'/images/myImages/';
$images = scandir( $path, 'svg', $depth = 0);
echo $images;
And:
$dir = get_bloginfo('template_directory').'/images/myImages/';
$files = scandir($dir);
print_r($files);
And:
$directory = get_bloginfo('template_directory')."/images/myImages/";
$images = glob($directory . "*.svg");
echo '<pre>';
print_r($images);
echo '</pre>';
echo $directory.'abnamro.svg">';
foreach($images as $image)
{
echo $image;
}
I'm kinda lost. I might think that there is something else wrong.
Also checked the privileges for the user but all is okay.
I run Wordpress on a local machine with MAMP.
Any thoughts?

Try the function below, I have notated for clarity. Some highlights are:
You can skip dots on outset in the directory iterator
You can trigger a fatal error if path doesn't exist (which is the issue in this case, you are using a domain-root path instead of the server root path [ABSPATH])
You can choose the extension type to filter files
function getPathsByKind($path,$ext,$err_type = false)
{
# Assign the error type, default is fatal error
if($err_type === false)
$err_type = E_USER_ERROR;
# Check if the path is valid
if(!is_dir($path)) {
# Throw fatal error if folder doesn't exist
trigger_error('Folder does not exist. No file paths can be returned.',$err_type);
# Return false incase user error is just notice...
return false;
}
# Set a storage array
$file = array();
# Get path list of files
$it = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path,RecursiveDirectoryIterator::SKIP_DOTS)
);
# Loop and assign paths
foreach($it as $filename => $val) {
if(strtolower(pathinfo($filename,PATHINFO_EXTENSION)) == strtolower($ext)) {
$file[] = $filename;
}
}
# Return the path list
return $file;
}
To use:
# Assign directory path
$directory = str_replace('//','/',ABSPATH.'/'.get_bloginfo('template_directory').'/images/myImages/');
# Get files
$files = getPathsByKind($directory,'svg');
# Check there are files
if(!empty($files)) {
print_r($files);
}
If the path doesn't exist, it will now tell you by way of system error that the path doesn't exist. If it doesn't throw a fatal error and comes up empty, then you actually do have some strange issue going on.
If all goes well, you should get something like:
Array
(
[0] => /data/19/2/133/150/3412/user/12321/htdocs/domain/images/myImages/img1.svg
[1] => /data/19/2/133/150/3412/user/12321/htdocs/domain/images/myImages/img2.svg
[2] => /data/19/2/133/150/3412/user/12321/htdocs/domain/images/myImages/img3.svg
[3] => /data/19/2/133/150/3412/user/12321/htdocs/domain/images/myImages/img4.svg
)
If path invalid, will throw:
Fatal error: Folder does not exist. No file paths can be returned. in /data/19/2/133/150/3412/user/12321/htdocs/domain/index.php on line 123

Related

Duplicate files in php

I am wondering how I can create a function that states:
if a file of name Setup.php exist twice in a folder and/or it's associated sub folders, return a message. if a file with the extension .css exists more then once in a folder or any of its sub folders, return a message
This function would have to be recursive, due to sub folders. and its fine to hard code 'Setup.php' or '.css' as they are the only things looked for.
What I currently have is a bit messy but does the trick (refactoring will come after I figure out this issue)
protected function _get_files($folder_name, $type){
$actual_dir_to_use = array();
$array_of_files[] = null;
$temp_array = null;
$path_info[] = null;
$array_of_folders = array_filter(glob(CUSTOM . '/' .$folder_name. '/*'), 'is_dir');
foreach($array_of_folders as $folders){
$array_of_files = $this->_fileHandling->dir_tree($folders);
if(isset($array_of_files) && !empty($array_of_files)){
foreach($array_of_files as $files){
$path_info = pathinfo($files);
if($type == 'css'){
if($path_info['extension'] == 'css'){
$actual_dir_to_use[] = $folders;
}
}
if($type == 'php'){
if($path_info['filename'] == 'Setup' && $path_info['extension'] == 'php'){
$temp_array[] = $folders;
$actual_dir_to_use[] = $folders;
}
}
}
}
$array_of_files = array();
$path_info = array();
}
return $actual_dir_to_use;
}
if you pass in say, packages and php into the function I will look through the packages folder and return all the sub-folder names, (eg: path/to/apples, path/to/bananas, path/to/fruit, path/to/cat, path/to/dog) that contain Setup with an extension of php.
The problem is if apples/ contains more then one Setup.php then I get: path/to/apples, path/to/apples, path/to/bananas, path/to/fruit, path/to/cat, path/to/dog
So I need to modify this function, or write a separate one, that sates the above sudo code.
problem? I don't know where to begin. So I am here asking for help.
You can find the class ipDirLiterator here - deleting all files in except the one running the delete code.
i hope you got it.
<?php
$directory = dirname( __FILE__ )."/test/";
$actual_dir_to_use = array();
$to_find = "php";
$literator = new ipDirLiterator( $directory, array( "file" => "file_literator", "dir" => "dir_literator" ) );
$literator->literate();
function file_literator( $file ) {
global $actual_dir_to_use, $to_find;
// use print_r( $file ) to see what all are inside $file
$filename = $file["filename"]; // the file name
$filepath = $file["pathname"]; // absolute path to file
$folder = $file["path"]; // the folder where the current file contains
$extens = strtolower( $file["extension"] );
if ( $to_find === "php" && $filename === "Setup.php" ) {
$actual_dir_to_use[] = $folder;
}
if ( $to_find === "css" && $extens === "css" ) {
$actual_dir_to_use[] = $folder;
}
}
function dir_literator( $file ) {}
print_r( $actual_dir_to_use );
// or check
if ( count( $actual_dir_to_use ) > 1 ) {
// here multiple files
}
?>
Q: Is this a homework assignment?
Assuming "no", then:
1) No, the function doesn't need to be recursive
2) Under Linux, you could find matching files like this: find /somefolder -name somefile -print
3) Similarly, you can detect if a match occurs zero, once or more than once in the path like this:
find /somefolder -name somefile -print|wc -l

unable to skip unreadable directories with RecursiveDirectoryIterator

I want to get a list of all the subdirectories and my below code works except when I have readonly permissions on certain folders.
In the below question it shows how to skip a directory with RecursiveDirectoryIterator
Can I make RecursiveDirectoryIterator skip unreadable directories? however my code is slightly different here and I am not able to get around the problem.
$path = 'www/';
foreach (new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path,RecursiveDirectoryIterator::KEY_AS_PATHNAME),
RecursiveIteratorIterator::CHILD_FIRST) as $file => $info)
{
if ($info->isDir())
{
echo $file . '<br>';
}
}
I get the error
Uncaught exception 'UnexpectedValueException' with message 'RecursiveDirectoryIterator::__construct(../../www/special): failed to open dir: Permission denied'
I have tried replacing it with the accepted answer in the other question.
new RecursiveIteratorIterator(
new RecursiveDirectoryIterator("."),
RecursiveIteratorIterator::LEAVES_ONLY,
RecursiveIteratorIterator::CATCH_GET_CHILD);
However this code will not give me a list of all the directories inside of www like I want, where am I going wrong here?
Introduction
The main issue with your code is using CHILD_FIRST
FROM PHP DOC
Optional mode. Possible values are
RecursiveIteratorIterator::LEAVES_ONLY - The default. Lists only leaves in iteration.
RecursiveIteratorIterator::SELF_FIRST - Lists leaves and parents in iteration with parents coming first.
RecursiveIteratorIterator::CHILD_FIRST - Lists leaves and parents in iteration with leaves coming first.
What you should use is SELF_FIRST so that the current directory is included. You also forgot to add optional parameters RecursiveIteratorIterator::CATCH_GET_CHILD
FROM PHP DOC
Optional flag. Possible values are RecursiveIteratorIterator::CATCH_GET_CHILD which will then ignore exceptions thrown in calls to RecursiveIteratorIterator::getChildren().
Your CODE Revisited
foreach (new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path,RecursiveDirectoryIterator::KEY_AS_PATHNAME),
RecursiveIteratorIterator::SELF_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD) as $file => $info)
{
if ($info->isDir())
{
echo $file . '<br>';
}
}
You really want CHILD_FIRST
If you really want to maintain the CHILD_FIRST structure then i suggest you use ReadableDirectoryIterator
Example
foreach ( new RecursiveIteratorIterator(
new ReadableDirectoryIterator($path),RecursiveIteratorIterator::CHILD_FIRST) as $file ) {
echo $file . '<br>';
}
Class Used
class ReadableDirectoryIterator extends RecursiveFilterIterator {
function __construct($path) {
if (!$path instanceof RecursiveDirectoryIterator) {
if (! is_readable($path) || ! is_dir($path))
throw new InvalidArgumentException("$path is not a valid directory or not readable");
$path = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS);
}
parent::__construct($path);
}
public function accept() {
return $this->current()->isReadable() && $this->current()->isDir();
}
}
function dirScan($dir, $fullpath = false){
$ignore = array(".","..");
if (isset($dir) && is_readable($dir)){
$dlist = array();
$dir = realpath($dir);
$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir,RecursiveDirectoryIterator::KEY_AS_PATHNAME),RecursiveIteratorIterator::SELF_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD);
foreach($objects as $entry){
if(!in_array(basename($entry), $ignore)){
if (!$fullpath){
$entry = str_replace($dir, '', $entry);
}
$dlist[] = $entry;
}
}
return $dlist;
}
}
This code works 100%...
You can simply use this function in order to scan for files and folders in your desired directory or drive. You just need to pass the path of the desired directory into the function. The second parameter of the function is to show full-path of the scanned files and folder. False value of the second parameter means not to show full-path.
The array $ignore is used to exclude any desired filename or foldername from the listing.
The function returns the array containing list of files and folders.
This function skips the files and folders that are unreadable while recursion.
I've set up the following directory structure:
/
test.php <-- the test script
www/
test1/ <-- permissions = 000
file1
test2/
file2
file3
I ran the following code (I've added the SKIP_DOTS flag to skip . and .. btw):
$i = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator("www", FilesystemIterator::SKIP_DOTS),
RecursiveIteratorIterator::LEAVES_ONLY,
RecursiveIteratorIterator::CATCH_GET_CHILD
);
print_r(iterator_to_array($i));
It outputs the following:
Array
(
[www/test2/file2] => SplFileInfo Object
(
[pathName:SplFileInfo:private] => www/test2/file2
[fileName:SplFileInfo:private] => file2
)
[www/file3] => SplFileInfo Object
(
[pathName:SplFileInfo:private] => www/file3
[fileName:SplFileInfo:private] => file3
)
)
This works as expected.
Update
Added the flags you've had in your original example (although I believe those are default anyway):
foreach (new RecursiveIteratorIterator(
new RecursiveDirectoryIterator("www", FilesystemIterator::SKIP_DOTS | FilesystemIterator::KEY_AS_PATHNAME),
RecursiveIteratorIterator::LEAVES_ONLY,
RecursiveIteratorIterator::CATCH_GET_CHILD | RecursiveIteratorIterator::CHILD_FIRST
) as $file => $info) {
echo $file, "\n";
print_r($info);
if ($info->isDir()) {
echo $file . '<br>';
}
}
Output:
www/test2/file2
SplFileInfo Object
(
[pathName:SplFileInfo:private] => www/test2/file2
[fileName:SplFileInfo:private] => file2
)
www/file3
SplFileInfo Object
(
[pathName:SplFileInfo:private] => www/file3
[fileName:SplFileInfo:private] => file3
)
<?php
$path = "D:/Movies";
$directory_iterator = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_PATHNAME);
$files = new RecursiveIteratorIterator($directory_iterator,
RecursiveIteratorIterator::SELF_FIRST,
RecursiveIteratorIterator::CATCH_GET_CHILD);
try {
foreach( $files as $fullFileName => $file) {
$path_parts = pathinfo($fullFileName);
if(is_file($fullFileName)){
$path_parts = pathinfo($fullFileName);
$fileName[] = $path_parts['filename'];
$extensionName[] = $path_parts['extension'];
$dirName[] = $path_parts['dirname'];
$baseName[] = $path_parts['basename'];
$fullpath[] = $fullFileName;
}
}
foreach ($fullpath as $filles){
echo $filles;
echo "</br>";
}
}
catch (UnexpectedValueException $e) {
printf("Directory [%s] contained a directory we can not recurse into", $directory);
}
?>
The glob function skips read errors automatically and should simplify your code a bit as well.
If you are getting unhandled exceptions, why don't you put that code in a try block, with an exception catch block to catch errors when it can't read directories? Just a simple suggestion by looking at your code and your problem. There is probably a neater way to do it in PHP.
You need to use SELF_FIRST constant if you want to return the unreadable directory name.
When you're doing CHILD_FIRST, it attempt to get into the directory, fails, and the current directory name is not included.
$path = 'testing';
$directory_iterator = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_PATHNAME);
$iterator = new RecursiveIteratorIterator($directory_iterator,
RecursiveIteratorIterator::SELF_FIRST,
RecursiveIteratorIterator::CATCH_GET_CHILD);
foreach ($iterator as $file => $info) {
if ($info->isDir()) {
echo $file . "\n";
}
}
What about try catch the UnexpectedValueException. Maybe there is even an unique exception code for that error you can check. Otherwise you can evil parse exception message for "permission denied".
I would suggest to examine the http://php.net/manual/de/class.unexpectedvalueexception.php

List Directories / Files in PHP Recursively and Ignore the ones in array

I'm trying to list directories recrusively in PHP using the RecursiveDirectoryIterator and RecursiveIteratorIterator, but the thing is, i need to ignore some directories and files within..
This is what i have so far..
// Define here the directory you have platform installed.
//
$path = 'testing';
// List of directories / files to be ignored.
//
$ignore_new = array(
# Directories
#
'.git',
'testing/dir1',
'testing/dir2',
'testing/dir3',
'testing/dir8',
'public',
# Files
#
'.gitignore',
'.gitmodules',
'.CHANGELOG.md',
'.README.md',
);
$ite = new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS);
foreach (new RecursiveIteratorIterator($ite) as $filename => $object)
{
echo $filename . '<br />';
}
I've tried different ways to check if the directory/file is in the array, but or it doesn't work, or the directory is not ignored completly...
This an example of the directory structure
testing\
testing\.git
testing\.git\files & directories
testing\testing\dir1
testing\testing\dir2
testing\testing\dir3
testing\testing\dir8
testing\.gitignore
testing\.gitmodules
testing\CHANGELOG.md
testing\README.md
Is this possible, or i need to use the old fashion way to recursive list directories/files in PHP ?
Thanks !
You should always use Full Path since you are combining file and folder
$path = __DIR__;
// List of directories / files to be ignored.
//
$ignoreDir = array('1.MOV.xml','.git','testing/dir1','testing/dir2','testing/dir3','testing/dir8','public');
/**
* Quick patch to add full path to Ignore
*/
$ignoreDir = array_map(function ($var) use($path) {
return $path . DIRECTORY_SEPARATOR . $var;
}, $ignoreDir);
$ite = new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS);
foreach ( new RecursiveIteratorIterator($ite) as $filename => $object ) {
if (in_array($filename, $ignoreDir))
continue;
echo $filename . '<br />';
}
Here is another approach using RecursiveCallbackFilterIterator:
<?php
$f_filter = function ($o_info) {
$s_file = $o_info->getFilename();
if ($s_file == '.git') {
return false;
}
if ($s_file == '.gitignore') {
return false;
}
return true;
};
$o_dir = new RecursiveDirectoryIterator('.');
$o_filter = new RecursiveCallbackFilterIterator($o_dir, $f_filter);
$o_iter = new RecursiveIteratorIterator($o_filter);
foreach ($o_iter as $o_info) {
echo $o_info->getPathname(), "\n";
}
https://php.net/class.recursivecallbackfilteriterator

Scan files in a directory and sub-directory and store their path in array using php

I want not scan all the files in a directory and its sub-directory. And get their path in an array. Like path to the file in the directory in array will be just
path -> text.txt
while the path to a file in sub-directory will be
somedirectory/text.txt
I am able to scan single directory, but it returns all the files and sub-directories without any ways to differentiate.
if ($handle = opendir('fonts/')) {
/* This is the correct way to loop over the directory. */
while (false !== ($entry = readdir($handle))) {
echo "$entry<br/>";
}
closedir($handle);
}
What is the best way to get all the files in the directory and sub-directory with its path?
Using the DirectoryIterator from SPL is probably the best way to do it:
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('.'));
foreach ($it as $file) echo $file."\n";
$file is an SPLFileInfo-object. Its __toString() method will give you the filename, but there are several other methods that are useful as well!
For more information see: http://www.php.net/manual/en/class.recursivedirectoryiterator.php
Use is_file() and is_dir():
function getDirContents($dir)
{
$handle = opendir($dir);
if ( !$handle ) return array();
$contents = array();
while ( $entry = readdir($handle) )
{
if ( $entry=='.' || $entry=='..' ) continue;
$entry = $dir.DIRECTORY_SEPARATOR.$entry;
if ( is_file($entry) )
{
$contents[] = $entry;
}
else if ( is_dir($entry) )
{
$contents = array_merge($contents, getDirContents($entry));
}
}
closedir($handle);
return $contents;
}

Gather image file paths Recursively in PHP

I am working on a pretty large PHP class that does a lot of stuff with Image Optimization from the Command line, you basically pass the program an Image path or a Folder path that has multiple images inside of it. It then runs the files through up to 5 other command line programs that optimize images.
Below is part of a loop that gathers the images paths, if the path is a Folder instead of an image path, it will iterate over all the images in the folder and add them to the image array.
So far I have everything working for single images and images in 1 folder. I would like to modify this section below so it could recursively go deeper then 1 folder to get the image paths.
Could someone possibly show me how I could modify this below to accomplish this?
// Get files
if (is_dir($path))
{
echo 'the path is a directory, grab images in this directory';
$handle = opendir($path);
// FIXME : need to run recursively
while(FALSE !== ($file = readdir($handle)))
{
if(is_dir($path.self::DS.$file))
{
continue;
}
if( ! self::is_image($path.self::DS.$file))
{
continue;
}
$files[] = $path.self::DS.$file;
}
closedir($handle);
}else{
echo 'the path is an Image and NOT a directory';
if(self::is_image($path))
{
echo 'assign image Paths to our image array to process = '. $path. '<br><br>';
$files[] = $path;
}
}
if (!count($files))
{
throw new NoImageFoundException("Image not found : $path");
}
UPDATE
#Chris's answer got me looking at the Docs and I found an example that I modified to this that seems to work
public static function find_recursive_images($path) {
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path),
RecursiveIteratorIterator::CHILD_FIRST);
foreach ($iterator as $path) {
if ($path->isDir()) {
//skip directories
continue;
} else {
$files[] = $path->__toString();
}
}
return $files;
}
...
$files = self::find_recursive_images($path);
echo '<pre>';
print_r($files);
echo '</pre>';
exit();
The output is JUST the filenames and there path like this which is my ultimate goal, so far this works perfect but as always if there is a better way I am all for improving
(
[0] => E:\Server\_ImageOptimize\img\testfiles\css3-generator.png
[1] => E:\Server\_ImageOptimize\img\testfiles\css3-please.png
[2] => E:\Server\_ImageOptimize\img\testfiles\css3-tools-10.png
[3] => E:\Server\_ImageOptimize\img\testfiles\fb.jpg
[4] => E:\Server\_ImageOptimize\img\testfiles\mysql.gif
[5] => E:\Server\_ImageOptimize\img\testfiles\OriginalImages\css3-generator.png
[6] => E:\Server\_ImageOptimize\img\testfiles\OriginalImages\css3-please.png
[7] => E:\Server\_ImageOptimize\img\testfiles\OriginalImages\css3-tools-10.png
[8] => E:\Server\_ImageOptimize\img\testfiles\OriginalImages\fb.jpg
[9] => E:\Server\_ImageOptimize\img\testfiles\OriginalImages\mysql.gif
[10] => E:\Server\_ImageOptimize\img\testfiles\OriginalImages\support-browsers.png
[11] => E:\Server\_ImageOptimize\img\testfiles\support-browsers.png
)
While andreas' answer probably works, you can also let PHP 5's RecursiveDirectoryIterator do that work for you and use a more OOP approach.
Here's a simple example:
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
while ($it->valid())
{
if ($it->isDot())
continue;
$file = $it->current();
if (self::is_image($file->pathName))
{
$files[] = $file->pathName;
}
$it->next();
}
Edit:
Alternatively, you could try this (copied from Zend_Translate_Adapter):
$it = new RecursiveIteratorIterator(
new RecursiveRegexIterator(
new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::KEY_AS_PATHNAME),
'/^(?!.*(\.svn|\.cvs)).*$/', RecursiveRegexIterator::MATCH
),
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($it as $dir => $info)
{
var_dump($dir);
}
Cheers
Chris
Create a recursive function to read a directory, then read further if a directory is found during the loop.
Something along the line of:
function r_readdir($path) {
static $files = array();
if(!is_dir($path)) {
echo 'the path is an Image and NOT a directory';
if(self::is_image($path))
{
echo 'assign image Paths to our image array to process = '. $path. '<br><br>';
$files[] = $path;
}
} else {
while(FALSE !== ($file = readdir($handle)))
{
if(is_dir($path.self::DS.$file))
{
r_readdir($path.self::DS.$file);
}
if( ! self::is_image($path.self::DS.$file))
{
continue;
}
}
closedir($handle);
}
return $files;
}

Categories