HEX
Server: nginx
System: Linux pool64-304-45.dca.atomicsites.net 5.10.0-31-amd64 #1 SMP Debian 5.10.221-1 (2024-07-14) x86_64
User: (0)
PHP: 8.4.18
Disabled: pcntl_fork
Upload Files
File: /wordpress/mu-plugins/atomic-cli-disk-usage.php
<?php

/**
 * Output disk usage information for the document root and tmp directories
 *
 * [--depth=<number>]
 * : Number of directory levels to traverse
 * ---
 * default: 2
 * ---
 */
function atomic_cli_disk_usage( $args, $assoc_args ) {
	// Get path depth arg
	if ( empty( $assoc_args['depth'] ) ) {
		$depth = '2';
	} else {
		$depth = (string) $assoc_args['depth'];
	}
	if ( ! ctype_digit( $depth ) ) {
		WP_CLI::warning( 'The depth argument must be a positive number.' );
		return;
	}
	$escaped_depth = escapeshellarg( $depth );

	// Run the shell command
	$command = escapeshellcmd( "/usr/bin/du --bytes --time --max-depth={$escaped_depth} '/srv/htdocs' '/tmp'" );
	$result = exec( $command, $output, $result_code );

	if ( false === $result || empty( $output ) || 0 !== $result_code ) {
		WP_CLI::warning( 'Could not get disk usage information.' );
		return;
	}

	// Define table headers and initialize their string lengths as the column max widths
	$headers    = array(
		'bytes' => 'Bytes',
		'date'  => 'Date Modified',
		'path'  => 'Directory',
	);
	$max_strlen = array(
		'bytes' => strlen( $headers['bytes'] ),
		'date'  => strlen( $headers['date'] ),
		'path'  => strlen( $headers['path'] ),
	);

	// Parse the output lines and get the max width of each column
	$parsed_results = array();
	foreach ( $output as $line ) {
		if ( empty( $line ) ) {
			continue;
		}

		$parts = preg_split( '/\s+/', $line );

		$parsed_line['bytes'] = $parts[0];
		$parsed_line['date']  = "{$parts[1]} {$parts[2]}";
		$parsed_line['path']  = $parts[3];
		$parsed_results[]     = $parsed_line;

		$max_strlen['bytes'] = max( $max_strlen['bytes'], strlen( number_format( $parsed_line['bytes'] ) ) );
		$max_strlen['date']  = max( $max_strlen['date'], strlen( $parsed_line['date'] ) );
		$max_strlen['path']  = max( $max_strlen['path'], strlen( $parsed_line['path'] ) );
	}

	// Sort by path name in order to easily filter out duplicated parent paths
	usort(
		$parsed_results,
		static function( $a, $b ) {
			if ( $a['path'] < $b['path'] ) {
				return 1;
			}
			if ( $a['path'] > $b['path'] ) {
				return -1;
			}

			return 0;
		}
	);

	// Filter out results with a parent directory when child directories are also included
	$prev_path        = null;
	$filtered_results = array();
	foreach ( $parsed_results as $parsed_result ) {
		if ( null ===$prev_path || ! ( 0 === strpos( $prev_path, $parsed_result['path'] ) ) ) {
			$prev_path          = $parsed_result['path'];
			$filtered_results[] = $parsed_result;
		}
	}

	// Sort the results in descending order by byte size
	usort(
		$filtered_results,
		static function( $a, $b ) {
			if ( (int) $a['bytes'] < (int) $b['bytes'] ) {
				return 1;
			}
			if ( (int) $a['bytes'] > (int) $b['bytes'] ) {
				return -1;
			}

			return 0;
		}
	);

	$format    = "| %{$max_strlen['bytes']}s | %{$max_strlen['date']}s | %-{$max_strlen['path']}s |\n";
	$horiz_sep = '+-' . str_repeat( '-', $max_strlen['bytes'] ) . '-+-' . str_repeat( '-', $max_strlen['date'] ) . '-+-' . str_repeat( '-', $max_strlen['path'] ) . "-+\n";

	echo $horiz_sep;
	printf( $format, $headers['bytes'], $headers['date'], $headers['path'] );
	echo $horiz_sep;

	foreach ( $filtered_results as $data ) {
		printf( $format, number_format( $data['bytes'] ), $data['date'], $data['path'] );
	}

	echo $horiz_sep;
}

if ( class_exists( 'WP_CLI' ) ) {
	WP_CLI::add_command( 'disk-usage', 'atomic_cli_disk_usage' );
}