boondoc/path-list

A trait for attaching simple lists of verified filesystem paths to a class for iteration.

1.1.5 2024-02-28 05:39 UTC

This package is not auto-updated.

Last update: 2024-04-24 06:16:28 UTC


README

Boondoc/PathList is a trait for attaching simple lists of verified filesystem paths to a class for iteration.

Both static and non-static methods are included, allowing instances of a class to iterate over a private list of paths, a list shared among all other instances of its kind, or a combination of both.

Alternatives

This project has an intentionally narrow scope, and may not be what you’re looking for.

  • If you want to create, delete or otherwise manipulate files or directories, you probably want symfony/filesystem (see Filesystem Utilities for more information).
  • If you want to perform sensible string manipulations on path-like strings, such as convert between absolute and relative file paths, but are not concerned with whether those paths are genuine filesystem locations on the server, you also probably want symfony/filesystem (see Path Manipulation Utilities for more information).

Installation

With Composer:

composer require boondoc/path-list

Manual Installation:

Download the file path-list.php and include it in your code with a require statement.

Usage

Import the trait:

use Boondoc\PathList;

Add it to your class:

class EG
{
	use PathList;
};

For the following examples, assume a directory structure like so:

/
+-- alpha
+-- bravo
|   +-- charlie
|   +-- delta		// Code is being executed here
+-- echo
+-- foxtrot
|   +-- golf
|   +-- hotel
|       +-- india
+-- juliet
    +-- kilo
        +-- lima.txt

Static path collection:

Pass an array of paths statically to have them shared across all class instances.

EG::pathsSet (['../charlie', '/xray', '/foxtrot/hotel/india']);
					// Two of three supplied paths actually exist
					// Non-existent path is discarded, others are canonicalised

EG::pathsGet ();			// Returns ['/bravo/charlie', '/foxtrot/hotel/india']

EG::pathsHas ('../charlie');		// Returns '/bravo/charlie'
EG::pathsHas ('/xray');			// Returns false
EG::pathsHas ('/alpha');		// Returns false

EG::pathsSet (['/xray']);		// Throws a Boondoc\PathList\NoRealPathsSupplied exception
EG::pathsSet ([]);			// Empty array clears collection, no exception thrown

EG::pathsHas ('../charlie');		// Returns false

All path strings are automatically passed through realpath, and those which return false are discarded. If all paths in the array fail to resolve, an exception is thrown.

Where multiple path strings resolve to the same absolute filesystem location, only the first is kept, and the rest are discarded.

Non-static path collection:

Pass an array of paths to a class to keep them private to that class.

$a = new EG ();
$b = new EG ();

$a->pathsSetOwn (['../../alpha', '/september', '/foxtrot/hotel/india']);
$b->pathsSetOwn (['/echo', '/zulu', '/echo']);

$a->pathsGetOwn ();			// Returns ['/alpha', '/foxtrot/hotel/india']
$b->pathsGetOwn ();			// Returns ['/echo']

$a->pathsHasOwn ('../../alpha');	// Returns '/alpha'
$a->pathsHasOwn ('/echo');		// Returns false
$a->pathsHasOwn ('/bravo');		// Returns false
$b->pathsHasOwn ('../../alpha');	// Returns false
$b->pathsHasOwn ('/echo');		// Returns '/echo'
$b->pathsHasOwn ('/bravo');		// Returns false

Arrays passed to ->pathsSetOwn are otherwise treated identically to those passed to ::pathsSet.

Combined path collection:

Once the static and/or non-static collection are defined, they can retrieved as a single combined array. Paths from the non-static collection will appear in the array first, followed by those from the static collection. Where paths appear in both collections, the non-static appearance will form part of the combined array, and the duplicate from the static collection will be omitted.

$a = new EG ();
$b = new EG ();
$c = new EG ();

EG::pathsSet (['../charlie', '/xray', '/foxtrot/hotel/india']);
$a->pathsSetOwn (['../../alpha', '/september', '/foxtrot/hotel/india']);
$b->pathsSetOwn (['/echo', '/zulu', '/echo']);

$a->pathsGetAll ():			// Returns ['/alpha', '/foxtrot/hotel/india', '/bravo/charlie']
$b->pathsGetAll ();			// Returns ['/echo', '/bravo/charlie', '/foxtrot/hotel/india']
$c->pathsGetAll ();			// Returns ['/bravo/charlie', '/foxtrot/hotel/india']

$a->pathsHasAll ('../../alpha');	// Returns '/alpha'
$a->pathsHasAll ('../charlie');		// Returns '/bravo/charlie'
$a->pathsHasAll ('/echo');		// Returns false
$b->pathsHasAll ('../../alpha');	// Returns false
$a->pathsHasAll ('../charlie');		// Returns '/bravo/charlie'
$b->pathsHasAll ('/echo');		// Returns '/echo'
$c->pathsHasAll ('../../alpha');	// Returns false
$c->pathsHasAll ('../charlie');		// Returns '/bravo/charlie'
$c->pathsHasAll ('/echo');		// Returns false

File finding

The collections can be queried to see if a given sub-path string resolves to a real filename in any of the paths, and if so returns the fully-resolved filesystem location.

$a = new EG ();

EG::pathsSet (['/juliet/kilo']);

$a->pathsFind ('lima.txt');		// Returns '/juliet/kilo/lima.txt'
$a->pathsFind ('kilo/lima.txt');	// Returns false

$a->pathsFindOwn ('lima.txt');		// Returns false
$a->pathsFindOwn ('kilo/lima.txt');	// Returns false

$a->pathsFindAll ('lima.txt');		// Returns '/juliet/kilo/lima.txt'
$a->pathsFindAll ('kilo/lima.txt');	// Returns false

EG::pathsSet ([]);
$a->pathsSetOwn (['/juliet']);

$a->pathsFind ('lima.txt');		// Returns false
$a->pathsFind ('kilo/lima.txt');	// Returns false

$a->pathsFindOwn ('lima.txt');		// Returns false
$a->pathsFindOwn ('kilo/lima.txt');	// Returns '/juliet/kilo/lima.txt'

$a->pathsFindAll ('lima.txt');		// Returns false
$a->pathsFindAll ('kilo/lima.txt');	// Returns '/juliet/kilo/lima.txt'

Note that this is not a full recursive filename search: the supplied sub-path string is directly appended to each path in the collection and tested to see if such a filesystem object exists, returning the first success as a string, or false if none are found.

Exceptions

During normal operation, the following exceptions may be thrown:

  • \Boondoc\PathList\NoRealPathsSupplied: None of the paths supplied to ::pathsSet or ->pathsSetOwn could be resolved to a genuine filesystem location.
  • \Boondoc\PathList\Exception: Abstract type, never thrown explicitly; catch to encompass all of the above.

These exceptions are for catching only, and should never need to be thrown explicitly.

All of the above exceptions feature a new method, ->getValue (), which returns the offending value without the rest of the message string.