Separation of concerns
This commit is contained in:
42
src/IO/Filesystem/Directory.php
Normal file
42
src/IO/Filesystem/Directory.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace IO\Filesystem;
|
||||
|
||||
use IO\Exception\DirectoryNotFoundException;
|
||||
use IO\Exception\DirectoryNotReadableException;
|
||||
use IO\Exception\NotADirectoryException;
|
||||
|
||||
class Directory
|
||||
{
|
||||
private string $directory;
|
||||
|
||||
private function __construct(string $directory)
|
||||
{
|
||||
$this->directory = rtrim($directory, DIRECTORY_SEPARATOR);
|
||||
$this->guardUnusableDirectory($directory);
|
||||
$this->directory = realpath($directory);
|
||||
}
|
||||
|
||||
public static function fromString(?string $directory): self
|
||||
{
|
||||
return new self($directory ?? getcwd());
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->directory;
|
||||
}
|
||||
|
||||
private function guardUnusableDirectory(string $directory): void
|
||||
{
|
||||
if (!file_exists($directory)) {
|
||||
throw new DirectoryNotFoundException($directory);
|
||||
}
|
||||
if (!is_dir($directory)) {
|
||||
throw new NotADirectoryException($directory);
|
||||
}
|
||||
if (!is_readable($directory)) {
|
||||
throw new DirectoryNotReadableException($directory);
|
||||
}
|
||||
}
|
||||
}
|
||||
44
src/IO/Filesystem/File.php
Normal file
44
src/IO/Filesystem/File.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace IO\Filesystem;
|
||||
|
||||
use IO\Exception\FileNotFoundException;
|
||||
use IO\Exception\FileNotReadableException;
|
||||
use SplFileInfo;
|
||||
|
||||
class File
|
||||
{
|
||||
private SplFileInfo $info;
|
||||
|
||||
private function __construct(string $filepath)
|
||||
{
|
||||
$this->guardUnusableFile($filepath);
|
||||
$filepath = realpath($filepath);
|
||||
$this->info = new SplFileInfo($filepath);
|
||||
}
|
||||
|
||||
public static function fromString(string $filepath): self
|
||||
{
|
||||
return new self($filepath);
|
||||
}
|
||||
|
||||
public function getInfo(): SplFileInfo
|
||||
{
|
||||
return $this->info;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return (string)$this->getInfo();
|
||||
}
|
||||
|
||||
private function guardUnusableFile(string $file): void
|
||||
{
|
||||
if (!file_exists($file)) {
|
||||
throw new FileNotFoundException($file);
|
||||
}
|
||||
if (!is_readable($file)) {
|
||||
throw new FileNotReadableException($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,13 +4,13 @@ namespace IO\Input;
|
||||
|
||||
trait ArgvAccess
|
||||
{
|
||||
protected static function getArguments(): array
|
||||
protected static function getScriptArgs(): array
|
||||
{
|
||||
// Get local copy of $argv
|
||||
// local copy of $argv
|
||||
global $argv;
|
||||
$arguments = $argv;
|
||||
|
||||
// Lose the script name
|
||||
// shift off the script name
|
||||
array_shift($arguments);
|
||||
|
||||
return $arguments;
|
||||
|
||||
@@ -3,38 +3,32 @@
|
||||
namespace IO\Input;
|
||||
|
||||
use Filter\DocumentFilter;
|
||||
use Filter\FilterFactory;
|
||||
use IO\Exception\DirectoryNotFoundException;
|
||||
use IO\Exception\DirectoryNotReadableException;
|
||||
use IO\Exception\NotADirectoryException;
|
||||
use Filter\FilterParser;
|
||||
use IO\Filesystem\Directory;
|
||||
|
||||
class FinderArguments
|
||||
{
|
||||
use ArgvAccess;
|
||||
|
||||
private ?string $directory;
|
||||
private Directory $directory;
|
||||
private array $filters;
|
||||
|
||||
public static function createFromGlobals(): self
|
||||
{
|
||||
$arguments = self::getArguments();
|
||||
$arguments = self::getScriptArgs();
|
||||
$directory = array_shift($arguments);
|
||||
|
||||
$dir = array_shift($arguments) ?? getcwd();
|
||||
$dir = rtrim($dir, DIRECTORY_SEPARATOR);
|
||||
|
||||
return new self($dir, $arguments);
|
||||
return new self($directory, $arguments);
|
||||
}
|
||||
|
||||
public function __construct(?string $directory, array $filters)
|
||||
{
|
||||
$this->guardUnusableDirectory($directory);
|
||||
$this->directory = realpath($directory);
|
||||
|
||||
$factory = new FilterFactory();
|
||||
$this->filters = array_map([$factory, 'createFromString'], $filters);
|
||||
$factory = new FilterParser();
|
||||
$this->directory = Directory::fromString($directory);
|
||||
$this->filters = array_map([$factory, 'parse'], $filters);
|
||||
}
|
||||
|
||||
public function getDirectory(): string
|
||||
public function getDirectory(): Directory
|
||||
{
|
||||
return $this->directory;
|
||||
}
|
||||
@@ -46,17 +40,4 @@ class FinderArguments
|
||||
{
|
||||
return $this->filters;
|
||||
}
|
||||
|
||||
private function guardUnusableDirectory(string $directory): void
|
||||
{
|
||||
if (!file_exists($directory)) {
|
||||
throw new DirectoryNotFoundException($directory);
|
||||
}
|
||||
if (!is_dir($directory)) {
|
||||
throw new NotADirectoryException($directory);
|
||||
}
|
||||
if (!is_readable($directory)) {
|
||||
throw new DirectoryNotReadableException($directory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,44 +2,31 @@
|
||||
|
||||
namespace IO\Input;
|
||||
|
||||
use IO\Exception\FileNotFoundException;
|
||||
use IO\Exception\FileNotReadableException;
|
||||
use IO\Exception\MissingFileArgumentException;
|
||||
use SplFileInfo;
|
||||
use IO\Filesystem\File;
|
||||
|
||||
class ShowInfoArguments
|
||||
{
|
||||
use ArgvAccess;
|
||||
|
||||
private SplFileInfo $file;
|
||||
private File $file;
|
||||
|
||||
public static function createFromGlobals(): self
|
||||
{
|
||||
$arguments = self::getArguments();
|
||||
$arguments = self::getScriptArgs();
|
||||
return new self(array_shift($arguments));
|
||||
}
|
||||
|
||||
public function __construct(?string $file)
|
||||
public function __construct(?string $filepath)
|
||||
{
|
||||
$this->guardUnusableFile($file);
|
||||
$this->file = new SplFileInfo($file);
|
||||
if (is_null($filepath)) {
|
||||
throw new MissingFileArgumentException();
|
||||
}
|
||||
$this->file = File::fromString($filepath);
|
||||
}
|
||||
|
||||
public function getFile(): SplFileInfo
|
||||
public function getFile(): File
|
||||
{
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
private function guardUnusableFile(string $file): void
|
||||
{
|
||||
if (is_null($file)) {
|
||||
throw new MissingFileArgumentException();
|
||||
}
|
||||
if (!file_exists($file)) {
|
||||
throw new FileNotFoundException($file);
|
||||
}
|
||||
if (!is_readable($file)) {
|
||||
throw new FileNotReadableException($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,16 +5,16 @@ namespace IO\Output;
|
||||
use PDF\Document;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class DocumentOutput implements Output
|
||||
class DocumentDetails implements Output
|
||||
{
|
||||
private Document $document;
|
||||
|
||||
public function __construct(Document $document)
|
||||
private function __construct(Document $document)
|
||||
{
|
||||
$this->document = $document;
|
||||
}
|
||||
|
||||
public static function forDocument(Document $document): self
|
||||
public static function of(Document $document): self
|
||||
{
|
||||
return new self($document);
|
||||
}
|
||||
@@ -5,17 +5,17 @@ namespace IO\Output;
|
||||
use PDF\Document;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class DocumentListingOutput implements Output
|
||||
class DocumentListing implements Output
|
||||
{
|
||||
/** @var Document[] */
|
||||
private iterable $documents;
|
||||
|
||||
public function __construct(iterable $documents)
|
||||
private function __construct(iterable $documents)
|
||||
{
|
||||
$this->documents = $documents;
|
||||
}
|
||||
|
||||
public static function forDocuments(iterable $documents): self
|
||||
public static function of(iterable $documents): self
|
||||
{
|
||||
return new self($documents);
|
||||
}
|
||||
@@ -55,10 +55,10 @@ class DocumentListingOutput implements Output
|
||||
|
||||
foreach ($this->documents as $document) {
|
||||
$template->addRow([
|
||||
$document->file->getBasename(),
|
||||
$document->file->getInfo()->getBasename(),
|
||||
$document->metadata->title,
|
||||
$document->metadata->author,
|
||||
$document->file->getPath(),
|
||||
$document->file->getInfo()->getPath(),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -13,13 +13,11 @@ class Pdfinfo
|
||||
$lines = $this->shellExec('pdfinfo', '-isodates', $filepath);
|
||||
|
||||
$data = [];
|
||||
foreach ($lines as $line) {
|
||||
$parts = explode(':', $line, 2);
|
||||
if (count($parts) === 2) {
|
||||
$data[trim($parts[0])] = trim($parts[1]);
|
||||
}
|
||||
}
|
||||
collect($lines)
|
||||
->map(fn(string $line) => explode(':', $line, 2))
|
||||
->filter(fn(array $parts) => count($parts) === 2)
|
||||
->each(fn(array $parts) => $data[trim($parts[0])] = trim($parts[1]));
|
||||
|
||||
return (new Metadata)->fillWith($data);
|
||||
return Metadata::fill($data);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user