Drupal - creating entries in file_managed - php

I have a custom content type with 2 custom fields: file (file) and list (status).
I can set the value of status by doing:
$node = node_load($n, $r);
$node->field_status[$node->language][0]['value'] = 1;
node_save($node);
I want to create entries for field_file and file_managed (core table) for a file that is ALREADY on the server. I already know the MIME type, size and path of the file.
What is the proper way to achieve this?

I would instantiate the file object manually and use file_save() to commit it (using an image file as an example):
global $user;
$file = new stdClass;
$file->uid = $user->uid;
$file->filename = 'image.png';
$file->uri = 'public://path/to/file/image.png';
$file->status = 1;
$file->filemime = 'image/png';
file_save($file);
You should then call file_usage_add() to let Drupal know your module has a vested interest in this file (using the nid from your $node object):
file_usage_add($file, 'mymodule', 'node', $node->nid);
Finally you can add the file to the node:
$node->field_file[$node->language][] = array(
'fid' => $file->fid
);
Hope that helps

Related

Dynamic Input Array with Image/file in Laravel 8

i am trying to do an update using dynamic for "education history" but there is an image also, i use eloquent to update too, for some reason the data is saved in the database but the image just tmp and cannot find in the folder.
//count array data inputed
for($incs=0; $incs < count($data_detail_user['institution_names']); $incs++) {
// update education
foreach( $data_detail_user['institution_names'] as $key => $file ){
// get old photo thumbnail
$get_photo = Educations::where('id', $key)->first();
// store photo
$path = $file->store(
'assets/education/thumbnail', 'public'
);
$education_user = Educations::find($incs);
$education_user->detail_user_id = $detail_user['id'];
$education_user->name = $data_detail_user['institution_names'][$incs];
$education_user->course = $data_detail_user['education_courses'][$incs];
$education_user->start = $data_detail_user['education_starts'][$incs];
$education_user->graduate = $data_detail_user['education_graduates'][$incs];
$education_user->address = $data_detail_user['education_addresses'][$incs];
$education_user->regencies = $data_detail_user['education_regencies'][$incs];
$education_user->provinces = $data_detail_user['education_provinces'][$incs];
$education_user->country = $data_detail_user['education_countries'][$incs];
$education_user->zip_code = $data_detail_user['education_zips'][$incs];
$education_user->certificate = $data_detail_user['education_certificates'][$incs][$path];
$education_user->save();
$data_detail_user = 'storage/' .$get_photo['certificate'];
if (File::exists($data_detail_user)) {
File::delete($data_detail_user);
} else {
File::delete('storage/app/public/' .$get_photo['certificate']);
}
}
}
[the error show Call to a member function store() on string]
this is the screenshoot of the error
[1]: https://i.stack.imgur.com/l96sm.png
$path = $request->file('path')->store('public/post');
I assume you have a directory where the image is suppose to be stored that's why i created the post directory after public.

Changing a MP3 files ID3 tags

I found a website recently that allows you to upload a file and change its ID3 tags (Image, Title, all that other stuff) and currently I am storing files in a directory after I parse them from another website before pushing them externally.
I am wondering if someone knows a library where I can read how to change the default ID3 tags in PHP? Is this a already existing feature with PHP?
if( writeTags($row['title'],$new) ) {
$fileName = rand(000000000,999999999).'_'.rand(0000000000,9999999999).'_'.rand(000000000,999999999).'.mp3';
$imageName = rand(000000000,999999999).'_'.rand(0000000000,9999999999).'_'.rand(000000000,999999999).'.jpg';
rename($new, $DPATH.'uploads/tracks/'.$fileName);
save_image($row['image'],$DPATH.'uploads/media/'.$imageName);
$track['uid'] = 151;
$track['title'] = $row['title'];
$track['description'] = '';
# fileName
$track['name'] = $fileName;
# make tag
$track['tag'] = $tag.',';
# download image
$track['art'] = $imageName;
# today date
$track['release'] = date("Y-m-d");
$track['size'] = filesize($DPATH.'uploads/tracks/'.$fileName);
$row['slippery_id'] = add_to_slippery($track);
}
function writeTags($title,$file) {
$TextEncoding = 'UTF-8';
require_once($DPATH.'cron/getid3/getid3.php');
$getID3 = new getID3;
$getID3->setOption(array('encoding'=>$TextEncoding));
require_once($DPATH.'cron/getid3/write.php');
$tagwriter = new getid3_writetags;
$tagwriter->filename = $file;
$tagwriter->tagformats = array('id3v1','id3v2.3');
$tagwriter->overwrite_tags = true;
$tagwriter->tag_encoding = $TextEncoding;
$tagwriter->remove_other_tags = true;
$TagData = array(
'album' => array($MP3TAG),
'comment' => array($MP3TAG),
);
$fd = fopen($DPATH.'cron/mp3image.png', 'rb');
$APICdata = fread($fd, filesize($DPATH.'cron/mp3image.png'));
fclose($fd);
$TagData['attached_picture'][0]['data'] = $APICdata;
$TagData['attached_picture'][0]['picturetypeid'] = 2;
$TagData['attached_picture'][0]['description'] = $MP3TAG;
$TagData['attached_picture'][0]['mime'] = 'image/jpeg';
$tagwriter->tag_data = $TagData;
if ($tagwriter->WriteTags()) {
return true;
} else {
return false;
}
}
I recently did something similar, you can edit the above code to match your requirements, if you wanted me to be more helpful you should have provided your own code within your question.
Please note that asking questions like this is often how your questions get shut down, good luck in the future and I hope this helps you.
EDIT: Use this GitHub for getting the ID3 tags.
I have recently made a PHP wrapper for eyeD3, a great python module for reading and updating ID3 metadata. Check it out here.
Usage is pretty simple if you're familiar with Composer. However, you will need to install eyed3 in order to use it. Then:
Install the php wrapper using composer:
composer require stormiix/php-eyed3 dev-master
Add the library to your code:
require __DIR__ . '/vendor/autoload.php';
Use the following code to read & update tags.
use Stormiix\EyeD3\EyeD3;
$eyed3 = new EyeD3("mp3 file path");
$tags = $eyed3->readMeta();
// $tags is an array that contains the following keys:
// artist, title, album, comment(s), lyrics ..etc
$meta = [
"artist" => "MyArtist",
"title" => "MyTitle",
"album" => "MyAlbum",
"comment" => "MyComment",
"lyrics" => "MyLyrics",
"album_art" => "cover.png"
];
// Update the mp3 file with the new meta tags
$eyed3->updateMeta($meta);

sugarCRM add document from script

I am trying to add Document to Sugar object (client) from PHP script. I have a directory of files (on the same server where sugarCRM is installed) and xls with sugar objec ID and filename). PHP Script should add correct filename to specific sugar object (identified with ID). I can read XLS this is no problem, I can also get instance of sugar object (retrieve by ID), but I have no idea how can I assign the file to sugar. I was trying with Document, and upload_file.php, but those seem to be usable with uploading single file with html Form.
How can I automate this task, copy files with correct filename to cache\upload and create Document related to my Customer from PHP Script? I would prefer not to use SOAP if it's not necesarry...
Edit:
I was able to save document and revision, but something is wrong, and file can't be downloaded from browser ("incorrect call to file")
My Code so far is:
require_once('include/upload_file.php');
$upload_file = new UploadFile('uploadfile');
$document->filename = 'robots.txt';
$document->document_name = 'robots.txt';
$document->save();
$contents = file_get_contents ($document->filename);
$revision = new DocumentRevision;
$revision->document_id = $document->id;
$revision->file = base64_encode($contents);
$revision->filename = $document->filename;
$revision->revision = 1;
$revision->doc_type = 'Sugar';
$revision->file_mime_type = 'text/plain';
$revision->save();
$document->revision_id = $revision->id;
$document->save();
$destination = clean_path($upload_file->get_upload_path($document->id));
$fp = sugar_fopen($destination, 'wb');
if( !fwrite($fp, $contents) ){
die("ERROR: can't save file to $destination");
}
fclose($fp);
WORKS! I Hope this will help someone
I have corrected 3 lines from code abowe:
//$document->revision_id = $revision->id;
//$document->save();
$destination = clean_path($upload_file->get_upload_path($revision->id));

Drupal 7 save user picture programmatically

I have found this script http://d.danylevskyi.com/node/7 which I have used as a starter for the below code.
The goal is to be able to save a user picture:
<?php
define('DRUPAL_ROOT', getcwd());
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
$uid = 99;
$account = user_load($uid);
// get image information
$image_path = 'public://avatars/upload/b8f1e69e83aa12cdd3d2babfbcd1fe27_4.gif';
$image_info = image_get_info($image_path);
// create file object
$file = new StdClass();
$file->uid = $uid;
$file->uri = $image_path;
$file->filemime = $image_info['mime_type'];
$file->status = 0; // Yes! Set status to 0 in order to save temporary file.
$file->filesize = $image_info['file_size'];
// standard Drupal validators for user pictures
$validators = array(
'file_validate_is_image' => array(),
'file_validate_image_resolution' => array(variable_get('user_picture_dimensions', '85x85')),
'file_validate_size' => array(variable_get('user_picture_file_size', '30') * 1024),
);
// here all the magic :)
$errors = file_validate($file, $validators);
if (empty($errors)) {
file_save($file);
$edit['picture'] = $file;
user_save($account, $edit);
}
?>
A picture is created in sites/default/files/pictures/ with the name picture-99-1362753611.gif
Everything seems correct in the file_managed table except that:
the filename field is empty
the uri field shows public://avatars/upload/b8f1e69e83aa12cdd3d2babfbcd1fe27_4.gif
the status field is set to 0 (temporary)
The picture field in the users table gets updated with the fid of the above mentioned entry.
I would guess that the file_managed table should store the final file (in sites/default/pictures) instead of the original file info and that the users table should link to the one too.
Any idea how I can achieve that? I am quite new to the Drupal API. Thank you.
Edit:
I understand that I am giving the original file to the file_save and user_save functions. But which one actually creates the file in sites/default/pictures/ ?
Try adding the following to your code:
$file->filename = drupal_basename($image_path);
$file->status = FILE_STATUS_PERMANENT;
$file = file_save($file); // Use this instead of your current file_save
Does that help?
------------------ EDIT ------------------
If you want to save a copy of the file in a new location, you can replace the third line above with something like
// Save the file to the root of the files directory.
$file = file_copy($file, 'public://');

Drupal 6 Node Creation PHP Script with File upload not working

I've got this PHP script I'm working on to import pay-stubs into Drupal. It's doing everything the way I want except the script is not attaching the uploaded PDF file to the node.
A few notes; Drupal's filesystem is set to private, not sure if this makes a difference or not. Second, the pdf files are already in the correct location 'paystubs/[uid]/paystub_1.pdf' so I think my problem is that the file is not being associated to the node correctly.
Here is the code
function create_drupal_node($employeeID, $employeeDate, $drupalUid, $file2) {
$sourcePDF = "/var/www/html/mgldev.************.com/burst_pdfs/pdfs/" . $file2;
$destinationPDF = '/paystubs/' . $drupalUid . '/' . $file2;
$destination = '/paystubs/' . $drupalUid . '/';
if (!file_check_directory($destination, TRUE)){
echo "Failed to check dir, does it exist?";
mkdir($destination);
echo "trying to drupal mkdir...";
}
// Copy the file to the Drupal files directory
if (file_exists($sourcePDF)) {
if(!rename($sourcePDF, $destinationPDF)) {
echo "Failed to move file\n";
}
}
//Create node and attach file uplaod
$file_drupal_path = "paystubs/" . $drupalUid . "/" . $file2;
$mime = 'pdf/application';
$file = new stdClass();
$file->filename = $file2;
$file->filepath = $file_drupal_path;
$file->filemime = $mime;
$file->filesize = filesize($file_drupal_path);
$file->uid = $drupalUid;
$file->status = FILE_STATUS_PERMANENT;
$file->timestamp = time();
drupal_write_record('files', $file);
$node = new StdClass();
$node->type = 'paystub';
$node->body = $employeeID;
$node->title = $employeeDate;
$node->field_paystub_upload = array(
array(
'fid' => $file->fid,
'title' => $file2,
'filename' => $file->filename,
'filepath' => $file->filepath,
'filesize' => $file->filesize,
'mimetype' => $mime,
'data' => array(
'description' => $file2,
),
'list' => 1,
),
);
$node->uid = $drupalUid;
$node->status = 1;
$node->active = 1;
$node->promote = 1;
node_save($node);
}
The node is created and the title and body of the node have the right values. When I look at the node using Devel module I can see that the 'field_paystub_upload' array is null. So for some reason its doing everything right except attaching the file to the node and that is what I've been banging my head on for days. Best response gets on free internet?
Drupal's file.inc file_save_upload uses $_FILES, which is a global, magically set by PHP. Drupal expects an uploaded file, not a file that exists locally.
You best just call a custom file-saver method, to process local files. Make sure its path up in the files database-table too. file_save_upload will be valuable for creating such a helper method.
Big thanks to berkes for helping me solve this problem. Turns out that since the files were already on the drupal webserver and not being uploaded to PHP $_FILES global variable, I was unable to programmatically upload the file correctly.
This was causing every other way I've tried to fail. I tried using Drupals defualt upload module and I also tried using CCK's fielfield module both were not working. Thanks to berkes suggestion I found a function that comes with CCK's filefield widget to save uploaded files that are already on the server. Hopefully this helps someone else.
This is the function I found that can save a file thats already on the web-server.
Here is the working code I used to create the node and attach the file after calling field_file_save_file.
function create_drupal_node($employeeID, $employeeDate, $drupalUid, $file2){
$file_remove_html_extention = substr($file2, 0, -7);
$file_pdf = $file_remove_html_extention . '.pdf';
$node = new stdClass();
$node->type = 'paystub';
$node->status = 1;
$node->uid = $drupalUid;
$node->title = $employeeDate . ' - eStub';
$node->body = $employeeID;
$node->created = time();
$node->changed = $node->created;
$node->promote = 1;
$node->sticky = 0;
$node->format = 1;
$node->language = 'en';
$file = '/var/www/html/mgldev.foobar.com/burst_pdfs/pdfs/' . $file_pdf;
// Get the path to your Drupal site's files directory
$dest_folder = '/paystubs/' . $drupalUid;
$dest = 'paystubs/' . $drupalUid . '/' . $file_pdf;
if (!file_check_directory($dest_folder, TRUE)){
mkdir($dest_folder);
}
// Load the CCK field
$field = content_fields('field_paystub_upload', 'paystub');
// Load the appropriate validators
$validators = array_merge(filefield_widget_upload_validators($field));
// Create the file object
$file = field_file_save_file($file, $validators, $dest_folder);
// Apply the file to the field, this sets the first file only, could be looped
// if there were more files
$node->field_paystub_upload = array(0 => $file);
// The file has been copied in the appropriate directory, so it can be
// removed from the import directory
unlink($file);
// change file status to permanent
file_set_status($file,1);
node_save($node);
}
</pre></code>
Thanks again berkes

Categories