Skip to content

Instantly share code, notes, and snippets.

@mvcaaa
Last active March 21, 2016 18:03
Show Gist options
  • Save mvcaaa/62aa1704b813882becdc to your computer and use it in GitHub Desktop.
Save mvcaaa/62aa1704b813882becdc to your computer and use it in GitHub Desktop.
<?php
/**
* FIXME: This is first working version of the script.
* I do not like it - not optimal and broke DRY, needs to be refactored
*
* Usage example:
*
* $strFolderName = $argv[1] ? $argv[1] : '.';
* var_dump(mainFunc($strFolderName, FORMAT_ARRAY));
*/
define('FORMAT_ARRAY', 0);
define('FORMAT_JSON', 1);
/**
* @param string $argStrFolderName
* @param int $argIntFormat
* @return array|string
* @throws Exception
*/
function mainFunc($argStrFolderName = '', $argIntFormat = FORMAT_ARRAY)
{
$arrOut = array();
$strFolderName = $argStrFolderName ? $argStrFolderName : '.';
if (!is_dir($strFolderName))
throw (new Exception("Path not found"));
foreach (scandir($strFolderName) as $strEntity)
{
$strFullPath = $strFolderName . DIRECTORY_SEPARATOR . $strEntity;
if (isNotDotFolder($strEntity) && is_dir($strFullPath))
{
$arrOut[] = [
'name' => $strEntity,
'size' => folderSize($strFullPath),
'files' => filesCount($strFullPath),
'dupes' => dupesCount($strFullPath)];
}
}
usort($arrOut, "sizeCmp");
return ($argIntFormat == FORMAT_JSON) ? json_encode($arrOut) : $arrOut;
}
/**
* Recursive function to get folder size
*
* @param string $argStrPath
* @return int
*/
function folderSize($argStrPath)
{
$intTotalSize = 0;
$arrFiles = scandir($argStrPath);
$strCleanPath = rtrim($argStrPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
foreach ($arrFiles as $strEntity)
{
if (isNotDotFolder($strEntity))
{
$strCurrentFile = $strCleanPath . $strEntity;
$intTotalSize += is_dir($strCurrentFile) ? folderSize($strCurrentFile) : filesize($strCurrentFile);
}
}
return $intTotalSize;
}
/**
* Recursive function to get files count
*
* @param string $argStrPath
* @return int
*/
function filesCount($argStrPath)
{
$intTotalFiles = 0;
$arrFiles = scandir($argStrPath);
$strCleanPath = rtrim($argStrPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
foreach ($arrFiles as $strEntity)
{
if (isNotDotFolder($strEntity))
{
$strCurrentFile = $strCleanPath . $strEntity;
$intTotalFiles += is_dir($strCurrentFile) ? filesCount($strCurrentFile) : 1;
}
}
return $intTotalFiles;
}
/**
* Count number of identical files in folder
*
*
* @param $argStrPath
* @return int
*/
function dupesCount($argStrPath)
{
$intTotalDupes = 0;
$arrFiles = scandir($argStrPath);
$strCleanPath = rtrim($argStrPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
foreach ($arrFiles as $strEntity)
{
$strCurrentFile = $strCleanPath . $strEntity;
if (isNotDotFolder($strEntity))
{
foreach ($arrFiles as $strEntityCompareTo)
{
if (isNotDotFolder($strEntityCompareTo)
&& !is_dir($strCleanPath . $strEntityCompareTo)
&& $strEntity != $strEntityCompareTo
)
$intTotalDupes += isIdentical($strCurrentFile, $strCleanPath . $strEntityCompareTo) ? 1 : 0;
}
}
}
return $intTotalDupes;
}
/**
* @param $strEntity
* @return bool
*/
function isNotDotFolder($strEntity)
{
return ($strEntity <> "." && $strEntity <> "..");
}
/**
* Return true if files are identical by content
*
* @param string $argStrFileName1
* @param string $argStrFileName2
* @return bool
*/
function isIdentical($argStrFileName1, $argStrFileName2)
{
// Fixme: remove errors suppression
return (@md5_file($argStrFileName1) == @md5_file($argStrFileName2));
}
/**
* @param array $argArrA
* @param array $argArrB
* @return int
*/
function sizeCmp($argArrA, $argArrB)
{
if ($argArrA['size'] == $argArrB['size'])
{
return 0;
}
return ($argArrA['size'] < $argArrB['size']) ? -1 : 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment