php-spark/plugins/com.noccy.watcher/Monitor/InotifyMonitor.php

98 lines
2.2 KiB
PHP

<?php
namespace SparkPlug\Com\Noccy\Watcher\Monitor;
use SparkPlug\Com\Noccy\Watcher\Rule;
class InotifyMonitor implements MonitorInterface
{
private array $rules = [];
private array $watched = [];
private array $modified = [];
private $fd;
public function __construct()
{
$this->fd = \inotify_init();
}
public function __destruct()
{
if (is_resource($this->fd)) fclose($this->fd);
}
/**
* {@inheritDoc}
*/
public function add(Rule $rule)
{
$this->rules[] = $rule;
$paths = $rule->getWatchedFiles();
$check = [];
foreach ($paths as $path) {
if (str_contains($path, '*')) {
$check = array_merge($check, glob($path));
} else {
$check[] = $path;
}
}
$dirs = [];
foreach ($check as $path) {
$dir = is_dir($path) ? $path : dirname($path);
if (!array_key_exists($dir, $dirs)) {
$dirs[$dir] = $rule;
\inotify_add_watch($this->fd, $dir, \IN_ATTRIB);
}
}
$this->watched = array_merge($this->watched, $dirs);
}
/**
* {@inheritDoc}
*/
public function getModified(): array
{
$mod = $this->modified;
$this->modified = [];
return $mod;
}
/**
* {@inheritDoc}
*/
public function getWatched(): array
{
return [];
}
public function loop()
{
$read = [ $this->fd ];
$write = null;
$except = null;
$changed = [];
while (stream_select($read,$write,$except,0)) {
$events = \inotify_read($this->fd);
foreach ($events as $event) {
$changed[] = $event['name'];
}
}
foreach ($changed as $file) {
foreach ($this->watched as $dir=>$rule) {
if (file_exists($dir."/".$file)) {
if (!in_array($rule, $this->modified)) {
printf("~ modified: %s (%s)\n", $dir."/".$file, $rule->getName());
$this->modified[] = $rule;
}
}
}
}
}
}