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