| 1 |
<?php |
| 2 |
namespace Mgleis\DiskUsageInsights\Frontend\Controller\Report; |
| 3 |
|
| 4 |
use Mgleis\DiskUsageInsights\Domain\Database; |
| 5 |
use Mgleis\DiskUsageInsights\Domain\FileEntry; |
| 6 |
use Mgleis\DiskUsageInsights\Frontend\Pagination; |
| 7 |
use Mgleis\DiskUsageInsights\Frontend\Table; |
| 8 |
use PDO; |
| 9 |
|
| 10 |
class ShowBrowserController { |
| 11 |
|
| 12 |
private PDO $db; |
| 13 |
|
| 14 |
public function execute(Database $database) { |
| 15 |
$this->db = $database->q->db; |
| 16 |
|
| 17 |
$WP_ADMIN_AJAX_URL = admin_url('admin-ajax.php'); |
| 18 |
$WP_SNAPSHOT_FILE = sanitize_file_name(wp_unslash($_GET['snapshot'] ?? '')); |
| 19 |
|
| 20 |
$totalSize = $this->selectInt($database, "SELECT SUM(size) FROM fileentries;"); |
| 21 |
|
| 22 |
$parent_id = $_GET['parent_id'] ?? 1; |
| 23 |
|
| 24 |
|
| 25 |
$parentDir = $this->findById($parent_id); |
| 26 |
$breadCrumbs = $this->calcDirBreadcrumbs($parentDir); |
| 27 |
$retval = []; |
| 28 |
foreach ($breadCrumbs as $bc) { |
| 29 |
$retval[] = [ |
| 30 |
'name' => $bc->name, |
| 31 |
'link' => sprintf( |
| 32 |
'%s?action=dui_results_table&table=browser&snapshot=%s&parent_id=%s', |
| 33 |
esc_url($WP_ADMIN_AJAX_URL), |
| 34 |
esc_js($WP_SNAPSHOT_FILE), |
| 35 |
esc_js($bc->id) |
| 36 |
) |
| 37 |
]; |
| 38 |
} |
| 39 |
$breadCrumbs = $retval; |
| 40 |
|
| 41 |
$pagination = new Pagination('', 0, 0, 10); |
| 42 |
|
| 43 |
$rows = $this->fetchAssoc($database, sprintf( |
| 44 |
"SELECT *, CASE WHEN type = 'dir' THEN dir_recursive_size ELSE size END AS ordersize FROM fileentries WHERE parent_id = %s ORDER BY ordersize DESC LIMIT %s OFFSET %s", |
| 45 |
$parent_id, $pagination->getItemsPerPage(), $pagination->calcOffset()) |
| 46 |
); |
| 47 |
$items = []; |
| 48 |
|
| 49 |
foreach ($rows as $row) { |
| 50 |
$items[] = [ |
| 51 |
'id' => $row['id'], |
| 52 |
'name' => $row['name'], |
| 53 |
'size' => $row['type'] == 'dir' ? $row['dir_recursive_size'] : $row['size'], |
| 54 |
'type' => $row['type'], |
| 55 |
'link' => $row['type'] == 'dir' |
| 56 |
? sprintf( |
| 57 |
'%s?action=dui_results_table&table=browser&snapshot=%s&parent_id=%s', |
| 58 |
esc_url($WP_ADMIN_AJAX_URL), |
| 59 |
esc_js($WP_SNAPSHOT_FILE), |
| 60 |
esc_js($row['id']) |
| 61 |
) |
| 62 |
: '' |
| 63 |
]; |
| 64 |
} |
| 65 |
$totalSize = array_reduce($items, fn($carry, $item) => $carry + $item['size'], 0); |
| 66 |
for ($i = 0; $i < count($items); $i++) { |
| 67 |
$items[$i]['percent'] = $totalSize > 0 ? round(100 * $items[$i]['size'] / $totalSize, 2) : 0; |
| 68 |
} |
| 69 |
$last = 0; |
| 70 |
for ($i = 0; $i < count($items); $i++) { |
| 71 |
$current = $last + $items[$i]['percent']; |
| 72 |
$items[$i]['conic'] = "{$last}% {$current}%"; |
| 73 |
$last = $current; |
| 74 |
} |
| 75 |
|
| 76 |
include_once __DIR__ . '/../../../../views/results/browser.php'; |
| 77 |
|
| 78 |
wp_die(); // All ajax handlers should die when finished |
| 79 |
|
| 80 |
} |
| 81 |
|
| 82 |
private function fetchAssoc(Database $database, string $sql): array { |
| 83 |
$stmt = $database->q->db->prepare($sql); |
| 84 |
$stmt->execute(); |
| 85 |
$rows = $stmt->fetchAll(\PDO::FETCH_ASSOC); |
| 86 |
|
| 87 |
return $rows; |
| 88 |
} |
| 89 |
|
| 90 |
private function selectInt(Database $database, string $sql) { |
| 91 |
$stmt = $database->q->db->prepare($sql); |
| 92 |
$stmt->execute(); |
| 93 |
$result = $stmt->fetch(); |
| 94 |
|
| 95 |
return $result[0]; |
| 96 |
} |
| 97 |
|
| 98 |
private static $cache = []; |
| 99 |
public function calcDirBreadcrumbs(FileEntry $fileEntry): array { |
| 100 |
$retval = []; |
| 101 |
|
| 102 |
while ($fileEntry->parent_id != 0) { |
| 103 |
$retval[] = $fileEntry; |
| 104 |
$fileEntry = $this->findById($fileEntry->parent_id); |
| 105 |
} |
| 106 |
$fileEntry->name = 'ROOT'; |
| 107 |
$retval[] = $fileEntry; |
| 108 |
|
| 109 |
return array_reverse($retval); |
| 110 |
} |
| 111 |
|
| 112 |
public function findById(int $id): FileEntry { |
| 113 |
|
| 114 |
$stmt = $this->db->prepare(" |
| 115 |
SELECT * FROM fileentries WHERE id =:id |
| 116 |
"); |
| 117 |
$stmt->bindValue(':id', $id); |
| 118 |
$stmt->execute(); |
| 119 |
$result = $stmt->fetch(\PDO::FETCH_ASSOC); |
| 120 |
if ($result === false) { |
| 121 |
throw new \Exception(sprintf("No file entry with id %s found.", esc_html($id))); |
| 122 |
} |
| 123 |
|
| 124 |
$entry = new FileEntry(); |
| 125 |
foreach ($result as $key => $value) { |
| 126 |
$entry->$key = $value; |
| 127 |
} |
| 128 |
|
| 129 |
return $entry; |
| 130 |
} |
| 131 |
|
| 132 |
|
| 133 |
} |