/** * Copies a file/directory on the remote host * * @param string $src * @param string $dest * @param bool $recursive * @throws \RuntimeException * @return mixed */ public function copy($src, $dest, $recursive = true) { if (false === $this->isConnected()) { $this->connectAndLogin(); } $this->dispatcher->dispatch(TransporterEvents::TRANSPORTER_COPY, new TransporterEvent($this, array('dest' => $dest, 'src' => $src))); $recursiveFlag = $recursive ? 'r' : ''; // adjust for symlink // we want to copy the contents of the symlink (dereference it), but keep links in subfolders $lstat = $this->sftp->lstat($src); if ($lstat['type'] === 3) { $result = $this->sftp->exec(sprintf("readlink -f %s", escapeshellarg($src))); if (false === $result) { throw new \RuntimeException('Something went wrong: ' . "\n" . implode("\n", (array) $this->sftp->getErrors())); } $src = trim($result); } $success = $this->sftp->exec(sprintf("cp -{$recursiveFlag}f %s %s", escapeshellarg($src), escapeshellarg($dest))); if (false === $success) { throw new \RuntimeException('Something went wrong: ' . "\n" . implode("\n", (array) $this->sftp->getErrors())); } }