<?php
require_once('config.php');
/**
* @author Gernot WALZL
*/
class FileSystemObject {
function order_by(&$table, $field, $sort_type=SORT_ASC) {
foreach ($table as $row) {
$keys[] = $row[$field];
}
array_multisort($keys, $sort_type, $table);
}
function group_by_dirname($files) {
$result = array();
$group = array();
$prevdir = dirname($files[0]['path']);
foreach ($files as $file) {
$currdir = dirname($file['path']);
if ($prevdir != $currdir) {
array_push($result, $group);
$group = array();
}
array_push($group, $file);
$prevdir = $currdir;
}
array_push($result, $group);
return $result;
}
function get_files($path='.') {
$result = null;
if ($handle = opendir($path)) {
$result = array();
while (false !== ($filename = readdir($handle))) {
if (substr($filename,0,1) != '.') {
$pathfile = $path.'/'.$filename;
if (is_file($pathfile) &&
is_readable($pathfile)) {
$file = array();
$file['path'] = $pathfile;
$file['time'] = filemtime($pathfile);
$file['size'] = filesize($pathfile);
array_push($result, $file);
}
}
}
closedir($handle);
}
return $result;
}
function is_ignored($ignored_dirnames, $dir) {
$result = false;
if (is_array($ignored_dirnames)) {
foreach ($ignored_dirnames as $ignored) {
if ($ignored == $dir) {
$result = true;
break;
}
}
}
return $result;
}
function get_files_rec(&$result, $path='.', $ignored_dirnames=null) {
if ($handle = opendir($path)) {
$files = $this->get_files($path);
foreach ($files as $file) {
array_push($result, $file);
}
while (false !== ($file = readdir($handle))) {
if (substr($file,0,1) != '.') {
if (is_dir($path.'/'.$file)) {
if (!$this->is_ignored($ignored_dirnames, $file)) {
$this->get_files_rec($result, $path.'/'.$file, $ignored_dirnames);
}
}
}
}
closedir($handle);
}
}
}
/**
* @author Gernot WALZL
*/
class ChangesRSS {
function __construct($config) {
$this->config = $config;
}
function println($msg) {
print($msg."\n");
}
function print_head() {
$this->println('<?xml version="1.0" encoding="utf-8"?>');
$this->println('<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">');
$this->println('<channel>');
$this->println('<title>'.$this->config->title.'</title>');
$this->println('<link>'.$this->config->link.'</link>');
$this->println('<description>'.$this->config->description.'</description>');
$this->println('<lastBuildDate>'.date(DATE_RSS).'</lastBuildDate>');
}
function print_item($title, $link, $date, $description='') {
$this->println('<item>');
$this->println('<title>'.$title.'</title>');
$this->println('<link>'.$link.'</link>');
$this->println('<pubDate>'.date(DATE_RSS, $date).'</pubDate>');
if (!empty($description)) {
$this->println('<description>'.$description.'</description>');
}
$this->println('</item>');
}
function print_change_item($files) {
$title = basename(dirname($files[0]['path']));
if ($title == '.') {
$title = $this->config->rootnode;
} else {
$title = str_replace('_', ' ', $title);
}
$link = $this->config->link;
if (!empty($this->config->link_append)) {
$link .= $this->config->link_append;
}
if ($this->config->urlencode_path) {
$link .= urlencode(dirname($files[0]['path']));
} else {
$link .= dirname($files[0]['path']);
}
$date = $files[0]['time'];
$desc = "\n";
foreach ($files as $file) {
$desc .= basename($file['path']).'<br />';
$desc .= "\n";
}
$this->print_item($title, $link, $date, $desc);
}
function print_changes($files_grouped) {
$max_num_elements = count($files_grouped);
if ($max_num_elements > $this->config->max_num_changes) {
$max_num_elements = $this->config->max_num_changes;
}
for ($cnt = 0; $cnt < $max_num_elements; $cnt++) {
$this->print_change_item($files_grouped[$cnt]);
}
}
function print_foot() {
$this->println('</channel>');
$this->println('</rss>');
}
}
/**
* @author Gernot WALZL
*/
class ChangesHTML {
function __construct($config) {
$this->config = $config;
$this->config->date_format = 'l, Y-m-d H:i T';
}
function println($msg) {
print($msg."\n");
}
function print_style() {
$this->println('html { background-color: #e9e9e9; }');
$this->println('body { background-color: #ffffff; border: 1px solid #a1a1a1; margin: 2.5em; padding: 2em; font-family: sans-serif; }');
$this->println('h2, h3 { line-height: 1; }');
$this->println('span.date { font-size: small; font-weight: normal; }');
$this->println('td { padding-left: 0.5em; padding-right: 0.5em; }');
$this->println('td.filedate { font-size: small; }');
}
function print_head() {
$this->println('<!DOCTYPE html>');
$this->println('<html lang="en">');
$this->println('<head>');
$this->println('<meta charset="utf-8">');
$this->println('<title>'.$this->config->title.'</title>');
$this->println('<meta name="viewport" content="width=device-width, initial-scale=1.0" />');
$this->println('<style>');
$this->print_style();
$this->println('</style>');
$this->println('</head>');
$this->println('<body>');
$this->println('<header>');
$this->println('<h1>'.$this->config->title.'</h1>');
$this->println('<h2>'.$this->config->description.'<br />');
$this->println('<span class="date">'.date($this->config->date_format).'</span></h2>');
$this->println('</header>');
}
function print_change_item($files) {
$title = basename(dirname($files[0]['path']));
if ($title == '.') {
$title = $this->config->rootnode;
} else {
$title = str_replace('_', ' ', $title);
}
$link = $this->config->link;
if (!empty($this->config->link_append)) {
$link .= $this->config->link_append;
}
if ($this->config->urlencode_path) {
$link .= urlencode(dirname($files[0]['path']));
} else {
$link .= dirname($files[0]['path']);
}
$date = $files[0]['time'];
$this->println('<h3><a href="'.$link.'">'.$title.'</a><br />');
$this->println('<span class="date">'.date($this->config->date_format, $date).'</span></h3>');
$this->println('<table>');
foreach ($files as $file) {
$this->println('<tr>');
$this->println('<td class="filename">'.basename($file['path']).'</td>');
$this->println('<td class="filedate">'.date('Y-m-d', $file['time']).'</td>');
$this->println('</tr>');
}
$this->println('</table>');
}
function print_changes($files_grouped) {
$max_num_elements = count($files_grouped);
if ($max_num_elements > $this->config->max_num_changes) {
$max_num_elements = $this->config->max_num_changes;
}
for ($cnt = 0; $cnt < $max_num_elements; $cnt++) {
$this->print_change_item($files_grouped[$cnt]);
}
}
function print_foot() {
$this->println('</body>');
$this->println('</html>');
}
}
$format = 'rss';
if (isset($_GET['format'])) {
if ($_GET['format'] == 'html') {
$format = 'html';
}
}
$config = new ChangesConfig();
$fso = new FileSystemObject();
$files = array();
$fso->get_files_rec($files, '.', $config->ignored_dirnames);
$fso->order_by($files, 'time', SORT_DESC);
$files_grouped = $fso->group_by_dirname($files);
if ($format == 'html') {
$html_changes = new ChangesHTML($config);
$html_changes->print_head();
$html_changes->print_changes($files_grouped);
$html_changes->print_foot();
} else {
header('Content-Type: application/rss+xml; charset=utf-8');
$rss_changes = new ChangesRSS($config);
$rss_changes->print_head();
$rss_changes->print_changes($files_grouped);
$rss_changes->print_foot();
}
?>