1<?php 2 3/** 4 * Hoa 5 * 6 * 7 * @license 8 * 9 * New BSD License 10 * 11 * Copyright © 2007-2017, Hoa community. All rights reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions are met: 15 * * Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * * Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * * Neither the name of the Hoa nor the names of its contributors may be 21 * used to endorse or promote products derived from this software without 22 * specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE 28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 * POSSIBILITY OF SUCH DAMAGE. 35 */ 36 37namespace Hoa\File; 38 39use Hoa\Event; 40 41/** 42 * Class \Hoa\File\Watcher. 43 * 44 * A naive file system watcher that fires three events: new, move and modify. 45 * 46 * @copyright Copyright © 2007-2017 Hoa community 47 * @license New BSD License 48 */ 49class Watcher extends Finder implements Event\Listenable 50{ 51 use Event\Listens; 52 53 /** 54 * Latency. 55 * 56 * @var int 57 */ 58 protected $_latency = 1; 59 60 61 62 /** 63 * Constructor. 64 * 65 * @param int $latency Latency (in seconds). 66 */ 67 public function __construct($latency = null) 68 { 69 parent::__construct(); 70 71 $this->setListener( 72 new Event\Listener( 73 $this, 74 [ 75 'new', 76 'modify', 77 'move' 78 ] 79 ) 80 ); 81 82 if (null !== $latency) { 83 $this->setLatency($latency); 84 } 85 86 return; 87 } 88 89 /** 90 * Run the watcher. 91 * 92 * Listenable events: 93 * • new, when a file is new, i.e. found by the finder; 94 * • modify, when a file has been modified; 95 * • move, when a file has moved, i.e. no longer found by the finder. 96 * 97 * @return void 98 */ 99 public function run() 100 { 101 $iterator = $this->getIterator(); 102 $previous = iterator_to_array($iterator); 103 $current = $previous; 104 105 while (true) { 106 foreach ($current as $name => $c) { 107 if (!isset($previous[$name])) { 108 $this->getListener()->fire( 109 'new', 110 new Event\Bucket([ 111 'file' => $c 112 ]) 113 ); 114 115 continue; 116 } 117 118 if (null === $c->getHash()) { 119 unset($current[$name]); 120 121 continue; 122 } 123 124 if ($previous[$name]->getHash() != $c->getHash()) { 125 $this->getListener()->fire( 126 'modify', 127 new Event\Bucket([ 128 'file' => $c 129 ]) 130 ); 131 } 132 133 unset($previous[$name]); 134 } 135 136 foreach ($previous as $p) { 137 $this->getListener()->fire( 138 'move', 139 new Event\Bucket([ 140 'file' => $p 141 ]) 142 ); 143 } 144 145 usleep($this->getLatency() * 1000000); 146 147 $previous = $current; 148 $current = iterator_to_array($iterator); 149 } 150 151 return; 152 } 153 154 /** 155 * Set latency. 156 * 157 * @param int $latency Latency (in seconds). 158 * @return int 159 */ 160 public function setLatency($latency) 161 { 162 $old = $this->_latency; 163 $this->_latency = $latency; 164 165 return $old; 166 } 167 168 /** 169 * Get latency. 170 * 171 * @return int 172 */ 173 public function getLatency() 174 { 175 return $this->_latency; 176 } 177} 178