98 lines
2.2 KiB
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;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|