I have to administer a Drupal Website, which I didn't set up and honestly, I haven't much experience with Drupal yet.
But I have a serious problem: If I upload a file (it's a PDF) not attached to a node, it will be deleted every few hours. Apparently, I need to indicate it as permanent manually from the file overview page.
Is there a way to set it as permanent automatically?
Hope you can help me! Thanks!
You need to set the status parameter on the file object then use file_save to save it:
// First obtain a file object, for example by file_load...
$file = file_load(10);
// Or as another example, the result of a file_save_upload...
$file = file_save_upload('upload', array(), 'public://', FILE_EXISTS_REPLACE);
// Now you can set the status
$file->status = FILE_STATUS_PERMANENT;
// And save the status.
file_save($file);
Related
I am using TinyMCE as a WYSIWYG editor.
It is working perfectly, except for the image upload directory. I want each user to have their own directory in the images directory, but I cannot get it to work.
I am passing the user id in the URL and have tried adding the code to get it from the URL in the config.php file where the directories are defined, but the $user_id value remains empty.
Any assistance would be great.
The URL:
http://mydomain.co.za/index.php?user_id=1
The Code:
<?php
$user_id= htmlspecialchars($_GET["user_id"]);
// The URL that points to the upload folder on your site.
// Can be a relative or full URL (include the protocol and domain)
$imageURL = 'http://mydomain.co.za/images/'.$user_id;
// Full upload system path. Make sure you have write permissions to this folder
$uploadPath = '/home/username/public_html/editor/images/'.$user_id;
//We create the directory if it does not exist - you can remove this if you consider it a security risk
if(!is_dir($uploadPath)) {
mkdir($uploadPath,0755,true);
}
//Create thumb directory if doesn't exist
if(!is_dir($uploadPath . 'thumbnail')) {
mkdir($uploadPath . 'thumbnail',0755,true);
}
//Allowed extenstions
$allowedExtensions = array('jpg','gif','jpeg','bmp','tif','png');
//Maximum upload limit
$sizeLimit = 2 * 1024 * 1024;
function isAuth() {
//Perform your own authorization to make sure user is allowed to upload
return true;
}
Is it possible the reason is because it is not in the main php file?
Or Can I get the variable from the URL?
They suggested on their Instructions that I add $userId = Auth::getId(); but id returns an empty value. Plus I have no idea what that command is executing.
PLEASE NOTE:
the file management is being done by TinyMCE Image Uploader & Manager
UPDATE:
By adding the $actual_link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; echo $actual_link; I noticed by the time the $_GET command is rung the URL has changed to http://mydomain.co.za/tinymce/plugins/lioniteimages/connector/php/gallery.php, but in the browser URL bar, the URL is still the same with the variable.
Is there anyway to access that URL instead of the one i am getting?
I found the solution.
Simple enough, just created a session and the problem was solved.
I was able to get the variable from the session.
I wanna create a few unique download link for my users. The reason is that I wanted to let them download once only, so that they can use back the same link to download again.
I've generate a few of the keys (example, qwertyasdfghzxcbn. As in the download link will be like www.xxxxx.com/download.php?qwertyasdfghzxcbn) in the database and flag field where when the user downloaded, it will update 1 to the flag field.
I did a search on the net and found this.
http://www.webvamp.co.uk/blog/coding/creating-one-time-download-links/
But that only works when you go to the page first then only the page will generate the unique link. I've already pre-generate the link inside my database, I don't need to regenerate again, if fact if I generate the key when user go the page, they will able to download multiple times by refreshing the page.
The solution would be to make the link target itself a PHP script.
You'd hide the actual file somewhere inaccessible from the browser (i.e., somewhere where you can reach the file via fopen(), but isn't within the document root), and put a download.php file to download files.
The download script itself would look something like this:
$fileid = $_REQUEST['file'];
$file = file_location($fileid); // you'd write this function somehow
if ($file === null) die("The file doesn't exist");
$allowed = check_permissions_for($file, $fileid) // again, write this
// the previous line would allow you to implement arbitrary checks on the file
if ($allowed) {
mark_downloaded($fileid, $file); // so you mark it as downloaded if it's single-use
header("Content-Type: application/octet-stream"); // downloadable file
echo file_get_contents($file);
return 0; // running a return 0; from outside any function ends the script
} else
die("You're not allowed to download this file");
Any link you point would simply point to download.php?fileid=712984 (whatever the fileid actually is). That would be the actual download link, since that script does transfer the file; but only if the user is allowed to retrieve it. You'd have to write the file_location(), check_permissions_for() and mark_downloaded() functions yourself though.
I would suggest using uniqid() function, and store unique ids with the expiration date in a database, while returning to the user url with something like this: ...?file_id=$id
When the link is being opened, you may delete it from the database or mark it to be deleted 'soon' (just in case user wants to refresh the page.)
This question is more about methodology than actual code - lines
I would like to know how to implement a pseudo caching (for lack of a better name) for FILES in php . I have tried to read some articles, but most of them refer to the internal caching system of PHP , and not to what I need which is a FILE cache.
I have several scenarios where I needed such a system applied :
Scenario 1 :
While accessing a post and clicking a link, all the post attachments are collected and added to a zip file for download.
Scenario 2 :
Accessing a post , the script will scan all the content , extract all links, download some matching images for each link (or dynamically prepare one) and then serve those to browser . (but not after checing expiration period ?? )
( Those example uses "post" and "attachment" because i use wordpress and it is wordpress terminology, both currently work for me fine, except they generate the file over and over again. )
My doubts regarding the two scenarios (especially No.2) - How do I prevent the script to do the operation EVERY time the page is accessed ? (in other words , if the file exists , just serve it without looping the whole creating operation again)
My first instinct was call the file with some distinctive (but not load - unique like uniqueid() ) name and then check if it is already on the server , but that presents several problems (like it can already exists as naming , but of another post ..) and also - that should be very resource intensive for a server with 20,000 images .
The second thing I thought was to somehow associate a meta data for those files, but then again, How to implement it ? How to knwo which link is of what image ??
Also, in a case where I check for the file existence on the server , how can I know if the file SHOULD be changed (and therefor recreated ) ?
Since I am refering to wordpress, I thought about storing those images as base64 from binary directly to the DB with the transien_API - but it feels quite clumsy.
To sum up the question . How to generate a file, but also know if it exists and call it directly when needed ?? does my only option is store the file-name in DB and associate it somehow with the post ?? that seems so non efficient ..
EDIT I
I decided to include some example code , as it can help people to understand my dilemma .
function o99_wbss_prepare_with_callback($content,$width='250'){
$content = preg_replace_callback( '/(http[s]?:[^\s]*)/i', 'o99_wbss_prepare_cb', $content );
return $content;
}
function o99_wbss_prepare_cb($match){
$url = $match[1];
$url = esc_url_raw( $url );//someone said not need ??
$url_name = parse_url($url);
$url_name = $url_name['host'];// get rid of http://..
$param = '660';
$url = 'http://somescript/' . urlencode($url) . '?w=' . $param ;
$uploads = wp_upload_dir();
//$uniqid = uniqid();
$img = $uploads['basedir'] . '/tmp/' . $url_name .'.jpg' ; // was with $uniqid...
if(! # file_get_contents($url)){
$url = 'path ' .$url. ' doesn"t exist or unreachable';
return $url;
} else {
$file = file_get_contents( $url );
}
// here I will need to make some chck if the file already was generated , and
// if so - just serve it ..
if ( $file) {
file_put_contents( $img, $file );
// Do some other operations on the file and prepare a new one ...
// this produces a NEW file in the wp-uploads folder with the same name...
unlink($img);
}
return $url;
}
For Scenario 1:
Wordpress stored all post attachments as posts in the posts table. When a post is accessed run a function either in a created plugin or your themes functions.php. Use the pre_get_posts hook check if you have already created the zip file with function file_exists() using a unique name for each zip archive you create, post ID or permalink would be a good idea. Although you would need to make sure there was no user specific content. You can use filemtime() to check the time the file was created and if it is still relevant. If zip file does not exist create it, pre_get_posts will pass the query object which has the the post ID, just grab all the post attachments using get_posts and the parent ID being set to the ID passed in the query object. The GUID field contains the URL for each attachment then just generate a zip archive using ZipArchive() following this tutorial at.
For Scenario 2:
If your wordpress templates are set up to use the wordpress functions then replace the attachment functions to return their url and map that to the new url you have the cached content. For example the_post_thumbnail() would go to wp_get_attachment_thumb_url() copy the file to your cache and use the cache url as output. If you wanted to cache the DOM for the page as well use ob_start(). Now just run a check at the start of the template using file_exists and filetime(), if both are valid read in the cached DOM instead of loading the page.
I am attempting a CMS photo gallery and need to create thumbnails at the end of my upload.php file. I have a function called create_square_image that works fine when run on the 'showphotos.php' page. However I don't want it to be run every time someone views the page. I have tried adding the following to SWFUpload...
// Process the file
/*
At this point we are ready to process the valid file. This sample code shows how to save the file. Other tasks
could be done such as creating an entry in a database or generating a thumbnail.
Depending on your server OS and needs you may need to set the Security Permissions on the file after it has
been saved.
*/
$thumb_save = "uploads/thumbs/thumb_" . $_FILES[$upload_name]["tmp_name"];
create_square_image($_FILES[$upload_name]["tmp_name"],$thumb_save,100);
if (!#move_uploaded_file($_FILES[$upload_name]["tmp_name"], $save_path.$file_name)) {
HandleError("File could not be saved.");
exit(0);
}
exit(0);
The create_square_image function uses this format:
create_square_image ( string $filename , string $destination, size )
I have tried it a few times and it will save the image but not the thumbnail.
Set the permissions on /uploads/thumbs/ to 777. You could also try specifying the absolute path to that location. To see your absolute path use this code: echo getcwd();
How do I programmatically add an image to a file field? I have an url/filepath of an image that I wish to upload. I have tried the following:
$newNode->field_profile_image[0]['value'] = 'http://www.mysite.com/default.gif';
But it does not seem to work.
I have also tried:
$newNode->field_profile_image[0]['value'] = 'sites/default/files/default.gif';
The file does not need to be external to the webiste. I am happy to have it anywhere on the site in question.
You're probably going to have to use hook_nodeapi to set this correctly. You're going to want to modify it under the "Insert" operation. Make sure that you resave the node after you've added the required fields.
Drupal wants to map the image to an entry in the file table, so simply setting the URL will not work. First off, if it's a remote file, you can use the function listed in the Brightcove module on line 176, brightcove_remote_image, to grab the image and move it into your local directory.
Once the remote image is moved into place, you need to save it into the files table and then properly configure the node's property. I've done it in this method:
////// in NodeAPI /////
case "insert":
$node->field_image[0] = _mymod_create_filearray($image_url);
node_save($node);
This writes the files record, and then returns a properly formatted image array.
///// mymod_create_filearray /////
function _mymod_create_filearray($remote_url){
if ($file_temp = brightcove_remote_image($remote_url)) {
$file = new stdClass();
$file->filename = basename($file_temp);
$file->filepath = $file_temp;
$file->filemime = file_get_mimetype($file_temp);
$file->filesize = filesize($file_temp);
$file->uid = $uid;
$file->status = FILE_STATUS_PERMANENT;
$file->timestamp = time();
drupal_write_record('files', $file);
$file = array(
'fid' => $file->fid,
'title' => basename($file->filename),
'filename' => $file->filename,
'filepath' => $file->filepath,
'filesize' => $file->filesize,
'mimetype' => $mime,
'description' => basename($file->filename),
'list' => 1,
);
return $file;
}
else {
return array();
}
}
And that should do it. Let me know if you have any questions.
Check out my Answer to a similar question from a while ago, where I describe how we did pretty much exactly what you need (if I understood the problem correctly).
The main point is to use the field_file_save_file() function from the filefield module for attaching a file (during hook_nodeapi, on operation presave), which will do most of the work for you (more or less what jacobangel's '_mymod_create_filearray()' tries to do, but more tuned to filefields needs, including validation).
This assumes that the file already exists on the servers filesystem somewhere (usually in /tmp), and will correctly 'import' it into Drupal, with corresponding entries in the files table, etc. If you want to import files from remote URLs, you'll need to add the additional step of fetching them as a separate task/functionality first.
As mentioned in the answer linked above, I ended up using the code from the Remote File module as an example for a custom implementation, as we needed some project specific additions - maybe you can use it more directly for your purposes.
using nodeapi you should be able to set the value like you are trying to in the code example, but only or local images. You will most likely need to have the images in the "files" folder in your drupal install, but if that is set up everything else should work without a hitch. When using the nodeapi all the things that would normally happen when you save a node using a form would happen, such as updating the files table etc.
If you wanted to pull the image from the remote site using a module like feeds make it possible to pull the remote images, and create nodes. Depending on your use case you could either use it, or take a look at how it pulls the images and maps them to local files.
What you try will not work. Drupal offers no way to handle remote files, without the use for a module. AFAIK there is no module that offers an API to upload remote files trough.
Here is a quick example taken from one of my projects.
$node = new stdClass;
$node->title = 'Example Callout';
$node->type = 'wn_hp_callout';
// Search examples directory to attach some images.
$callouts_dir = drupal_get_path('module', 'wn_hp_callout').'/imgs/examples/';
$callout_imgs = glob($callouts_dir.'*.{jpg,jpeg,png,gif}',GLOB_BRACE);
// Now add the images and provide imagefield extended additional text.
foreach($callout_imgs as $img) {
$img_info = pathinfo($img);
$field = field_file_save_file($img, array(), file_directory_path() .'/example_callouts/');
if( !isset($field['data']) ) {
$field['data'] = array();
}
$field['data']['title'] = ucwords(str_replace('_',' ',$img_info['filename']));
$field['data']['alt'] = 'This is alt text.';
$node->field_wn_hp_callout_image[] = $field;
}
$node = node_submit($node);
node_save($node);