Your Ad Here

Posted By

SoN9ne on 12/30/10


Tagged

css php html directory with scan filters recursively


Versions (?)

Who likes this?

1 person have marked this snippet as a favorite

dlahay


PHP/HTML/CSS - Script to scan a directoy recursively with filters and/or ingore list


 / Published in: PHP
 

There seems to be many scan directory systems but I could not find one that works the way I needed. I added in functionality for a search filter and an ignore list. The search filter and ignore list can ignore by extension, file (case-sensitive file name), and directory. I also added in the ability to have a max depth for the scan.

The HTML and CSS that are in the script is to preview in the browser the output. If you scan a directory that is outside the webroot then the links will not be built properly. I did not care to resolve this issue as it was not a problem for me.

I tested the script in Strict mode and have no errors, warnings, or notices. Pasting this here for a few friends and the community. If you can improve the script, please let me know as I always enjoy learning new techniques.

Thanks, SoN9ne

  1. <?php
  2. /**
  3.  * Scans a directory recursively
  4.  * Can filter the directory to show only desired file extensions
  5.  *
  6.  * @author Jeremy Simkins <SoN9ne>
  7.  */
  8.  
  9. /**
  10.  * Prepare filters
  11.  * - Do not edit unless you know what you are doing!
  12.  * - Look below (Look for BEGIN) to edit the filters
  13.  */
  14. # Define search Filters
  15. $searchFilter = array();
  16. $searchFilter['file'] = array();
  17. $searchFilter['extension'] = array();
  18. $searchFilter['directory'] = array();
  19.  
  20. # Define ignore Filters
  21. $ignore = array();
  22. $ignore['file'] = array();
  23. $ignore['extension'] = array();
  24. $ignore['directory'] = array();
  25. //--> End Prepare filters
  26.  
  27.  
  28. //-----[ BEGIN - Edit this data as you see fit ]-----------------------------------\\
  29. /**
  30.  * Directory to scan
  31.  * @var string
  32.  */
  33. $directory = "../"; // up one directory to get all the files of the system
  34.  
  35.  
  36. /**
  37.  * Set the maximum depth for the scan
  38.  *
  39.  * @var mixed - NULL|int - NULL will have no depth limitation, int is the number of levels deep to step into
  40.  */
  41. define('MAX_SCAN_DEPTH', NULL);
  42.  
  43. /**
  44.  * Custom search filters
  45.  * - You can add any type of filter to limit the search.
  46.  *
  47.  * Notes:
  48.  * - Extension and directory filters should be all lowercase
  49.  * - File filters should include the extension and are case-sensitive
  50.  */
  51. # Define search extension filters
  52. //$searchFilter['extension'][] = 'php';
  53.  
  54.  
  55. # Define search file filters
  56. //$searchFilter['file'][] = '';
  57.  
  58.  
  59. # Define search directory filters
  60. //$searchFilter['directory'][] = '';
  61. //--> End search filters
  62.  
  63.  
  64. /**
  65.  * Edit the ignore filters
  66.  */
  67. # Define ignore extension filters
  68. $ignore['extension'][] = 'buildpath'; // ZDE file
  69. $ignore['extension'][] = 'ds_store'; // Desktop Services Store file
  70. $ignore['extension'][] = 'project'; // ZDE file
  71.  
  72.  
  73. # Define ignore file filters
  74. //$ignore['file'][] = '';
  75.  
  76.  
  77. # Define ignore directory filters
  78. $ignore['directory'][] = '.svn'; // Do not scan svn directories
  79. $ignore['directory'][] = '.settings'; // Do not scan ZDE .setting folder
  80. $ignore['directory'][] = '__sessions'; // Do not scan custom sessions storage folder
  81. //--> End ignore filters
  82. //-----[ STOP - Edit this data as you see fit ]-----------------------------------\\
  83.  
  84.  
  85. /**
  86.  * Do Not edit below unless you know what you are doing
  87.  */
  88. # Set timezone
  89. date_default_timezone_set('America/New_York');
  90.  
  91. # Total files flag
  92. $totalFiles = 0;
  93. $totalDirectories = 0;
  94.  
  95. # Define direcoty tree array
  96. $directory_tree = array();
  97.  
  98. # Scan the directory
  99. $directory_tree = customScanDir($directory, $searchFilter, $ignore);
  100.  
  101. # Sort the array
  102. array_sort($directory_tree, 'name');
  103.  
  104. //echo '<pre>';
  105. //print_r($directory_tree);
  106. //echo '</pre>';
  107. //die();
  108.  
  109.  
  110. # Start output buffering
  111.  
  112. # Display the content
  113. displayDirRecursively($directory_tree, $totalFiles, $totalDirectories);
  114.  
  115. # Save output to a var
  116. $tmp = ob_get_contents();
  117.  
  118. # Delete the output buffer
  119.  
  120. # Output the page
  121. ?>
  122. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  123. <html xmlns="http://www.w3.org/1999/xhtml">
  124. <head>
  125. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  126. <title>Scanner</title>
  127. <style>
  128. body {
  129. margin: 0;
  130. padding: 0;
  131. font: normal 14px Arial;
  132. color: #666;
  133. background: #efefef;
  134. }
  135.  
  136. ul,ol {
  137. background: #fff;
  138. border: 4px solid #fff;
  139. }
  140.  
  141. .dirList {
  142. margin: 5px auto;
  143. width: 60%;
  144. overflow: hidden;
  145. -moz-box-shadow: 0 0 20px #b5b5b5;
  146. }
  147.  
  148. #detail-container {
  149. margin: 5px auto;
  150. width: 60%;
  151. }
  152.  
  153. #details,#legend {
  154. margin: 5px auto;
  155. -moz-box-shadow: 0 0 20px #b5b5b5;
  156. }
  157.  
  158. #details {
  159. float: left;
  160. width: 70%;
  161. list-style: none;
  162. }
  163.  
  164. #legend {
  165. display: inline-block;
  166. float: right;
  167. width: 20%;
  168. }
  169.  
  170. .clear {
  171. clear: both;
  172. }
  173.  
  174. li {
  175. line-height: 1.8em;
  176. margin: 0 5px;
  177. padding-left: 2em;
  178. text-indent: -2em;
  179. width: 100%;
  180. }
  181.  
  182. ol.legend:first-child {
  183. background: maroon;
  184. }
  185.  
  186. .dirList li:nth-child(even) {
  187. background: #fff;
  188. }
  189.  
  190. .dirList li:nth-child(odd) {
  191. background: #ecf3fe;
  192. }
  193.  
  194. .dirList li:hover {
  195. background: yellow;
  196. }
  197.  
  198. .dirList ul {
  199. margin-left: -30px;
  200. }
  201.  
  202. #details .title,#legend .title {
  203. list-style: none;
  204. font-weight: bold;
  205. border-bottom: 1px solid #ccc;
  206. margin: 0 0 0 -38px;
  207. }
  208.  
  209. .folder {
  210. list-style: circle;
  211. }
  212.  
  213. .file {
  214. list-style: square;
  215. }
  216.  
  217. h3,h4 {
  218. padding: 10px;
  219. margin: 0px;
  220. font: normal 20px 'Trebuchet MS';
  221. text-align: center;
  222. }
  223.  
  224. h4 {
  225. font: normal 15px 'Trebuchet MS';
  226. }
  227.  
  228. a {
  229. color: #0079e0;
  230. }
  231.  
  232. a:visited {
  233. color: purple;
  234. }
  235. </style>
  236. <!--<script type="text/javascript" src="/gs_sortable.js"></script>-->
  237. <!--<script type="text/javascript">-->
  238. <!---->
  239. <!--var TSort_Data = new Array ('scanner', 's', 'd');-->
  240. <!--tsRegister();-->
  241. <!--// -->
  242. <!--</script>-->
  243. </head>
  244. <body>
  245. <div id="detail-container">
  246. <ol id="details">
  247. <li class="title">Details:</li>
  248. <li>Total Directories Scanned: <strong><?php
  249. echo $totalDirectories;
  250. ?></strong></li>
  251. <li>Total Files Located: <strong><?php
  252. echo $totalFiles;
  253. ?></strong></li>
  254. </ol>
  255. <ol id="legend">
  256. <li class="title">Legend:</li>
  257. <li class="folder">Folder</li>
  258. <li class="file">File</li>
  259. </ol>
  260. <div class="clear"></div>
  261. </div>
  262. <hr />
  263.  
  264. <?php
  265. # Output the buffer
  266. echo $tmp;
  267. ?>
  268.  
  269. </body>
  270. </html>
  271. <?php
  272.  
  273. /**
  274.  * Recursively scans the directory
  275.  *
  276.  * @param string $directory - Directory to scan
  277.  * @param array $searchFilter - Array of serch data
  278.  * @param array $ignore - Array of data to ignore
  279.  * @param int $depth - Flag for knowing the depth of the scan
  280.  * @throws Exception
  281.  */
  282. function customScanDir($directory = '.', $searchFilter = NULL, $ignore = NULL, $depth = 0) {
  283.  
  284. if ( MAX_SCAN_DEPTH && $depth > MAX_SCAN_DEPTH ) return array();
  285.  
  286. if ( substr($directory, -1) == '/' ) {
  287. $directory = substr($directory, 0, -1);
  288. }
  289.  
  290. try {
  291. try {
  292. $directory_tree = array(); // Define output array
  293. foreach (new DirectoryIterator($directory) as $fileInfo) {
  294. if ( $fileInfo->isDot() ) continue;
  295.  
  296. $subdirectories = explode('/', $fileInfo->getPathname());
  297. $tmpName = end($subdirectories);
  298.  
  299. if ( $fileInfo->isDir() && !empty($ignore['directory']) && !in_array($tmpName, $ignore['directory']) ) {
  300. $directory_tree['directory'][] = array('path'=>$fileInfo->getPathname(), 'name'=>$tmpName, 'kind'=>'directory', 'content'=>array_sort(customScanDir($fileInfo->getPathname(), $searchFilter, $ignore, $depth + 1), 'name'));
  301. } else if ( $fileInfo->isFile() ) {
  302. $tmpExtension = strtolower(end(explode('.', $tmpName)));
  303.  
  304. # Ignored files and extensions
  305. if ( !empty($ignore['extension']) && in_array($tmpExtension, $ignore['extension']) || !empty($ignore['file']) && in_array(strtolower($tmpName), $ignore['file']) || !empty($searchFilter['extension']) && !in_array($tmpExtension, $searchFilter['extension']) ) {
  306. continue;
  307. }
  308.  
  309. # Add the file to the tree if it is searched or we are displaying the entire directory
  310. if ( empty($searchFilter['file']) || !empty($searchFilter['file']) && in_array(strtolower($tmpName), $searchFilter['file']) ) {
  311. $directory_tree['file'][] = array('name'=>$tmpName, 'extension'=>$tmpExtension, 'path'=>$fileInfo->getPathname(), 'lastModified'=>date('M d Y h:i:s a', $fileInfo->getMTime()), 'kind'=>'file');
  312. }
  313. }
  314. }
  315.  
  316. unset($tmpName, $tmpExtension); // Free tmp vars
  317. return $directory_tree;
  318. } catch ( UnexpectedValueException $e ) {
  319. throw new Exception(sprintf("Directory [%s/] contained a directory that cannot be stepped into", $directory), E_USER_WARNING);
  320. return array(); // Return an empty array
  321. }
  322. } catch ( Exception $e ) {
  323. die($e->getMessage()); // Show the error
  324. }
  325. }
  326.  
  327. /**
  328.  * Steps throught the directory array and displays
  329.  *
  330.  * @param array $fileSystem - Array of file system
  331.  * @param int $totalFiles - Flag to count the total files found
  332.  * @param int $totalDirectories - Flag to count the total directories scanned
  333.  * @param int $depth - Flag to know the depth of the display
  334.  */
  335. function displayDirRecursively($fileSystem = array(), & $totalFiles = 0, & $totalDirectories = 0, $depth = 0) {
  336. echo '<ul class="' . (($depth) ? "sub-depth-{$depth}" : 'dirList') . '">';
  337. foreach ($fileSystem as $fsType=>$fsData) {
  338. foreach ($fsData as $item) {
  339. if ( $fsType === 'directory' ) {
  340. ++$totalDirectories;
  341.  
  342. echo '<li class="folder">';
  343. echo $item['name'];
  344.  
  345. if ( isset($item['content']) && is_array($item['content']) && !empty($item['content']) ) {
  346. displayDirRecursively($item['content'], $totalFiles, $totalDirectories, $depth + 1);
  347. }
  348. $deep = 0;
  349. echo '</li>';
  350. } else if ( $fsType === 'file' ) {
  351. ++$totalFiles;
  352.  
  353. echo '<li class="file">';
  354. echo sprintf('<a href="%s" target="_blank" title="%s">%s</a>', $item['path'], $item['path'], $item['name']);
  355. echo '</li>';
  356. }
  357. }
  358. }
  359. echo '</ul>';
  360. }
  361.  
  362. /**
  363.  * Sorts an array by key
  364.  *
  365.  * @param array $array
  366.  * @param mixed $on - string||int
  367.  * @param bool $sortASC - TRUE sort ASC, FALSE sort DESC
  368.  * @return array
  369.  */
  370. function array_sort($array, $on, $sortASC = TRUE) {
  371. $new_array = array();
  372. $sortable_array = array();
  373.  
  374. if ( count($array) > 0 ) {
  375. foreach ($array as $k=>$v) {
  376. if ( is_array($v) ) {
  377. foreach ($v as $k2=>$v2) {
  378. if ( $k2 == $on ) {
  379. $sortable_array[$k] = $v2;
  380. }
  381. }
  382. } else {
  383. $sortable_array[$k] = $v;
  384. }
  385. }
  386.  
  387. if ( $sortASC ) {
  388. asort($sortable_array);
  389. } else {
  390. arsort($sortable_array);
  391. }
  392.  
  393. foreach ($sortable_array as $k=>$v) {
  394. $new_array[$k] = $array[$k];
  395. }
  396. }
  397.  
  398. return $new_array;
  399. }

Report this snippet  

You need to login to post a comment.