/** * Copy all files in directory $src to directory $dst * * The default behavior is to also copy directories recursively. * * @param string $src Path to copy files from * @param string $dst Path to copy files to. Directory is created if it doesn't already exist. * @param bool|array Array of options: * - recursive (boolean): Whether to copy directories within recursively. (default=true) * - allowEmptyDirs (boolean): Copy directories even if they are empty? (default=true) * - If a boolean is specified for $options, it is assumed to be the 'recursive' option. * @return bool True on success, false on failure. * */ function wireCopy($src, $dst, $options = array()) { $defaults = array('recursive' => true, 'allowEmptyDirs' => true); if (is_bool($options)) { $options = array('recursive' => $options); } $options = array_merge($defaults, $options); if (substr($src, -1) != '/') { $src .= '/'; } if (substr($dst, -1) != '/') { $dst .= '/'; } $dir = opendir($src); if (!$dir) { return false; } if (!$options['allowEmptyDirs']) { $isEmpty = true; while (false !== ($file = readdir($dir))) { if ($file == '.' || $file == '..') { continue; } $isEmpty = false; break; } if ($isEmpty) { return true; } } if (!wireMkdir($dst)) { return false; } while (false !== ($file = readdir($dir))) { if ($file == '.' || $file == '..') { continue; } $isDir = is_dir($src . $file); if ($options['recursive'] && $isDir) { wireCopy($src . $file, $dst . $file, $options); } else { if ($isDir) { // skip it, because not recursive } else { copy($src . $file, $dst . $file); $chmodFile = wire('config')->chmodFile; if ($chmodFile) { @chmod($dst . $file, octdec($chmodFile)); } } } } closedir($dir); return true; }
/** * Copy all files in directory $src to directory $dst * * The default behavior is to also copy directories recursively. * * @param string $src Path to copy files from * @param string $dst Path to copy files to. Directory is created if it doesn't already exist. * @param bool $recursive Whether to copy directories within recursively. Default=true. * @return bool True on success, false on failure. * */ function wireCopy($src, $dst, $recursive = true) { if (substr($src, -1) != '/') { $src .= '/'; } if (substr($dst, -1) != '/') { $dst .= '/'; } $dir = opendir($src); if (!$dir) { return false; } if (!wireMkdir($dst)) { return false; } while (false !== ($file = readdir($dir))) { if ($file == '.' || $file == '..') { continue; } if ($recursive && is_dir($src . $file)) { wireCopy($src . $file, $dst . $file); } else { copy($src . $file, $dst . $file); $chmodFile = wire('config')->chmodFile; if ($chmodFile) { chmod($dst . $file, octdec($chmodFile)); } } } closedir($dir); return true; }
protected function backupDir($moduleDir) { $dir = rtrim($moduleDir, "/"); $name = basename($dir); $parentDir = dirname($dir); $backupDir = "{$parentDir}/.{$name}/"; if (is_dir($backupDir)) { wireRmdir($backupDir, true); } // if there's already an old backup copy, remove it $success = false; if (is_link(rtrim($moduleDir, '/'))) { // module directory is a symbolic link // copy files from symlink dir to real backup dir $success = wireCopy($moduleDir, $backupDir); // remove symbolic link unlink(rtrim($moduleDir, '/')); $dir = str_replace($this->wire('config')->paths->root, '/', $moduleDir); $this->error(sprintf($this->_('Please note that %s was a symbolic link and has been converted to a regular directory'), $dir), Notice::warning); } else { // module is a regular directory // just rename it to become the new backup dir if (rename($moduleDir, $backupDir)) { $success = true; } } if ($success) { $this->message(sprintf($this->_('Backed up existing %s'), $name) . " => " . str_replace($this->wire('config')->paths->root, '/', $backupDir)); return true; } else { return false; } }
/** * Unzip the module file to tempDir and then copy to destination directory * * @param string $file File to unzip * @param string $destinationDir Directory to copy completed files into. Optionally omit to determine automatically. * @return bool|string Returns destinationDir on success, false on failure * @throws WireException * */ public function unzipModule($file, $destinationDir = '') { $success = false; $tempDir = $this->getTempDir(); $mkdirDestination = false; try { $files = wireUnzipFile($file, $tempDir); if (is_file($file)) { unlink($file); } foreach ($files as $f) { $this->message("Extracted: {$f}", Notice::debug); } } catch (Exception $e) { $this->error($e->getMessage()); if (is_file($file)) { unlink($file); } return false; } if (!$destinationDir) { $destinationDir = $this->determineDestinationDir($files); if (!$destinationDir) { throw new WireException($this->_('Unable to find any module files')); } } if (is_link($destinationDir)) { throw new WireException($this->_('Directory is a symbolic link') . " - {$destinationDir}"); } $files0 = trim($files[0], '/'); $extractedDir = is_dir("{$tempDir}/{$files0}") && substr($files0, 0, 1) != '.' ? "{$files0}/" : ""; // now create module directory and copy files over if (is_dir($destinationDir)) { // destination dir already there, perhaps an older version of same module? // create a backup of it $hasBackup = $this->backupDir($destinationDir); if ($hasBackup) { wireMkdir($destinationDir, true); } } else { if (wireMkdir($destinationDir, true)) { $mkdirDestination = true; } $hasBackup = false; } // label to identify destinationDir in messages and errors $dirLabel = str_replace($this->config->paths->root, '/', $destinationDir); if (is_dir($destinationDir)) { $from = $tempDir . $extractedDir; if (wireCopy($from, $destinationDir)) { $this->message($this->_('Successfully copied files to new directory:') . ' ' . $dirLabel); wireChmod($destinationDir, true); $success = true; } else { $this->error($this->_('Unable to copy files to new directory:') . ' ' . $dirLabel); if ($hasBackup) { $this->restoreDir($destinationDir); } } } else { $this->error($this->_('Could not create directory:') . ' ' . $dirLabel); } if (!$success) { $this->error($this->_('Unable to copy module files:') . ' ' . $dirLabel); if ($mkdirDestination && !wireRmdir($destinationDir, true)) { $this->error($this->_('Could not delete failed module dir:') . ' ' . $destinationDir, Notice::log); } } return $success ? $destinationDir : false; }