I am using the phpSPO library for sharepoint: https://github.com/vgrem/phpSPO
I am able to copy a folder along with it's files using:
$credentials = new ClientCredential("MyCredentialsGoHere","MyCredentialsGoHere");
$ctx = (new ClientContext("https://MyURL.sharepoint.com/enquiries"))->withCredentials($credentials);
$sourceFolder = $ctx->getWeb()->getFolderByServerRelativeUrl("Shared Documents/Project Templates");
$targetFolder = $sourceFolder->copyTo("Shared Documents/".$test, true)->executeQuery();
However it does not copy any subfolders.
I assume that I have to iterate through the subfolders of my source directory manually doing a copy for each one to the new target directory.
My starting point for this was to list the subfolders in a SharePoint folder:
$credentials = new ClientCredential("MyCredentialsGoHere","MyCredentialsGoHere");
$ctx = (new ClientContext("https://MyURL.sharepoint.com/enquiries"))->withCredentials($credentials);
$sourceFolder = $ctx->getWeb()->getFolderByServerRelativeUrl("Shared Documents/Project Templates");
$subfolders = $sourceFolder->getFolders()->executeQuery();
foreach ($subfolders as $folder) {
print_r($folder);
}
However this doe not work as I expected (it produces no output) and my resources are exhausted.
Any pointers to help me solve the issue or an example of a finished solution would be very helpful.
This will loop the folders in a folder:
$parentpath = $ctx->getWeb()->getFolderByServerRelativeUrl("Shared Documents/Project Templates");
$folders = $parentpath->getFolders();
$ctx->load($folders);
$ctx->executeQuery();
foreach ($folders->getData() as $folder) {
$display = $folder->getProperty("ServerRelativeUrl");
echo ("File name: ".$display."<br/>");
}
Related
I'm working with phpSPO library for work with sharePooint in a PHP app.
https://github.com/vgrem/phpSPO
For example, I retrieve the files of an specific folder
try {
$authCtx = new AuthenticationContext($Settings['Url']);
$authCtx->acquireTokenForUser($Settings['UserName'],$Settings['Password']);
// conecction successfull
$folderUrl = "/sites/mySite/Tfts/eiic";
$url = $Settings['Url'] . "/_api/web/getFolderByServerRelativeUrl('{$folderUrl}')/Files";
$request = new RequestOptions($url);
$ctx = new ClientContext($url,$authCtx);
$data = $ctx->executeQueryDirect($request);
// HOW to Convert $data to FolderItem or Folder class ??
}
catch (Exception $e) {
echo 'Error: ', $e->getMessage(), "\n";
}
In the example above, $data is a JSON with the folder files but, How can I convert this JSON to a File or FileCollection for working with its properties?
Another Question, How to Upload a file to a specific folder ??
Thank u very much !
I would suggest to target entities such as File and Folder when dealing with SharePoint resources.
In that case the example for getting files under a specific folder could be converted to:
$files = $ctx->getWeb()->getFolderByServerRelativeUrl($parentFolderUrl)->getFiles();
$ctx->load($files);
$ctx->executeQuery();
//print files info
foreach ($files->getData() as $file) {
print "File name: '{$file->getProperty("ServerRelativeUrl")}'\r\n";
}
Let's say your site has the following structure:
Documents (library)
|
--- Archive (folder)
|
--- 2001 (folder)
then the below example demonstrates how to upload file into 2001 sub folder:
$targetFolderUrl = "/Documents/Archive/2007";
$localPath = "./User Guide.docx";
$fileName = basename($localPath);
$fileCreationInformation = new FileCreationInformation();
$fileCreationInformation->Content = file_get_contents($localPath);
$fileCreationInformation->Url = $fileName;
$uploadFile = $ctx->getWeb()->getFolderByServerRelativeUrl($targetFolderUrl)->getFiles()->add($fileCreationInformation);
$ctx->executeQuery();
I know there is quite some code out there about that topic. But I can't get the code I found to work...
I'm using a function that comes from a Wordpress plugin called Zip-Attachments.
So I modified it to zip files from a specific folder. BUT it doesn't work....
It seems as if I'm missing something when it comes to accurately assigning a paths within the RecursiveDirectoryIterator class.
I was able to zip a single file and downloading it without the recursiveIteration functionality and passing the absolute path as a string. So the main part of the function works.
What am I missing to make that function work?
Here is my non working code:
function za_create_zip_callback(){
$upload_dir = wp_upload_dir();
$rootPath = $upload_dir['basedir'];
$upload_dir_Knippsbox = 'Knippsbox';
// Prepare File
$file = tempnam($upload_dir['path'], "zip");
$zip = new ZipArchive();
$zip->open($file, ZipArchive::OVERWRITE);
// create recursive directory iterator
$files = new RecursiveIteratorIterator (new RecursiveDirectoryIterator("{$rootPath}/{$upload_dir_Knippsbox}/"), RecursiveIteratorIterator::LEAVES_ONLY);
// let's iterate
foreach ($files as $name => $fileX) {
$filePath = $fileX->getRealPath();
$zip->addFile($filePath);
}
//Close the file
$zip->close();
// Add a download to the Counter
global $wpdb;
$meta_name = "_za_counter";
// Retrieve the meta value from the DB
$za_download_count = get_post_meta($postId, $meta_name, true) != '' ? get_post_meta($postId, $meta_name, true) : '0';
$za_download_count = $za_download_count + 1;
// Update the meta value
update_post_meta($postId, $meta_name, $za_download_count);
// We have to return an actual URL, that URL will set the headers to force the download
echo zip_attachments_url."/download.php?za_pretty_filename=".sanitize_file_name($pretty_filename)."&za_real_filename=".$filename;
die();}
Desperately looking for your expert views...
Thanks,
Ben
I'm writing a PHP script that archives a selected directory and all its sub-folders. The code works fine, however, I'm running into a small problem with the structure of my archived file.
Imagine the script is located in var/app/current/example/two/ and that it wants to backup everything plus its sub directories starting at var/app/current
When I run the script it creates an archive with the following structure:
/var/app/current/index.html
/var/app/current/assets/test.css
/var/app/current/example/file.php
/var/app/current/example/two/script.php
Now I was wondering how:
a) How can I remove the /var/app/current/ folders so that the root directory of the archive starts beyond the folder current, creating the following structure:
index.html
assets/test.css
example/file.php
example/two/script.php
b) Why & how can I get rid of the "/" before the folder var?
//Create ZIP file
$zip = new ZipArchive();
$tmpzip = realpath(dirname(__FILE__))."/".substr(md5(TIME_NOW), 0, 10).random_str(54).".zip";
//If ZIP failed
if($zip->open($tmpzip,ZIPARCHIVE::CREATE)!== TRUE)
{
$status = "0";
}
else
{
//Fetch all files from directory
$basepath = getcwd(); // var/app/current/example/two
$basepath = str_replace("/example/two", "", $basepath); // var/app/current
$dir = new RecursiveDirectoryIterator($basepath);
//Loop through each file
foreach(new RecursiveIteratorIterator($dir) as $files => $file)
{
if(($file->getBasename() !== ".") && ($file->getBasename() !== ".."))
{
$zip->addFile(realpath($file), $file);
}
}
$zip->close();
You should try with:
$zip->addFile(realpath($file), str_replace("/var/app/current/","",$file));
I've never used the ZipArchive class before but with most archiver application it works if you change the directory and use relative path.
So you can try to use chdir to the folder you want to zip up.
I am trying to create a web app using codeigniter which will be used over a home or office network. Now Im looking for a backup option which can be done from the web protal. For example, in my htdocs folder i have: App1, App2 etc.
i want to backup and download the App1 folder directly from the webapp which can be done from any client machine which is connected to the server. is it possible. if yes then can you please let me know how?
~muttalebm
sorry for the late reply. I found a quite easy and simple backup option builtin with codeigniter. Hope this helps someone
$this->load->library('zip');
$path='C:\\xampp\\htdocs\\CodeIgniter\\';
$this->zip->read_dir($path);
$this->zip->download('my_backup.zip');
i used the code directly from the view and then just called it using the controller.
~muttalebm
Basically what you want to do is zip the application folder and download it, fairly simple to do. Please check out:
Download multiple files as a zip folder using php
On how to zip a folder for download.
I you do not have that extension a simple command can be used instead, I assume you are running on Linux if not replace command with zip/rar Windows equivalent:
$application_path = 'your full path to app folder without trailing slash';
exec('tar -pczf backup.tar.gz ' . $application_path . '/*');
header('Content-Type: application/tar');
readfile('backup.tar.gz');
Note: Make every effort to protect this file from being accessed by unauthorized users otherwise a malicious user will have a copy of your site code including config details.
// to intialize the path split the real path by dot .
public function init_path($string){
$array_path = explode('.', $string);
$realpath = '';
foreach ($array_path as $p)
{
$realpath .= $p;
$realpath .= '/';
}
return $realpath;
}
// backup files function
public function archive_folder($source = '' , $zip_name ='' , $save_dir = '' , $download = false){
// Get real path for our folder
$name = 'jpl';
if($zip_name == '')
{
$zip_name = $name."___(".date('H-i-s')."_".date('d-m-Y').")__".rand(1,11111111).".zip";
}
$realpath = $this->init_path($source);
if($save_dir != '')
{
$save_dir = $this->init_path($save_dir);
}else{
if (!is_dir('archives/'))
mkdir('archives/', 0777);
$save_dir = $this->init_path('archives');
}
$rootPath = realpath( $realpath);
// echo $rootPath;
// return;
// Initialize archive object
$zip = new ZipArchive();
$zip->open($save_dir . '\\' . $zip_name, ZipArchive::CREATE | ZipArchive::OVERWRITE);
// Create recursive directory iterator
/** #var SplFileInfo[] $files */
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($rootPath),
RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($files as $name => $file)
{
// Skip directories (they would be added automatically)
if (!$file->isDir())
{
// Get real and relative path for current file
$filePath = $file->getRealPath();
$relativePath = substr($filePath, strlen($rootPath) + 1);
// Add current file to archive
$zip->addFile($filePath, $relativePath);
}
}
// Zip archive will be created only after closing object
$zip->close();
if($download){
$this->download($zip);
}
}
Problem
I am building an online file manager, for downloading a whole directory structure I am generating a zip file of all subdirectories and files (recursively), therefore I use the RecursiveDirectoryIterator.
It all works well, but empty directories are not in the generated zip file, although the dir is handled correctly. This is what i am currently using:
<?php
$dirlist = new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS);
$filelist = new RecursiveIteratorIterator($dirlist, RecursiveIteratorIterator::SELF_FIRST);
$zip = new ZipArchive();
if ($zip->open($tmpName, ZipArchive::CREATE) !== TRUE) {
die();
}
foreach ($filelist as $key=>$value) {
$result = false;
if (is_dir($key)) {
$result = $zip->addEmptyDir($key);
//this message is correctly generated!
DeWorx_Logger::debug('added dir '.$key .'('.$this->clearRelativePath($key).')');
}
else {
$result = $zip->addFile($key, $key);
}
}
$zip->close();
If I ommit the FilesystemIterator::SKIP_DOTS I end up having a . file in all directories.
Conclusion
The iterator works, the addEmptyDir call gets executed (the result is checked too!) correctly, creating a zip file with various zip tools works with empty directories as intendet.
Is this a bug in phps ZipArchive (php.net lib or am I missing something? I don't want to end up creating dummy files just to keep the directory structure intact.