I'm trying to download a zip generated file but I'm getting a FileNotFoundException, this is the code:
$zipper = new \Chumper\Zipper\Zipper;
foreach($request->values as $id_post){
$post = Post::find($id_post);
$imagenes[] = public_path().'/uploads/posts/'.$post->imagen;
}
$nombreZip = 'test'.time().'.zip';
$rutaZip = (public_path().'/zips/'.$nombreZip);
$zipper->make($rutaZip)->add($imagenes);
return (response()->download($rutaZip, 'posts.zip'));
I have already checked the file route that returns and the file is right there, with the same name and everything. Any ideas?
Try this:
$zipper = new \Chumper\Zipper\Zipper;
foreach($request->values as $id_post){
$post = Post::find($id_post);
$imagenes[] = 'public/uploads/posts/'.$post->imagen;
}
$nombreZip = 'test'.time().'.zip';
$rutaZip = (public_path().'/zips/'.$nombreZip);
$zipper->make("public/zips/{$nombreZip}")->add($imagenes);
return (response()->download($rutaZip, 'posts.zip'));
Related
i'm new in phbp and yii and i have a pronblem with sendind file, i'm using kartik\file\FileInput widget without model and i send to yii controller, where i can get my file from $POST and in first time i used move_uploaded_file with linkt to my file on tmp. The first idea with move doesnt work, i wouldnt find my file on disk, i know is systemd, but i change my tmp folder in php.ini but the file from form doesnt show in this place. This is my conbtroller
$output = "";
$modelZalaczniki = new DelegacjeZalacznikiSearch();
$modelZalaczniki->d_add = date('Y-m-d H:i:s');
$modelZalaczniki->u_add = Yii::$app->user->identity->id;
if (empty($_FILES['file'])){
echo json_encode(['error'=>'Nie znaleziono plik.w.']);
return;
}
$files = $_FILES['file'];
$success = null;
$paths = [];
$fileNames = $files['name'];
if(!file_exists('uploads')){
mkdir('uploads', 0750, true);
}
if(!file_exists('uploads'.DIRECTORY_SEPARATOR.'delegacje')){
mkdir('uploads'.DIRECTORY_SEPARATOR.'delegacje', 0750, true);
}
if(!file_exists('uploads'.DIRECTORY_SEPARATOR.'delegacje'.DIRECTORY_SEPARATOR.'pliki')){
mkdir('uploads'.DIRECTORY_SEPARATOR.'delegacje'.DIRECTORY_SEPARATOR.'pliki', 0750, true);
}
if(!file_exists('uploads'.DIRECTORY_SEPARATOR.'delegacje'.DIRECTORY_SEPARATOR.'pliki'.DIRECTORY_SEPARATOR.$delegacja_id)){
mkdir('uploads'.DIRECTORY_SEPARATOR.'delegacje'.DIRECTORY_SEPARATOR.'pliki'.DIRECTORY_SEPARATOR.$delegacja_id, 0750, true);
}
for($i = 0; $i < count($fileNames); $i++){
$ext = explode('.', basename($fileNames[$i]));
$hashName = md5($fileNames[$i]);
$target = 'uploads'.DIRECTORY_SEPARATOR.'delegacje'.DIRECTORY_SEPARATOR.'pliki'.DIRECTORY_SEPARATOR.$delegacja_id.DIRECTORY_SEPARATOR.$hashName;
// if(file_exists($target)){
// $success = true;
// break;
// }
if(move_uploaded_file($files['tmp_name'][$i], $target)){
$success = true;
$paths[] = $target;
$modelZalaczniki = new DelegacjeZalaczniki();
$modelZalaczniki->delegacja_id = $delegacja_id;
$modelZalaczniki->d_add = date('Y-m-d H:i:s');
$modelZalaczniki->u_add = Yii::$app->user->identity->id;
$modelZalaczniki->sciezka = $target;
$modelZalaczniki->nazwa = $fileNames[$i];
$modelZalaczniki->typ = $ext[1];
$modelZalaczniki->size = $files['size'][$i];
if ($modelZalaczniki->validate()){
$modelZalaczniki->save();
}
}else{
$success = false;
break;
}
Every things work fine but i cant move file to my folder, aha, file is create but in this file is linkt to yii documentation.
Yii 2.0 is great at uploading files. No need for move_uploaded_file.
Take a look at the documentation, and specifically the UploadedFile::getInstance() method.
Useful examples which are relevant to what you're doing are here:
https://www.yiiframework.com/doc/guide/2.0/en/input-file-upload
In the above code, when the form is submitted, the yii\web\UploadedFile::getInstance() method is called to represent the uploaded file as an UploadedFile instance. We then rely on the model validation to make sure the uploaded file is valid and save the file on the server.
In my Laravel project I created a page to upload the files and I use the $file of laravel it works fine for some system only but for some system it shows an error as shown in image below.
Function I am using to upload files in model
public function add_document_sub_cert($req)
{
$subcontractor_id = $req['subcontractor_id'];
$reference_id = $req['reference_id'];
$files = $req->file("uploaded_doc0");
$i = 0;
foreach($files as $file){
$i++;
$ext = $file->guessClientExtension();
$name = $file->getClientOriginalName();
$file_name_1 = str_replace(".".$ext,"",$name);
$path = $file->storeAs('subcontractor/','avc'.$i.'.jpg');
if($path){
$document = new Document();
$document->doc_name = 'avc.jpg';
$document->module = 'subcontractor';
$document->reference_id = $reference_id;
$document->save();
}
}
}
Your error says that you didn't specify a filename. I see that your variable $file_name_1 is never used. Haven't you forgotten to use it somewhere?
Without knowing how your class Document works, it's impossible to tell you exactly where is the bug.
I want to save a file, that I have created in the temp directory, into drupal. But file_save requests a file object but I have just the real path.
$imageId =file_save('/tmp/proj/media/cover.jpg']);
I think you're looking for the file_save_data function, or possibly file_unmanaged_save_data, instead of file_save().
file_save(stdClass $file) save a file object. You are trying to download a file.
You can do as
$file = '/tmp/proj/media/cover.jpg';
// Get the file size
$details = stat($file);
$filesize = $details['size'];
// Get the path to your Drupal site's files directory
$dest = file_directory_path();
// Copy the file to the Drupal files directory
if(!file_copy($file, $dest)) {
echo "Failed to move file: $file.\n";
return;
} else {
// file_move might change the name of the file
$name = basename($file);
}
// Build the file object
$file_obj = new stdClass();
$file_obj->filename = $name;
$file_obj->filepath = $file;
$file_obj->filemime = file_get_mimetype($name);
$file_obj->filesize = $filesize;
$file_obj->filesource = $name;
// You can change this to the UID you want
$file_obj->uid = 1;
$file_obj->status = FILE_STATUS_TEMPORARY;
$file_obj->timestamp = time();
$file_obj->list = 1;
$file_obj->new = true;
// Save file to files table
drupal_write_record('files', $file_obj);
I hope this will help you.
I'm trying to create nodes programatically. Using Media module with the youtube extension, I'd like to populate a field with youtube data. From what I've read so far, it's going to look something like this:
<?php
// $value in this case is the youtube ID.
$file = new stdClass();
$file->uid = 1;
$file->filename = $value;
$file->uri = 'youtube://v/' . $value;
$file->filemime = 'video/youtube';
$file->type = 'video';
$file->status = 1;
$youtube = file_save($file);
node->field_youtube[$node->language]['0']['fid'] = (array) $youtube->fid;
?>
I learned this by looking at the information in the $content variable in the bartik theme. However, this results in a "Bad file extension" error. I also tried putting the whole url in $file->uri and using file_get_mimetype on it, then it didn't throw an error but the video didn't work either. Does anyone know how to do this?
I found the answer. The function file_save only checks if a file id is already in the database. However, the youtube uri field did not allow duplicates. Therefore I stole this function from the file_example module. It checks if a file exists with that uri, if it does it loads the object.
function file_example_get_managed_file($uri) {
$fid = db_query('SELECT fid FROM {file_managed} WHERE uri = :uri', array(':uri' => $uri))->fetchField();
if (!empty($fid)) {
$file_object = file_load($fid);
return $file_object;
}
return FALSE;
}
So in the end I simply put an if statement, like this:
$file_exists = wthm_get_managed_file('youtube://v/' . $value);
if (!$file_exists) {
$file_path = drupal_realpath('youtube://v/' . $value);
$file = new stdClass();
$file->uid = 1;
$file->filename = $value;
$file->uri = 'youtube://v/' . $value;
$file->filemime = file_get_mimetype($file_path);
$file->type = 'video';
$file->status = 1;
$file_exists = file_save($file);
}
$node->field_youtube[$node->language]['0'] = (array) $file_exists;
This solved most problems. I still get a message saying bad file extension, but it works anyway.
I got it working like this. I'm importing embed codes that need to be parsed and some are dupes, and i think this function file_uri_to_object($code, $use_existing = TRUE) allows you to reuse managed urls.
$r->video is an iframe embed code for youtube which gets parsed to the correct uri format
// include the media youtube handler.inc file to use the embed code parsing
$path = drupal_get_path('module','media_youtube').'/includes/MediaInternetYouTubeHandler.inc';
require_once($path);
$code = MediaInternetYouTubeHandler::parse($r->video);
$youtube = file_uri_to_object($code, $use_existing = TRUE);
$youtube->display = 1;
$youtube = file_save($youtube);
$node->field_video[$lang][0] = (array)$youtube;
node_save($node);
A nicer way:
module_load_include('inc', 'media_youtube', 'includes/MediaInternetYouTubeHandler.inc');
$obj = new MediaInternetYouTubeHandler($url);
$file = $obj->getFileObject();
$file->display = 1;
file_save($file);
$product->field_product_video[LANGUAGE_NONE][] = (array) $file;
I will try to explain as well as possible what I'm trying to do.
I have a folder on a server with about 100 xml files. These xml files are content pages with text and references to attachment filenames on the server that will be pushed to a wiki through an API.
It's all working fine 1 XML file at a time but I want to loop through each one and run my publish script on them.
I tried with opendir and readdir and although it doesn't error it only picks up the one file anyway.
Could someone give me an idea what I have to do. I'm very new to PHP, this is my first PHP project so my code is probably not very pretty!
Here's my code so far.
The functions that gets the XML content from the XML file:
<?php
function gettitle($file)
{
$xml = simplexml_load_file($file);
$xmltitle = $xml->xpath('//var[#name="HEADLINE"]/string');
return $xmltitle[0];
}
function getsummary($file)
{
$xml = simplexml_load_file($file);
$xmlsummary = $xml->xpath('//var[#name="summary"]/string');
return $xmlsummary[0];
}
function getsummarymore($file)
{
$xml = simplexml_load_file($file);
$xmlsummarymore = $xml->xpath('//var[#name="newslinetext"]/string');
return $xmlsummarymore[0];
}
function getattachments($file)
{
$xml = simplexml_load_file($file);
$xmlattachments = $xml->xpath('//var[#name="attachment"]/string');
return $xmlattachments[0];
}
?>
Here's the main publish script which pushes the content to the wiki:
<?php
// include required classes for the MindTouch API
include('../../deki/core/dream_plug.php');
include('../../deki/core/deki_result.php');
include('../../deki/core/deki_plug.php');
//Include the XML Variables
include('loadxmlfunctions.php');
//Path to the XML files on the server
$path = "/var/www/dekiwiki/skins/importscript/xmlfiles";
// Open the XML file folder
$dir_handle = #opendir($path) or die("Unable to open $path");
// Loop through the files
while ($xmlfile = readdir($dir_handle)) {
if($xmlfile == "." || $xmlfile == ".." || $xmlfile == "index.php" )
continue;
//Get XML content from the functions and put in the initial variables
$xmltitle = gettitle($xmlfile);
$xmlsummary = getsummary($xmlfile);
$xmlsummarymore = getsummarymore($xmlfile);
$xmlattachments = getattachments($xmlfile);
//Build the variables for the API from the XML content
//Create the page title - replace spaces with underscores
$pagetitle = str_replace(" ","_",$xmltitle);
//Create the page path variable
$pagepath = '%252f' . str_replace("'","%27",$pagetitle);
//Strip HTML from the $xmlsummary and xmlsummarymore
$summarystripped = strip_tags($xmlsummary . $xmlsummarymore, '<p><a>');
$pagecontent = $summarystripped;
//Split the attachments into an array
$attachments = explode("|", $xmlattachments);
//Create the variable with the filenames
$pagefilenames = '=' . $attachments;
$pagefilenamefull = $xmlattachments;
//Create the variable with the file URL - Replace the URL below to the correct one
$pagefileurl = 'http://domain/skins/importscript/xmlfiles/';
//authentication
$username = 'admin';
$password = 'password';
// connect via proxy
$Plug = new DreamPlug('http://domain/#api');
// setup the deki api location
$Plug = $Plug->At('deki');
//authenticate with the following details
$authResult = $Plug->At('users', 'authenticate')->WithCredentials($username, $password)->Get();
$authToken = $authResult['body'];
$Plug = $Plug->With('authtoken', $authToken);
// Upload the page content - http://developer.mindtouch.com/Deki/API_Reference/POST:pages//%7Bpageid%7D//contents
$Plug_page = $Plug->At('pages', '=Development%252f' . $pagetitle, 'contents')->SetHeader('Expect','')->Post($pagecontent);
// Upload the attachments - http://developer.mindtouch.com/MindTouch_Deki/API_Reference/PUT:pages//%7Bpageid%7D//files//%7Bfilename%7D
for($i = 0; $i < count($attachments); $i++){
$Plug_attachment = $Plug->At('pages', '=Development' . $pagepath, 'files', '=' . $attachments[$i])->SetHeader('Expect','')->Put($pagefileurl . $attachments[$i]);
}
}
//Close the XMl file folder
closedir($dir_handle);
?>
Thanks for any help!
To traverse a directory of XML files you can just do:
$files = glob("$path/*.xml");
foreach($files as $file)
{
$xml = simplexml_load_file($file);
$xmltitle = gettitle($xml);
$xmlsummary = getsummary($xml);
$xmlsummarymore = getsummarymore($xml);
$xmlattachments = getattachments($xml);
}
I also recommend you make a minor adjustment to your code so simplexml doesn't need to parse the same file four times to get the properties you need:
function gettitle($xml)
{
$xmltitle = $xml->xpath('//var[#name="HEADLINE"]/string');
return $xmltitle[0];
}
function getsummary($xml)
{
$xmlsummary = $xml->xpath('//var[#name="summary"]/string');
return $xmlsummary[0];
}
function getsummarymore($xml)
{
$xmlsummarymore = $xml->xpath('//var[#name="newslinetext"]/string');
return $xmlsummarymore[0];
}
function getattachments($xml)
{
$xmlattachments = $xml->xpath('//var[#name="attachment"]/string');
return $xmlattachments[0];
}
Try changing your while loop to and see if that helps out better:
while (false !== ($xmlfile = readdir($dir_handle)))
Let me know.
EDIT:
By using the old way, there could have been a directory name that could have evaluated to false and stopped the loop, the way I suggested is considered the right way to loop over a directory while using readdir taken from here