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 /** @var string[] */ 16 private array $buckets = ['<1d', '<1w', '<1m', '<3m', '<6m', '<1y', '>1y']; 17 18 /** @inheritDoc */ 19 protected function setup(Options $options) 20 { 21 $options->setHelp('Collect statistics about the cache directory.'); 22 23 $options->registerOption('format', 'Output format: table|json|csv', 'f', 'table'); 24 $options->registerOption('sort', 'Sort by count|size|dups', 's', false); 25 } 26 27 /** @inheritDoc */ 28 protected function main(Options $options) 29 { 30 global $conf; 31 32 $sort = $options->getOpt('sort', 'size'); 33 if (!in_array($sort, ['count', 'size', 'dups'])) { 34 $this->error("Invalid sort option '$sort'. Allowed are: count, size, dups."); 35 return 1; 36 } 37 38 $format = $options->getOpt('format', 'table'); 39 if (!in_array($format, ['table', 'json', 'csv'])) { 40 $this->error("Invalid format option '$format'. Allowed are: table, json, csv."); 41 return 1; 42 } 43 44 if ($format === 'json') { 45 fprintf(STDERR, 'Collecting cache statistics from ' . $conf['cachedir'] . "…\n"); 46 } else { 47 $this->info('Collecting cache statistics from ' . $conf['cachedir'] . '…'); 48 } 49 50 $stats = (new FileStatistics($conf['cachedir']))->collect(); 51 52 // for debugging 53 print_r($stats); 54 55 $keys = array_unique( 56 array_merge( 57 array_keys($stats['extensions']), 58 array_keys($stats['sizes']), 59 array_keys($stats['duplicates']) 60 ) 61 ); 62 $result = []; 63 foreach ($keys as $key) { 64 $modified = []; 65 foreach ($this->buckets as $bucket) { 66 $modified[$bucket] = $stats['modified_groups'][$key][$bucket] ?? 0; 67 } 68 $result[$key] = [ 69 'count' => $stats['extensions'][$key] ?? 0, 70 'size' => $stats['sizes'][$key] ?? 0, 71 'dups' => $stats['duplicates'][$key] ?? 0, 72 'modified' => $modified, 73 ]; 74 } 75 76 // sort with preserved keys 77 uasort($result, function ($a, $b) use ($sort) { 78 return $b[$sort] <=> $a[$sort]; 79 }); 80 81 match ($format) { 82 'json' => $this->print_json($result), 83 'csv' => $this->print_csv($result), 84 default => $this->print_table($result), 85 }; 86 return 0; 87 } 88 89 /** 90 * Output statistics as JSON 91 */ 92 private function print_json(array $result): void 93 { 94 echo json_encode($result, JSON_PRETTY_PRINT); 95 } 96 97 /** 98 * Output statistics as CSV 99 */ 100 private function print_csv(array $result): void 101 { 102 $handle = fopen('php://output', 'w'); 103 if ($handle === false) { 104 $this->error('Could not open output for CSV.'); 105 return; 106 } 107 108 $header = array_merge( 109 ['extension', 'count', 'total_size_bytes', 'duplicate_files'], 110 $this->buckets 111 ); 112 fputcsv($handle, $header); 113 114 foreach ($result as $ext => $data) { 115 $row = [ 116 $ext, 117 $data['count'], 118 $data['size'], 119 $data['dups'] 120 ]; 121 foreach ($this->buckets as $bucket) { 122 $row[] = $data['modified'][$bucket]; 123 } 124 fputcsv($handle, $row); 125 } 126 } 127 128 /** 129 * Output statistics as table 130 */ 131 private function print_table(array $result): void 132 { 133 $tr = new TableFormatter($this->colors); 134 $columns = array_merge(['*', 7, 10, 7], array_fill(0, count($this->buckets), 5)); 135 $headers = array_merge( 136 ['Extension', 'File Count', 'Total Size (bytes)', 'Duplicate Files'], 137 $this->buckets 138 ); 139 echo $tr->format( 140 $columns, 141 $headers, 142 ['', '', '', ''] 143 ); 144 145 foreach ($result as $ext => $data) { 146 $row = [ 147 $ext, 148 sprintf("% 7s", number_format($data['count'])), 149 sprintf("% 10s", filesize_h($data['size'])), 150 sprintf("% 7s", number_format($data['dups'])) 151 ]; 152 foreach ($this->buckets as $bucket) { 153 $row[] = sprintf("% 5s", number_format($data['modified'][$bucket])); 154 } 155 echo $tr->format( 156 $columns, 157 $row, 158 ['', '', '', ''] 159 ); 160 } 161 } 162} 163