diff --git a/actions/DisplayAction.php b/actions/DisplayAction.php index 52853d36..94416639 100644 --- a/actions/DisplayAction.php +++ b/actions/DisplayAction.php @@ -240,7 +240,6 @@ class DisplayAction extends ActionAbstract { // Data transformation try { $formatFac = new FormatFactory(); - $formatFac->setWorkingDir(PATH_LIB_FORMATS); $format = $formatFac->create($format); $format->setItems($items); $format->setExtraInfos($infos); diff --git a/formats/HtmlFormat.php b/formats/HtmlFormat.php index b3f02099..12b5fc3a 100644 --- a/formats/HtmlFormat.php +++ b/formats/HtmlFormat.php @@ -11,7 +11,6 @@ class HtmlFormat extends FormatAbstract { // Dynamically build buttons for all formats (except HTML) $formatFac = new FormatFactory(); - $formatFac->setWorkingDir(PATH_LIB_FORMATS); $buttons = ''; $links = ''; diff --git a/lib/BridgeList.php b/lib/BridgeList.php index 4aca037c..3b6d832e 100644 --- a/lib/BridgeList.php +++ b/lib/BridgeList.php @@ -66,7 +66,6 @@ EOD; $bridgeList = $bridgeFac->getBridgeNames(); $formatFac = new FormatFactory(); - $formatFac->setWorkingDir(PATH_LIB_FORMATS); $formats = $formatFac->getFormatNames(); $totalBridges = count($bridgeList); diff --git a/lib/FormatFactory.php b/lib/FormatFactory.php index c5024e15..2044a899 100644 --- a/lib/FormatFactory.php +++ b/lib/FormatFactory.php @@ -11,140 +11,60 @@ * @link https://github.com/rss-bridge/rss-bridge */ -/** - * Factory class responsible for creating format objects from a given working - * directory. - * - * This class is capable of: - * - Locating format classes in the specified working directory (see {@see Format::$workingDir}) - * - Creating new format instances based on the format's name (see {@see Format::create()}) - * - * The following example illustrates the intended use for this class. - * - * ```PHP - * require_once __DIR__ . '/rssbridge.php'; - * - * // Step 1: Set the working directory - * Format::setWorkingDir(__DIR__ . '/../formats/'); - * - * // Step 2: Create a new instance of a format object (based on the name) - * $format = Format::create('Atom'); - * ``` - */ -class FormatFactory extends FactoryAbstract { +class FormatFactory +{ + private $folder; + private $formatNames; + + public function __construct(string $folder = PATH_LIB_FORMATS) + { + $this->folder = $folder; + + // create format names + foreach(scandir($this->folder) as $file) { + if(preg_match('/^([^.]+)Format\.php$/U', $file, $m)) { + $this->formatNames[] = $m[1]; + } + } + } + /** - * Creates a new format object from the working directory. - * - * @throws \InvalidArgumentException if the requested format name is invalid. - * @throws \Exception if the requested format file doesn't exist in the - * working directory. - * @param string $name Name of the format object. - * @return object|bool The format object or false if the class is not instantiable. + * @throws \InvalidArgumentException + * @param string $name The name of the format e.g. "Atom", "Mrss" or "Json" */ - public function create($name){ - if(!$this->isFormatName($name)) { + public function create(string $name): FormatInterface + { + if (! preg_match('/^[a-zA-Z0-9-]*$/', $name)) { throw new \InvalidArgumentException('Format name invalid!'); } - $name = $this->sanitizeFormatName($name); - - if (is_null($name)) { + if ($name === null) { throw new \InvalidArgumentException('Unknown format given!'); } - - $name .= 'Format'; - $pathFormat = $this->getWorkingDir() . $name . '.php'; - - if(!file_exists($pathFormat)) { - throw new \Exception('Format file ' . $filePath . ' does not exist!'); - } - - if((new \ReflectionClass($name))->isInstantiable()) { - return new $name(); - } - - return false; + $className = '\\' . $name . 'Format'; + return new $className; } - /** - * Returns true if the provided name is a valid format name. - * - * A valid format name starts with a capital letter ([A-Z]), followed by - * zero or more alphanumeric characters or hyphen ([A-Za-z0-9-]). - * - * @param string $name The format name. - * @return bool true if the name is a valid format name, false otherwise. - */ - public function isFormatName($name){ - return is_string($name) && preg_match('/^[a-zA-Z0-9-]*$/', $name) === 1; + public function getFormatNames(): array + { + return $this->formatNames; } - /** - * Returns the list of format names from the working directory. - * - * The list is cached internally to allow for successive calls. - * - * @return array List of format names - */ - public function getFormatNames(){ - static $formatNames = array(); // Initialized on first call - - if(empty($formatNames)) { - $files = scandir($this->getWorkingDir()); - - if($files !== false) { - foreach($files as $file) { - if(preg_match('/^([^.]+)Format\.php$/U', $file, $out)) { - $formatNames[] = $out[1]; - } - } - } - } - - return $formatNames; - } - - /** - * Returns the sanitized format name. - * - * The format name can be specified in various ways: - * * The PHP file name (i.e. `AtomFormat.php`) - * * The PHP file name without file extension (i.e. `AtomFormat`) - * * The format name (i.e. `Atom`) - * - * A format file matching the given format name must exist in the working - * directory! - * - * @param string $name The format name - * @return string|null The sanitized format name if the provided name is - * valid, null otherwise. - */ - protected function sanitizeFormatName($name) { + protected function sanitizeFormatName(string $name) { $name = ucfirst(strtolower($name)); - if(is_string($name)) { - - // Trim trailing '.php' if exists - if(preg_match('/(.+)(?:\.php)/', $name, $matches)) { - $name = $matches[1]; - } - - // Trim trailing 'Format' if exists - if(preg_match('/(.+)(?:Format)/i', $name, $matches)) { - $name = $matches[1]; - } - - // The name is valid if a corresponding format file is found on disk - if(in_array($name, $this->getFormatNames())) { - $index = array_search($name, $this->getFormatNames()); - return $this->getFormatNames()[$index]; - } - - Debug::log('Invalid format name: "' . $name . '"!'); - + // Trim trailing '.php' if exists + if (preg_match('/(.+)(?:\.php)/', $name, $matches)) { + $name = $matches[1]; } - return null; // Bad parameter - + // Trim trailing 'Format' if exists + if (preg_match('/(.+)(?:Format)/i', $name, $matches)) { + $name = $matches[1]; + } + if (in_array($name, $this->formatNames)) { + return $name; + } + return null; } } diff --git a/tests/Formats/BaseFormatTest.php b/tests/Formats/BaseFormatTest.php index dac0e341..94da7b04 100644 --- a/tests/Formats/BaseFormatTest.php +++ b/tests/Formats/BaseFormatTest.php @@ -53,7 +53,6 @@ abstract class BaseFormatTest extends TestCase { protected function formatData(string $formatName, \stdClass $sample): string { $formatFac = new FormatFactory(); - $formatFac->setWorkingDir(PATH_LIB_FORMATS); $format = $formatFac->create($formatName); $format->setItems($sample->items); $format->setExtraInfos($sample->meta);