1

To any Drupal 7 gurus out there... I have hundreds of PDFs that need to be uploaded to users as their own private attachment. I've created the PDFs in the folder:-

../website-files/userfiles-{uid}/filename.pdf (There's one for each uid)

My field_data_field_attachments table has the "field_attachments_fid" column with the id relating to the file_managed table.

This is all pretty self explanatory, until... I find the file_managed table has two mysterious columns:-

__pk
__unique_uri

Both seem to be MD5 checksums, e.g:-

4A448458-860C-4E16-B901-F8841136C17D

So my question is; how do I correctly generate these two values for each attachment I import to the DB?

Thanks, Darren

4
  • 1
    Those should be indexes, not fields...one for primary key (pk) and a unique index for the uri field (unique_uri)
    – Clive
    Nov 20, 2012 at 17:16
  • Thanks Clive - So they should be generated automatically by SQL when I import the data?
    – Darren
    Nov 20, 2012 at 18:18
  • I would guess so, where exactly are you seeing these extra fields? Is it an SQL dump file?
    – Clive
    Nov 20, 2012 at 18:22
  • Yeah, It's a SQL dump where I see the two keys. The __unique_uri field is generated by SQL, but the __pk value must be generated in PHP. I've tried an MD5 of the URI but not sure if that's correct.
    – Darren
    Nov 20, 2012 at 19:15

2 Answers 2

1

You want to try and use the drupal api to move these files into drupal. Since you talk about private files, I assume you've enabled a private filesystem ... or else this discussion is pointless as all your files with be public :).

Once you've done that you could take your hundreds of files and put them in your server someplace and use file_move to place them into the drupal private filesystem using a small php script.

A module tutorial with a private file upload widget can be seen at this blog post and uses the drupal api to store a private file. Private files typically use hook_file_download which that blog post also shows to allow access to the file.

1
  • Yeah I got private files enabled :) Ah - So there's no way for me to easily generate the keys so I simply import the data at the SQL level? EDIT just seen Clive's comment above - these two values should hopefully be generated automatically when I import the rest of the table data...
    – Darren
    Nov 20, 2012 at 18:15
1

OK, I've given up trying to do it in raw SQL due to the intricate referential integrity of the Drupal datamodel (OK, I admit defeat!! :)

The following code bootstraps drupal, then moves files from an input directory to the private-files folder on the local drive and uses the Drupal file_save() API to create the Drupal file registers, then updates the user profile custom field (in my case called "field_attachments").

hope it helps anyone trying to do the same. (I created a standalone PHP file called "importuserfiles.php" in the root of the drupal folder using the code below)

<?php 
define('DRUPAL_ROOT', getcwd());
$_SERVER['REMOTE_ADDR'] = "localhost"; // Necessary if running from command line
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

$local_from_path = 'c:\\inputfiles'; // root folder of your input folders.
$drupal_private_base = 'c:\\website-files'; // root location of Drupal's private website files.

$di = new RecursiveDirectoryIterator($local_from_path); 
foreach (new RecursiveIteratorIterator($di) as $filename => $file) {

    $user_id = explode('-', $di);   // the userid is held in the folder name (userfiles-uid) 
    $uid = $user_id[1];             // so pull the second value from the array (after userfiles-)

    echo $filename . ' - ' . $file->getSize() . ' bytes. Attaching to user: ' . $uid . '<br/>';

    $local_to_path = $drupal_private_base . '\\userfiles-' . $uid . '\\' . basename($filename); // the destination folder on the local file system for this user.

    $drupal_to_path = "private://userfiles-" . $uid.'/'.basename($filename); // the private files folder URI for this user.

    echo "Moving file: " . $filename . " To: " . $local_to_path . '</br>';

    mkdir($drupal_private_base . '\\userfiles-' . $uid); // make the destination folder in case it doesn't exist.

    //move the file to the new location
    if (!rename($filename, $local_to_path)) {
    echo "failed to move $file.. </br>";
        break;
    }

    $user = user_load($uid); // load the user object


// create the file object for Drupal...
$filetosave = new stdClass();
$filetosave->filename = basename($filename);
$filetosave->filepath = $filename;
$filetosave->uri = $drupal_to_path;
$filetosave->filemime = file_get_mimetype($filename);
$filetosave->filesize = filesize($filename);
$filetosave->display = 1;
$filetosave->description = basename($filename); // just use the filename as the description
$filetosave->uid = $uid; 
$filetosave->status = FILE_STATUS_PERMANENT;
file_save($filetosave);  // save the file so Drupal registers it.

$user->field_attachments['und'][] = (array)$filetosave; // add the file to the file field called "field_attachments"
user_save($user);
?>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.