xref: /plugin/totext/Extractor/ExtractorFactory.php (revision 0fbee1892eb8b7339ce48e27e48e3fc821a8695f)
1<?php
2
3namespace dokuwiki\plugin\totext\Extractor;
4
5use dokuwiki\plugin\totext\Exception\UnsupportedFormatException;
6
7/**
8 * Picks the right extractor for a file based on its extension.
9 */
10class ExtractorFactory
11{
12    /**
13     * Maps each supported file extension to its extractor class.
14     *
15     * This is the single source of truth for the formats the plugin handles and
16     * the only routing authority: forFile() looks a file's extension up here and
17     * supportedExtensions() lists the keys. Add a format with one new extractor
18     * class plus one entry below.
19     *
20     * @var array<string, class-string<ExtractorInterface>>
21     */
22    protected const EXTRACTORS = [
23        'docx' => DocxExtractor::class,
24        'xlsx' => XlsxExtractor::class,
25        'pptx' => PptxExtractor::class,
26        'odt' => OdtExtractor::class,
27        'ods' => OdsExtractor::class,
28        'odp' => OdpExtractor::class,
29        'pdf' => PdfExtractor::class,
30        'txt' => TextExtractor::class,
31        'csv' => TextExtractor::class,
32        'md' => TextExtractor::class,
33        'markdown' => TextExtractor::class,
34        'log' => TextExtractor::class,
35        'text' => TextExtractor::class,
36        'jpg' => ImageExtractor::class,
37        'jpeg' => ImageExtractor::class,
38        'tif' => ImageExtractor::class,
39        'tiff' => ImageExtractor::class,
40    ];
41
42    /**
43     * Return an Extractor for the given file, based on its extension.
44     *
45     * @param string $path file name or path
46     * @return ExtractorInterface
47     * @throws UnsupportedFormatException if the extension is not recognised
48     */
49    public static function forFile(string $path): ExtractorInterface
50    {
51        $ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
52        if (!isset(self::EXTRACTORS[$ext])) {
53            throw new UnsupportedFormatException(
54                $ext === ''
55                    ? "Cannot determine format: no file extension on $path"
56                    : "Unsupported file extension: .$ext",
57            );
58        }
59        $class = self::EXTRACTORS[$ext];
60        return new $class();
61    }
62
63    /**
64     * Convenience: pick the right extractor and run it.
65     *
66     * @param string $path absolute path to the file
67     * @return ExtractionResult the extracted body text and canonical metadata
68     * @throws \dokuwiki\plugin\totext\Exception\ExtractionException on failure or unsupported format
69     */
70    public static function extract(string $path): ExtractionResult
71    {
72        return self::forFile($path)->extract($path);
73    }
74
75    /**
76     * List all file extensions this factory can route to an extractor.
77     *
78     * @return string[] supported extensions (without leading dot)
79     */
80    public static function supportedExtensions(): array
81    {
82        return array_keys(self::EXTRACTORS);
83    }
84}
85