Gets files by relative or absolute path,
optionally creates missing files.

@param  array   $paths
@param  boolean $createMissing
@return Tarsana\Filesystem\Collection

@throws Tarsana\Filesystem\Exceptions\FilesystemException
508003
public function files($paths = false, $createMissing = false)
    {
        if ($paths === false) {
            return $this->find('*')->files();
        }

        $list = new Collection;
        foreach ($paths as $path) {
            $list->add($this->file($path, $createMissing));
        }
        return $list;
    }
163492
public function getRestorationFiles($path = null)
	{
		if ($path === null) {
			$path = $this->getPath();
		}

		$results = [];

		if (!$this->getBackupFilesystemInstance()->checkPathExists($path)) {
			throw new BackupException('Unable to get restoration files as path "' . $path . '" doesn\'t exist');
		}

		try {
			foreach (new DirectoryIterator($path) as $fileinfo) {
				if ($fileinfo->isDot() ||
					!$fileinfo->isFile() ||
					in_array($fileinfo->getFilename(), BackupFilesystem::$ignoredFiles) ||
					substr($fileinfo->getFilename(), 0, 1) == '.'
				) {
					continue;
				}

				$results[] = $fileinfo->getPathname();
			}
		} catch (Exception $exception) {
			// Exception thrown continue and return empty result set
		}

		return $results;
	}
472411
protected function sanitize($paths): Collection
    {
        return collect($paths)
            ->reject(function ($path) {
                return $path === '';
            })
            ->flatMap(function ($path) {
                return glob($path);
            })
            ->map(function ($path) {
                return realpath($path);
            })
            ->reject(function ($path) {
                return $path === false;
            });
    }
193397
public static function mergeAbsPath(array $paths): array
    {
        if (defined('ABSPATH')) {
            $dir = constant('ABSPATH');
            $path = trailingslashit($dir) . 'preflight.toml';

            $paths[] = normalize_path($path);
        }

        return $paths;
    }
1174784
public function getFolder($container, $path, $include_files = true, $include_folders = true, $full_tree = false)
    {
        $delimiter = ($full_tree) ? '' : '/';
        $resources = [];
        if ($this->containerExists($container)) {
            if (!empty($path)) {
                if (!$this->blobExists($container, $path)) {
                    // blob may not exist for "fake" folders, i.e. S3 prefixes
                    throw new NotFoundException("Folder '$path' does not exist in storage.");
                }
            }
            $results = $this->listBlobs($container, $path, $delimiter);
            foreach ($results as $data) {
                $fullPathName = array_get($data, 'name');
                $data['path'] = $fullPathName;
                $data['name'] = rtrim(substr($fullPathName, strlen($path)), '/');
                if ('/' == substr($fullPathName, -1)) {
                    // folders
                    if ($include_folders) {
                        $data['type'] = 'folder';
                        $resources[] = $data;
                    }
                } else {
                    // files
                    if ($include_files) {
                        $data['type'] = 'file';
                        $resources[] = $data;
                    }
                }
            }
        } else {
            if (!empty($path)) {
                throw new NotFoundException("Folder '$path' does not exist in storage.");
            }
            // container root doesn't really exist until first write creates it
        }

        return $resources;
    }
311848
public static function create($paths)
    {
        $backends = array(
            new Backend\Inotifywait($paths),
            new Backend\Fswatch($paths),
            new Backend\Watchmedo($paths),
            new Backend\Inotify($paths),
            new Backend\Poll($paths),
        );
        foreach ($backends as $b) {
            if ($b->isAvailable()) {
                $backend = $b;
                break;
            }
        }
        return $backend;
    }
505626
private function excludeSubPaths(array $paths) : array
    {
        if (empty($paths)) {
            return $paths;
        }
        sort($paths);
        $uniquePaths = [$paths[0]];
        for ($i = 1, $count = count($paths); $i < $count; ++$i) {
            $lastUniquePath = end($uniquePaths);
            assert($lastUniquePath !== false);

            if (strpos($paths[$i], $lastUniquePath) === 0) {
                continue;
            }

            $uniquePaths[] = $paths[$i];
        }

        return $uniquePaths;
    }
819659
protected function getFiles(string $relativeDir, array &$filesystem = []) : array
    {
        $fullDir = $this->getPath($relativeDir);

        $dirIterator = new FilesystemIterator($fullDir, FilesystemIterator::SKIP_DOTS);

        /** @var \SplFileInfo $info */
        foreach ($dirIterator as $info) {
            if ($info->isDir()) {
                $this->getFiles("{$relativeDir}/{$info->getFilename()}", $filesystem);
            } else {
                if (!isset($filesystem[$relativeDir])) {
                    $filesystem[$relativeDir] = [];
                }

                $filesystem[$relativeDir][] = $info->getFilename();
            }
        }

        return $filesystem;
    }
575881
public function getMigrationsDefinitions(array $paths = array())
    {
        // we try to be flexible in file types we support, and the same time avoid loading all files in a directory
        $handledDefinitions = array();
        foreach ($this->loader->listAvailableDefinitions($paths) as $migrationName => $definitionPath) {
            foreach ($this->DefinitionParsers as $definitionParser) {
                if ($definitionParser->supports($migrationName)) {
                    $handledDefinitions[] = $definitionPath;
                }
            }
        }

        // we can not call loadDefinitions with an empty array using the Filesystem loader, or it will start looking in bundles...
        if (empty($handledDefinitions) && !empty($paths)) {
            return new MigrationDefinitionCollection();
        }

        return $this->loader->loadDefinitions($handledDefinitions);
    }
550084
public function processMultiplePaths($paths)
    {
        $paths = $this->parseAsArray($paths);
        $paths = array_map([ $this, 'filterPath' ], $paths);
        $paths = array_filter($paths, [ $this, 'pathExists' ]);

        if ($paths === false) {
            throw new InvalidArgumentException('Received invalid paths.');
        }

        if (empty($paths)) {
            throw new InvalidArgumentException('Received empty paths.');
        }

        return $paths;
    }
338089
public static function formatDirectory($pathOrPaths, ...$additionalPaths)
    {
        $directory = self::formatPath($pathOrPaths, ...$additionalPaths);

        if ($directory) {
            $directory = rtrim($directory, "/") . "/";
        }

        return $directory;
    }
193701
private function createFilesIterator(string ...$paths): Iterator
    {
        return new ArrayIterator(
            array_map(
                function (string $path) : SplFileInfo {
                    return new SplFileInfo($path);
                },
                array_filter(
                    $paths,
                    function (string $path) : bool {
                        return is_readable($path);
                    }
                )
            )
        );
    }
347348
protected function getFiles(array $files)
    {
        $filesEntity = [];

        foreach ($files as $file) {
            $filesEntity[] = new File($file);
        }

        return $filesEntity;
    }
141423
protected function buildCollection(array $sources, array $extensions)
    {
        $collection = new Collection();
        $collection->setAllowedExtensions($extensions);
        foreach ($sources as $path) {
            if (is_dir($path)) {
                $collection->addDirectory($path);
                continue;
            }

            $collection->addFile($path);
        }

        return $collection;
    }
813424
public function getFileByName(
       $folderName,
       $mimeType,
       $includeTrash = false,
       \Google_Service_Drive_DriveFile $parent = null,
       $createIfNotFound = false
    ) {
        $query = 'title = \'' . $folderName . '\' and mimeType = \'' . $mimeType . '\'';
        if (!$includeTrash) {
            $query .= ' and trashed = false';
        }
        if ($parent !== null) {
            $query .= ' and \'' . $parent->getId() . '\' in parents';
        }
        $fileList = $this->service->files->listFiles(array('q' => $query));
        $folders   = $fileList->getItems();
        if (isset($folders[0])) {
            return $folders[0];
        }
        if ($createIfNotFound) {
            $this->helper->getLogger()->debug('Creating Folder ' . $folderName);
            return $this->createFolder($folderName, $parent);
        }

        return null;
    }
1359761
public function sharedFilesAndDirs(array $paths = []): self
    {
        $this->sharedDirs = [];
        $this->sharedFiles = [];

        foreach ($paths as $path) {
            $this->validatePathIsRelativeToProject($path, __METHOD__);
            if (is_dir($this->localProjectDir.DIRECTORY_SEPARATOR.$path)) {
                $this->sharedDirs[] = rtrim($path, DIRECTORY_SEPARATOR);
            } else {
                $this->sharedFiles[] = $path;
            }
        }

        return $this;
    }
1220322
public function getMigrationFiles($paths = [], $recursive = true)
    {
        if ($recursive) {
            $paths = $this->getRecursiveFolders($paths);
        }

        $files = parent::getMigrationFiles($paths);

        return $files;
    }