xref: /plugin/cachestats/cli.php (revision c25debc6bd808a17b10cab0771c0153188c1e6cf)
1<?php
2
3use dokuwiki\plugin\cachestats\FileStatistics;
4use splitbrain\phpcli\Options;
5use splitbrain\phpcli\TableFormatter;
6
7/**
8 * DokuWiki Plugin cachestats (CLI Component)
9 *
10 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
11 * @author  Andreas Gohr <andi@splitbrain.org>
12 */
13class cli_plugin_cachestats extends \dokuwiki\Extension\CLIPlugin
14{
15    /** @inheritDoc */
16    protected function setup(Options $options)
17    {
18        $options->setHelp('Collect statistics about the cache directory.');
19
20        $options->registerOption('format', 'Output format: table|json|csv', 'f', 'table');
21        $options->registerOption('sort', 'Sort by count|size|dups', 's', false);
22    }
23
24    /** @inheritDoc */
25    protected function main(Options $options)
26    {
27        global $conf;
28
29        $sort = $options->getOpt('sort', 'size');
30        if (!in_array($sort, ['count', 'size', 'dups'])) {
31            $this->error("Invalid sort option '$sort'. Allowed are: count, size, dups.");
32            return 1;
33        }
34
35        $format = $options->getOpt('format', 'table');
36        if (!in_array($format, ['table', 'json', 'csv'])) {
37            $this->error("Invalid format option '$format'. Allowed are: table, json, csv.");
38            return 1;
39        }
40
41        if ($format === 'json') {
42            fprintf(STDERR, 'Collecting cache statistics from ' . $conf['cachedir'] . "…\n");
43        } else {
44            $this->info('Collecting cache statistics from ' . $conf['cachedir'] . '…');
45        }
46
47        $result = (new FileStatistics($conf['cachedir']))->collect();
48
49        // sort with preserved keys
50        uasort($result, function ($a, $b) use ($sort) {
51            return $b[$sort] <=> $a[$sort];
52        });
53
54        match ($format) {
55            'json' => $this->print_json($result),
56            'csv' => $this->print_csv($result),
57            default => $this->print_table($result),
58        };
59        return 0;
60    }
61
62    /**
63     * Output statistics as JSON
64     */
65    private function print_json(array $result): void
66    {
67        echo json_encode($result, JSON_PRETTY_PRINT);
68    }
69
70    /**
71     * Output statistics as CSV
72     */
73    private function print_csv(array $result): void
74    {
75        $handle = fopen('php://output', 'w');
76        if ($handle === false) {
77            $this->error('Could not open output for CSV.');
78            return;
79        }
80
81        $header = array_merge(['extension'], array_keys(reset($result)));
82        fputcsv($handle, $header);
83
84        foreach ($result as $ext => $data) {
85            fputcsv($handle, array_merge([$ext], $data));
86        }
87    }
88
89    /**
90     * Output statistics as table
91     */
92    private function print_table(array $result): void
93    {
94        $colWidth = 9;
95
96        $headers = array_merge(['ext'], array_keys(reset($result)));
97        $widths = array_merge(['*'], array_fill(0, count($headers) -1, $colWidth));
98        $colors = array_fill(0, count($headers), '');
99
100        // ensure terminal is wide enough, otherwise break ugly
101        $tr = new TableFormatter($this->colors);
102        if($tr->getMaxWidth() < $colWidth * count($headers)){;
103            $tr->setMaxWidth($colWidth * count($headers) + 10);
104        }
105
106        echo $tr->format($widths, $headers, $colors);
107
108        foreach ($result as $ext => $data) {
109            array_walk(
110                $data,
111                fn (&$v, $k) => $v = sprintf(
112                    "% ${colWidth}s",
113                    ($k == 'size') ? filesize_h($v) : number_format($v)
114                )
115            );
116
117            echo $tr->format(
118                $widths,
119                array_merge([$ext], array_values($data)),
120                $colors
121            );
122        }
123    }
124}
125