Skip to content

Commit

Permalink
Merge pull request #39 from cosmocode/refactor
Browse files Browse the repository at this point in the history
Major Refactoring, Clean-Up and Simplification
  • Loading branch information
splitbrain authored Mar 4, 2024
2 parents 31b4eb6 + 1d52ebc commit ea0fa0c
Show file tree
Hide file tree
Showing 24 changed files with 1,531 additions and 1,522 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/.* export-ignore
/_test export-ignore
11 changes: 11 additions & 0 deletions .github/workflows/dokuwiki.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: DokuWiki Default Tasks
on:
push:
pull_request:
schedule:
- cron: '58 2 25 * *'


jobs:
all:
uses: dokuwiki/github-action/.github/workflows/all.yml@main
13 changes: 0 additions & 13 deletions .travis.yml

This file was deleted.

191 changes: 191 additions & 0 deletions Crawler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
<?php

namespace dokuwiki\plugin\filelist;

class Crawler
{
/** @var string regexp to check extensions */
protected $ext;

/** @var string */
protected $sortby = 'name';

/** @var bool */
protected $sortreverse = false;

/**
* Initializes the crawler
*
* @param string $extensions The extensions to allow (comma separated list)
*/
public function __construct($extensions)
{
$this->ext = explode(',', $extensions);
$this->ext = array_map('trim', $this->ext);
$this->ext = array_map('preg_quote_cb', $this->ext);
$this->ext = implode('|', $this->ext);
}

public function setSortBy($sortby)
{
$this->sortby = $sortby;
}

public function setSortReverse($sortreverse)
{
$this->sortreverse = $sortreverse;
}

/**
* Does a (recursive) crawl for finding files based on a given pattern.
* Based on a safe glob reimplementation using fnmatch and opendir.
*
* @param string $path the path to search in
* @param string $pattern the pattern to match to
* @param bool $recursive whether to search recursively
* @param string $titlefile the name of the title file
* @return array a hierarchical filelist or false if nothing could be found
*
* @see http://www.php.net/manual/en/function.glob.php#71083
*/
public function crawl($root, $local, $pattern, $recursive, $titlefile)
{
$path = $root . $local;

if (($dir = opendir($path)) === false) return [];
$result = [];
while (($file = readdir($dir)) !== false) {
if ($file[0] == '.' || $file == $titlefile) {
// ignore hidden, system and title files
continue;
}
$self = $local . '/' . $file;
$filepath = $path . '/' . $file;
if (!is_readable($filepath)) continue;

if ($this->fnmatch($pattern, $file) || (is_dir($filepath) && $recursive)) {
if (!is_dir($filepath) && !$this->isExtensionAllowed($file)) {
continue;
}

// get title file
$filename = $file;
if (is_dir($filepath)) {
$title = $filepath . '/' . $titlefile;
if (is_readable($title)) {
$filename = io_readFile($title, false);
}
}

// prepare entry
if (!is_dir($filepath) || $recursive) {
$entry = [
'name' => $filename,
'local' => $self,
'path' => $filepath,
'mtime' => filemtime($filepath),
'ctime' => filectime($filepath),
'size' => filesize($filepath),
'children' => ((is_dir($filepath) && $recursive) ?
$this->crawl($root, $self, $pattern, $recursive, $titlefile) :
false
),
'treesize' => 0,
];

// calculate tree size
if ($entry['children'] !== false) {
foreach ($entry['children'] as $child) {
$entry['treesize'] += $child['treesize'];
}
} else {
$entry['treesize'] = 1;
}

// add entry to result
$result[] = $entry;
}
}
}
closedir($dir);
return $this->sortItems($result);
}

/**
* Sort the given items by the current sortby and sortreverse settings
*
* @param array $items
* @return array
*/
protected function sortItems($items)
{
$callback = [$this, 'compare' . ucfirst($this->sortby)];
if (!is_callable($callback)) return $items;

usort($items, $callback);
if ($this->sortreverse) {
$items = array_reverse($items);
}
return $items;
}

/**
* Check if a file is allowed by the configured extensions
*
* @param string $file
* @return bool
*/
protected function isExtensionAllowed($file)
{
if ($this->ext === '') return true; // no restriction
return preg_match('/(' . $this->ext . ')$/i', $file);
}


/**
* Replacement for fnmatch() for windows systems.
*
* @author jk at ricochetsolutions dot com
* @link http://www.php.net/manual/en/function.fnmatch.php#71725
*/
protected function fnmatch($pattern, $string)
{
return preg_match(
"#^" . strtr(
preg_quote($pattern, '#'),
[
'\*' => '.*',
'\?' => '.',
'\[' => '[',
'\]' => ']'
]
) . "$#i",
$string
);
}

public function compareName($a, $b)
{
return strcmp($a['name'], $b['name']);
}

public function compareIname($a, $b)
{
return strcmp(strtolower($a['name']), strtolower($b['name']));
}

public function compareCtime($a, $b)
{
return $a['ctime'] <=> $b['ctime'];
}

public function compareMtime($a, $b)
{
return $a['mtime'] <=> $b['mtime'];
}

public function compareSize($a, $b)
{
return $a['size'] <=> $b['size'];
}
}
Loading

0 comments on commit ea0fa0c

Please sign in to comment.