I'm trying copy a single file from the Plugin directory inside of my Wordpress installation to the root directory of the Wordpress installation. I need the functionality to do this no matter where the installation is located. It's for my Wordpress plugin, and it doesn't seem to be working on a site I tested.
Somehow I'm thinking that I'm not capturing each possible directory location in my function destpath() function. I need it to successfully find the exact directories of the Plugin folder so that it copies the file (process.php) to the exact root directory, no matter the location of the Wordpress install.
function destpath()
{
$base = dirname(__FILE__);
$path = false;
if (#file_exists(dirname(dirname($base))."/wp-config.php")) {
$path = dirname(dirname($base))."/process.php";
} else
if (#file_exists(dirname(dirname(dirname($base)))."/wp-config.php")) {
$path = dirname(dirname(dirname($base)))."/process.php";
} else
$path = false;
if ($path != false) {
$path = str_replace("\\", "/", $path);
}
return $path;
}
function pluginpath()
{
$base = dirname(__FILE__);
$path = false;
if (#file_exists(dirname(dirname($base))."/wp-content/plugins/malware finder/process.php")) {
$path = dirname(dirname($base))."/wp-content/plugins/malware finder/process.php";
} else
if (#file_exists(dirname(dirname(dirname($base)))."/wp-content/plugins/malware finder/process.php")) {
$path = dirname(dirname(dirname($base)))."/wp-content/plugins/malware finder/process.php";
} else
$path = false;
if ($path != false) {
$path = str_replace("\\", "/", $path);
}
return $path;
}
copy(pluginpath(), destpath());
According to the source code, it looks like the destpath and pluginpath methods of the MalwareFinder class are being injected into the printAdminPage function:
Source code line:83:
function printAdminPage() {
Source code line:108 (appears to close if):
<?php }
Source code line:111-133 (still within printAdminPage):
function destpath() { ... }
Source code line:136-158 (still within printAdminPage):
function pluginpath() { ... }
Source code line:205:
}//End function printAdminPage()
Also, on lines 62 and 65, these php tags appear unnecessary.
Related
So as the title said, I'm struggling to copy a folder to another folder
I tried this but no results
Edit: I got this to work by fixing the $npath variable I was just giving the url without the folder's name $npath = $newk->url;
so the final code will be :
public function copyFolder(Request $request)
{
$id= $request->get('oldf');
$new = $request->get('newf');
$document = Document::find($id);
$newk = Document::find($new);
$npath = $newk->url.'/'.$document->nom;
$file= new Filesystem();
if($file->copyDirectory($document->url, $npath)){
return redirect('home');
}
return redirect('home');
}
any help would be appreciated :)
use this function
function recursive_files_copy($source_dir, $destination_dir)
{
// Open the source folder / directory
$dir = opendir($source_dir);
// Create a destination folder / directory if not exist
if (!is_dir($destination_dir)){
mkdir($destination_dir);
}
// Loop through the files in source directory
while($file = readdir($dir))
{
// Skip . and ..
if(($file != '.') && ($file != '..'))
{
// Check if it's folder / directory or file
if(is_dir($source_dir.'/'.$file))
{
// Recursively calling this function for sub directory
recursive_files_copy($source_dir.'/'.$file, $destination_dir.'/'.$file);
}
else
{
// Copying the files
copy($source_dir.'/'.$file, $destination_dir.'/'.$file);
}
}
}
closedir($dir);
}
I have a zip file containing one folder, that contains more folders and files, like this:
myfile.zip
-firstlevel
--folder1
--folder2
--folder3
--file1
--file2
Now, I want to extract this file using PHPs ZipArchive, but without the "firstlevel" folder. At the moment, the results look like this:
destination/firstlevel/folder1
destination/firstlevel/folder2
...
The result I'd like to have would look like this:
destination/folder1
destination/folder2
...
I've tried extractTo, which produces the first mentioned result, and copy(), as suggested here, but this doesn't seem to work at all.
My current code is here:
if($zip->open('myfile.zip') === true) {
$firstlevel = $zip->getNameIndex(0);
for($i = 0; $i < $zip->numFiles; $i++) {
$entry = $zip->getNameIndex($i);
$pos = strpos($entry, $firstlevel);
if ($pos !== false) {
$file = substr($entry, strlen($firstlevel));
if(strlen($file) > 0){
$files[] = $file;
}
}
}
//attempt 1 (extractTo):
//$zip->extractTo('./test', $files);
//attempt 2 (copy):
foreach($files as $filename){
copy('zip://'.$firstlevel.'/'.$filename, 'test/'.$filename);
}
}
How can I achieve the result I'm aiming for?
Take a look at my Quick Unzipper script. I wrote this for personal use a while back when uploading large zip files to a server. It was a backup, and 1,000s of files take forever with FTP so using a zip file was faster. I use Git and everything, but there wasn't another option for me. I place this php file in the directory I want the files to go, and put the zip file in the same directory. For my script, they all have to operate in the same directory. It was an easy way to secure it for my needs, as everything I needed was in the same dir.
Quick Unzipper: https://github.com/incomepitbull/QuickUnzipper/blob/master/unzip.php
I linked the file because I am not showcasing the repo, just the code that makes the unzip tick. With modern versions of PHP, there should't be anything that isn't included on your setup. So you shouldn't need to do any server config changes to use this.
Here is the PHP Doc for the ZipArchive class it uses: http://php.net/manual/en/class.ziparchive.php
There isn't any included way to do what you want, which is a shame. So I would unzip the file to a temp directory, then use another function to copy the contents to where you want. So when using ZipArchive, you will need to return the first item to get the folder name if it is unknown. If the folder is known, ie: the same pesky folder name every time, then you could hard code the name.
I have made it return the first item from the index. So if you ALWAYS have a zip with 1 folder inside it, and everything in that folder, this would work. However, if you have a zip file without everything consolidated inside 1 folder, it would fail. The code I have added will take care of your question. You will need to add further logic to handle alternate cases.
Also, You will still be left with the old directory from when we extract it to the temp directory for "processing". So I included code to delete it too.
NOTE: The code uses a lot of if's to show the processing steps, and print a message for testing purposes. You would need to modify it to your needs.
<?php
public function copyDirectoryContents($source, $destination, $create=false)
{
if ( ! is_dir($source) ) {
return false;
}
if ( ! is_dir($destination) && $create === true ) {
#mkdir($destination);
}
if ( is_dir($destination) ) {
$files = array_diff(scandir($source), array('.','..'));
foreach ($files as $file)
{
if ( is_dir($file) ) {
copyDirectoryContents("$source/$file", "$destination/$file");
} else {
#copy("$source/$file", "$destination/$file");
}
}
return true;
}
return false;
}
public function removeDirectory($directory, $options=array())
{
if(!isset($options['traverseSymlinks']))
$options['traverseSymlinks']=false;
$files = array_diff(scandir($directory), array('.','..'));
foreach ($files as $file)
{
if (is_dir("$directory/$file"))
{
if(!$options['traverseSymlinks'] && is_link(rtrim($file,DIRECTORY_SEPARATOR))) {
unlink("$directory/$file");
} else {
removeDirectory("$directory/$file",$options);
}
} else {
unlink("$directory/$file");
}
}
return rmdir($directory);
}
$file = dirname(__FILE__) . '/file.zip'; // full path to zip file needing extracted
$temp = dirname(__FILE__) . '/zip-temp'; // full path to temp dir to process extractions
$path = dirname(__FILE__) . '/extracted'; // full path to final destination to put the files (not the folder)
$firstDir = null; // holds the name of the first directory
$zip = new ZipArchive;
$res = $zip->open($file);
if ($res === TRUE) {
$firstDir = $zip->getNameIndex(0);
$zip->extractTo($temp);
$zip->close();
$status = "<strong>Success:</strong> '$file' extracted to '$temp'.";
} else {
$status = "<strong>Error:</strong> Could not extract '$file'.";
}
echo $status . '<br />';
if ( empty($firstDir) ) {
echo 'Error: first directory was empty!';
} else {
$firstDir = realpath($temp . '/' . $firstDir);
echo "First Directory: $firstDir <br />";
if ( is_dir($firstDir) ) {
if ( copyDirectoryContents($firstDir, $path) ) {
echo 'Directory contents copied!<br />';
if ( removeDirectory($directory) ) {
echo 'Temp directory deleted!<br />';
echo 'Done!<br />';
} else {
echo 'Error deleting temp directory!<br />';
}
} else {
echo 'Error copying directory contents!<br />';
}
} else {
echo 'Error: Could not find first directory';
}
}
I am connecting to another server via php's ftp connect.
However I need to be able to extract all html files from it's web root which is causing me a bit of a headache...
I found this post Recursive File Search (PHP) which talks about using RecursiveDirectoryIterator function however this is for a directory on the same server as the php script its self.
I've had a go with writing my own function but not sure I've got it right... assuming that the original path sent to the method is the doc root of the server:
public function ftp_dir_loop($path){
$ftpContents = ftp_nlist($this->ftp_connection, $path);
//loop through the ftpContents
for($i=0 ; $i < count($ftpContents) ; ++$i)
{
$path_parts = pathinfo($ftpContents[$i]);
if( in_array($path_parts['extension'], $this->accepted_file_types ){
//call the cms finder on this file
$this->html_file_paths[] = $path.'/'.$ftpContents[$i];
} elseif(empty( $path_parts['extension'] )) {
//run the directory method
$this->ftp_dir_loop( $path.'/'.$ftpContents[$i] );
}
}
}
}
Has anyone seen a premade class to do something like this?
You can try
public function ftp_dir_loop($path) {
$ftpContents = ftp_nlist($this->ftp_connection, $path);
foreach ( $ftpContents as $file ) {
if (strpos($file, '.') === false) {
$this->ftp_dir_loop($this->ftp_connection, $file);
}
if (in_array(pathinfo($file, PATHINFO_EXTENSION), $this->accepted_file_types)) {
$this->html_file_paths[$path][] = substr($file, strlen($path) + 1);
}
}
}
Can I zip files using relative paths?
For example:
$zip->addFile('c:/wamp/www/foo/file.txt');
the ZIP should have a directory structure like:
foo
-> file.txt
and not:
wamp
-> www
-> foo
-> file.txt
like it is by default...
ps: my full code is here (I'm using ZipArchive to compress contents of a directory into a zip file)
See the addFile() function definition, you can override the archive filename:
$zip->addFile('/path/to/index.txt', 'newname.txt');
If you are trying to recursively add all subfolders and files of a folder, you can try the code below (I modified this code/note in the php manual).
class Zipper extends ZipArchive {
public function addDir($path, $parent_dir = '') {
if($parent_dir != ''){
$this->addEmptyDir($parent_dir);
$parent_dir .= '/';
print '<br>adding dir ' . $parent_dir . '<br>';
}
$nodes = glob($path . '/*');
foreach ($nodes as $node) {
if (is_dir($node)) {
$this->addDir($node, $parent_dir.basename($node));
}
else if (is_file($node)) {
$this->addFile($node, $parent_dir.basename($node));
print 'adding file '.$parent_dir.basename($node) . '<br>';
}
}
}
} // class Zipper
So basically what this does is it does not include the directories (absolute path) before the actual directory/folder that you want zipped but instead only starts from the actual folder (relative path) you want zipped.
Here is a modified version of Paolo's script in order to also include dot files like .htaccess, and it should also be a bit faster since I replaced glob by opendir as adviced here.
<?php
$password = 'set_a_password'; // password to avoid listing your files to anybody
if (strcmp(md5($_GET['password']), md5($password))) die();
// Make sure the script can handle large folders/files
ini_set('max_execution_time', 600);
ini_set('memory_limit','1024M');
//path to directory to scan
if (!empty($_GET['path'])) {
$fullpath = realpath($_GET['path']); // append path if set in GET
} else { // else by default, current directory
$fullpath = realpath(dirname(__FILE__)); // current directory where the script resides
}
$directory = basename($fullpath); // parent directry name (not fullpath)
$zipfilepath = $fullpath.'/'.$directory.'_'.date('Y-m-d_His').'.zip';
$zip = new Zipper();
if ($zip->open($zipfilepath, ZipArchive::CREATE)!==TRUE) {
exit("cannot open/create zip <$zipfilepath>\n");
}
$past = time();
$zip->addDir($fullpath);
$zip->close();
print("<br /><hr />All done! Zipfile saved into ".$zipfilepath);
print('<br />Done in '.(time() - $past).' seconds.');
class Zipper extends ZipArchive {
// Thank's to Paolo for this great snippet: http://stackoverflow.com/a/17440780/1121352
// Modified by LRQ3000
public function addDir($path, $parent_dir = '') {
if($parent_dir != '' and $parent_dir != '.' and $parent_dir != './') {
$this->addEmptyDir($parent_dir);
$parent_dir .= '/';
print '<br />--> ' . $parent_dir . '<br />';
}
$dir = opendir($path);
if (empty($dir)) return; // skip if no files in folder
while(($node = readdir($dir)) !== false) {
if ( $node == '.' or $node == '..' ) continue; // avoid these special directories, but not .htaccess (except with GLOB which anyway do not show dot files)
$nodepath = $parent_dir.basename($node); // with opendir
if (is_dir($nodepath)) {
$this->addDir($nodepath, $parent_dir.basename($node));
} elseif (is_file($nodepath)) {
$this->addFile($nodepath, $parent_dir.basename($node));
print $parent_dir.basename($node).'<br />';
}
}
}
} // class Zipper
?>
This is a standalone script, just copy/paste it into a .php file (eg: zipall.php) and open it in your browser (eg: zipall.php?password=set_a_password , if you don't set the correct password, the page will stay blank for security). You must use a FTP account to retrieve the zip file afterwards, this is also a security measure.
I'm using this code to recursive copy of directories (and files). I can't understand why but, after a copy, my $source folder increase ... it has 76.3MB, after a copy it will increase to 123 MB! Any ideia?
<?php
class MyDirectory {
public function copy($source, $destination, $directoryPermission = 0755, $filePermission = 0644) {
$source = $this->addSlash($source);
$destination = $this->addSlash($destination);
$directoryIterator = new DirectoryIterator($source);
if (!file_exists($destination)) {
mkdir($destination, $directoryPermission);
}
foreach ($directoryIterator as $fileInfo) {
$filePath = $fileInfo->getPathname();
$newDestination = str_replace($source, $destination, $filePath);
if (!$fileInfo->isDot()) {
if ($fileInfo->isFile()) {
copy($filePath, $newDestination);
chmod($newDestination, $filePermission);
} else if ($fileInfo->isDir()) {
mkdir($newDestination, $directoryPermission);
$this->copy($filePath, $newDestination);
}
}
}
}
private function addSlash($directory) {
if (!empty($directory)) {
if (!preg_match('/\/$/', $directory)) {
$directory .= '/';
}
return $directory;
}
}
}
UPDATE: There is no significance differences to increase the source size!
$ diff -rq mag/ copy-mag/
Only in mag//app/etc: local.xml
Thank you.
It's very tough to deduce from the source code what goes wrong.
Analyze the directory instead, compare the differences, and update your question with the results. You can use a tool like Beyond Compare (commercial but 30-day trial available) to find out what went wrong.