source = $source; $this->progress = $progress; } private function createStreamContext() { $progress = $this->progress; return stream_context_create([],["notification" => function($notification, $severity, $message, $code, $bytes_cur, $bytes_max) use($progress) { switch ($notification) { case STREAM_NOTIFY_CONNECT: $progress(0); break; case STREAM_NOTIFY_PROGRESS: $progress($bytes_max ? $bytes_cur/$bytes_max : .5); break; case STREAM_NOTIFY_COMPLETED: /* this is not generated, why? */ $progress(1); break; } }]); } /** * @param bool $verbose * @return \pharext\Task\Tempfile * @throws \pharext\Exception */ public function run($verbose = false) { if ($verbose !== false) { printf("Fetching %s ...\n", $this->source); } $context = $this->createStreamContext(); if (!$remote = fopen($this->source, "r", false, $context)) { throw new Exception; } $local = new Tempfile("remote"); if (!stream_copy_to_stream($remote, $local->getStream())) { throw new Exception; } $local->closeStream(); /* STREAM_NOTIFY_COMPLETED is not generated, see above */ call_user_func($this->progress, 1); return $local; } }