*/ class ParTCP_Hooks { public $fileSystem; public $dataDir; public function __construct( $fileSystem, $dataDir ){ $this->fileSystem = $fileSystem; $this->dataDir = $dataDir; } public function get_dir( $hookId ){ return "hooks/{$hookId}"; } public function get_list(){ $dir = 'hooks'; if ( ! $this->fileSystem->exists( $dir ) ){ return []; } $list = $this->fileSystem->get_listing( $dir ); $hooks = []; foreach ( $list as $hook ){ if ( $data = $this->get_data( $hook ) ){ $hooks[] = $data; } } return $hooks; } public function get_data( $hookId ){ $dir = $this->get_dir( $hookId ) . '/_def'; $msg = $this->fileSystem->get_recent_contents( $dir, '[0-9]*-{update,definition}*' ); if ( empty( $msg ) ){ return FALSE; } $receipt = yaml_parse( $msg ); if ( empty( $receipt['Hook-Data'] ) ){ return FALSE; } $data = $receipt['Hook-Data']; return $data; } public function purge_data( $data ){ $validKeys = [ 'pattern' => 0, 'url' => 0, 'secret' => 0, ]; return array_intersect_key( $data, $validKeys ); } public function trigger_hooks( $path, $content ){ $cacheFile = "{$this->dataDir}/hooks/list.yaml"; if ( file_exists( $cacheFile ) /* && is_up_to_date( $cacheFile ) */ ){ $list = yaml_parse( file_get_contents( $cacheFile ) ); } else { $list = $this->get_list(); file_put_contents( $cacheFile, yaml_emit( $list ) ); } foreach ( $list as $hook ){ if ( preg_match( $hook['pattern'], $path ) ){ $this->add_trigger_to_queue( $hook, $path, $content ); } } return TRUE; } private function add_trigger_to_queue( $hook, $path, $content ){ $name = date('Ymd-His-') . md5( microtime() ); $dir = "{$this->dataDir}/hooks/queue/tmp/{$name}"; mkdir( $dir, 0755, TRUE ); $content = trim( $content ); $hash = hash( 'sha256', $content . $hook['secret'] ); $url = $hook['url']; $data = compact( 'url', 'path', 'content', 'hash' ); file_put_contents( "{$dir}/data.yaml", yaml_emit( $data ) ); rename( $dir, "{$this->dataDir}/hooks/queue/{$name}" ); } } // end of file hooks.class.php