working with folders with SharePoint phpSPO library - php

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();

Related

phpSPO library - How to copy subfolders in Sharepoint

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/>");
}

problem when compile .docx file from codeigniter php

i have this simple code that generate a new .docx file from a sample with some "token" to modify
this code work in a local MAMP webserver
$template_file_name = 'template2.docx';
$rand_no = rand(111111, 999999);
$fileName = "results_" . $rand_no . ".docx";
$folder = "results";
$full_path = $folder . '/' . $fileName;
echo $full_path;
try
{
if (!file_exists($folder))
{
mkdir($folder);
}
//Copy the Template file to the Result Directory
copy($template_file_name, $full_path);
// add calss Zip Archive
$zip_val = new ZipArchive;
//Docx file is nothing but a zip file. Open this Zip File
if($zip_val->open($full_path) == true)
{
// In the Open XML Wordprocessing format content is stored.
// In the document.xml file located in the word directory.
$key_file_name = 'word/document.xml';
$message = $zip_val->getFromName($key_file_name);
$timestamp = date('d-M-Y H:i:s');
// this data Replace the placeholders with actual values
$message = str_replace("token1", "text to replace", $message);
//Replace the content with the new content created above.
$zip_val->addFromString($key_file_name, $message);
$zip_val->close();
}
echo "<script type='text/javascript'>alert('file creato');</script>";
}
catch (Exception $exc)
{
$error_message = "Error creating the Word Document";
var_dump($exc);
}
in online webserver despite the file and folder are 777 privileges ,the file was created but without my text to replace
in codeigniter i get this error:
$message = $zip_val->getFromName($key_file_name);
$zip_val->addFromString($key_file_name, $message);
$zip_val->close();
anyone can help me ?
the stranger thigs are that in webserver in local work without problem, on webserver online doesnt work
i hope in your answer
thanks a lot

Read an excel file stored in media folder

I'm developing a WordPress plugin that requires to upload an excel file and then read the data inside of it.
I'm using the function "media_handle_upload" to upload the excel file, then, when I try to use SpreadsheetReader to read the file there's an error saying that the file is not readable.
This is what I'm coding, (I know it's horrible coding, but I'm learning and this is just to get the plugin working)
if(isset($_FILES['test_upload_pdf'])){
$pdf = $_FILES['test_upload_pdf'];
// Use the wordpress function to upload
// test_upload_pdf corresponds to the position in the $_FILES array
// 0 means the content is not associated with any other posts
$uploaded=media_handle_upload('test_upload_pdf', 0);
// Error checking using WP functions
if(is_wp_error($uploaded)){
echo "Error uploading file: " . $uploaded->get_error_message();
}else{
echo $pdf."<br>";
$year = date('Y');
$month = date('m');
$targetPath = get_site_url()."/wp-content/uploads/".$year."/".$month."/".$_FILES['test_upload_pdf']['name'];
$targetPath2 = $_SERVER['DOCUMENT_ROOT']."/".$_SERVER["HTTP_HOST"]."/wp-content/uploads/".$year."/".$month."/".$_FILES['test_upload_pdf']['name'];
echo "<br>";
echo $targetPath2;
echo "<br>";
try
{
$Reader = new SpreadsheetReader($targetPath2);
}
catch (Exception $E)
{
echo $E -> getMessage();
}
I think the reader doesn't work because is trying to access "localhost" instead of the physical folder, for example, one of the $targetPath prints this:
http://127.0.0.1/wordpress/wp-content/uploads/2019/04/example.xlsx
So... My question is, there's a way to access the media files so I can open them with the reader?
Thanks.
Perhaps this helps:
https://developer.wordpress.org/reference/functions/wp_upload_dir/
Otherwise try to hardcode folder "/your/path/to/upload/folder/file.extension" and find out how to create this programmaticly

Application Folder backup using Codeigniter

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);
}
}

For loop over named folder to read each .txt filename and contents

The script below takes a named file that resides in the "myplugin" folder (the folder that the script itself resides in) and runs file_get_contents() on it to load the contents into memory, then does some preprocessing on the contents before finally inserting it as a post into the WordPress database via the wp_insert_post method.
$my_post3 = array();
$my_post3['post_title'] = 'Privacy Policy';
if(file_exists(ABSPATH.'/wp-content/plugins/myplugin/pages/privacy_policy.txt'))
{
$my_privacy_policy = file_get_contents(ABSPATH.'/wp-content/plugins/myplugin/pages/privacy_policy.txt');
}
else
{
$my_privacy_policy = "";
}
$my_post3['post_content'] = addslashes($my_post3_replace);
$my_post3['post_type'] = 'page';
$my_post3['post_status'] = 'publish';
wp_insert_post($my_post3);
This method works pretty good. However, this method forces me to write a different routine for every file I want to use as the basis of a new page.
What I would like to do instead, is create a folder called "pages" and place my .txt files in that, then run a for loop on the contents of the folder, creating a new page for each file in the folder. I'd like to use the file name (minus the .txt extension) as the name of the page.
For example, the pages folder may have these files:
About Us.txt
Contact Us.txt
And the routine would result in the creation of two new pages in WordPress site, one called "About Us" containing the content found in that file. The other page would of course be "Contact Us" with the contents of that file.
In this way, I can just drop an unlimited number of named and prepopulated .txt files into that folder and when I activate my plugin, it creates those pages.
I just need some help with the for loop and how to reference the folder and files.
I will also have a folder called "posts", which will do the same for posts that this routine does for pages.
Thanks in advance for your help and suggestions.
Update based on #clientbucket answer:
DEFINE ('PAGES', './pages/');
$directory_pages = new DirectoryIterator(PAGES);
foreach ($directory_pages as $files) {
if ($files_pages->isFile()) {
$file_name_page = $files_pages->getFilename();
$my_page_content = file_get_contents(PAGES. $file_name_page);
$my_page['post_content'] = addslashes($my_page_content);
$my_page['post_title'] = $file_name_page;
$my_page['post_type'] = 'page';
$my_page['post_status'] = 'publish';
wp_insert_post($my_page);
}
}
DEFINE ('POSTS', './posts/');
$directory_posts = new DirectoryIterator(POSTS);
foreach ($directory_posts as $files_posts) {
if ($files_posts->isFile()) {
$file_name_post = $files_posts->getFilename();
$my_post_content = file_get_contents(POSTS. $file_name_post);
$my_post['post_content'] = addslashes($my_post_content);
$my_post['post_title'] = $file_name_post;
$my_post['post_type'] = 'post';
$my_post['post_status'] = 'publish';
$post_id = wp_insert_post($my_post);
stick_post($post_id);
}
}
Fatal error: Uncaught exception 'UnexpectedValueException' with message 'DirectoryIterator::__construct(./pages/) [directoryiterator.--construct]: failed to open dir: No such file or directory' in C:\xampplite\htdocs\mytestsite\wp-content\plugins\myplugindirectory\myplugin.php:339
Line 339 is here > $directory_pages = new DirectoryIterator(PAGES);
Here is another way you could try.
DEFINE ('PAGES', './pages/'); //Define the directory path
$directory = new DirectoryIterator(PAGES); //Get all the contents in the directory
foreach ($directory as $files) { //Check that the contents of the directory are each files and then do what you want with them after you have the name of the file.
if ($files->isFile()) {
$file_name = $files->getFilename();
$my_page = file_get_contents(PAGES. $file_name); //Collect the content of the file.
} else {
//Insert nothing into the $my_privacy_policy variable.
}
echo $my_page; // Do what you want with the contents of the file.
}
From the PHP manual here:
http://php.net/manual/en/function.glob.php
They provide this solution for finding all text files in a directory:
<?php
foreach (glob("*.txt") as $filename) {
echo $filename . "\n";
}
?>
Given this example, your actual request is to be able to create a file based on the name in another directory. I'll leave the hard work to you - but this is a simple implementation:
<?php
$source_dir = "/your/directory/with/textfiles";
$target_dir = "/directory/to/create/files/in";
foreach (glob($source_dir . DIRECTORY_SEPARATOR . "*.txt") as $filename) {
$filepart = explode('.',$filename);
file_put_contents($target_dir . DIRECTORY_SEPARATOR . $filepart[0] . ".php");
}
?>

Categories