This is a trivial addition which would help reduce the bloated code to convert /myfile.jpg to
$file->uri = public://myfile.jpg
$file->size = 12345
$file->filemime = 'image/jpeg'

So that it can be run through file_save. This will help massively for any file import operation, and should also replace similar code in a ton of functions like file_save_upload, file_copy, file_scan_directory, etc...

For now, just adding this function is a win for profiles and contrib if nothing else.

Files: 
CommentFileSizeAuthor
#37 685818-create-reuse-file-api.patch1.5 KBDave Reid
#26 685818-file-uri-to-object-rev4.patch2.85 KBJeremyFrench
FAILED: [[SimpleTest]]: [MySQL] 34,479 pass(es), 186 fail(s), and 184 exception(s). View
#24 685818-file-uri-to-object-rev3.patch1.15 KBJeremyFrench
PASSED: [[SimpleTest]]: [MySQL] 34,635 pass(es). View
#20 sites - all - modules - plupload .txt18.27 KBGuilhermePuentes
#19 685818-file-uri-to-object-rev2.patch1.13 KBbrianV
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 685818-file-uri-to-object-rev2.patch. Unable to apply patch. See the log in the details link for more information. View
#17 685818-file-uri-to-object.patch1.13 KBbrianV
PASSED: [[SimpleTest]]: [MySQL] 32,867 pass(es). View
#9 file_uri_to_object.685818.9.patch1.52 KBaaron
PASSED: [[SimpleTest]]: [MySQL] 29,394 pass(es). View
#2 685818_file_uri_to_object-3.patch991 bytesJacobSingh
Passed on all environments. View
#2 2-3.diff.txt313 bytesJacobSingh
#1 685818_file_uri_to_object-2.patch955 bytesJacobSingh
Passed on all environments. View

Comments

JacobSingh’s picture

FileSize
955 bytes
Passed on all environments. View
JacobSingh’s picture

FileSize
313 bytes
991 bytes
Passed on all environments. View

Fixed the timestamp (didn't realize we don't use built in timestamp type in MySQL).

pwolanin’s picture

Looks good but I think we really need an additional API function that will take a URI and return the existing file object, or save as a new one otherwise.

aaron’s picture

yes, otherwise, sending it an existing youtube url (for instance) will fail. as will uploading a file that already exists (is there an md5 check somewhere in the system?)

aaron’s picture

ah, scratch that re the md5; it's the filename doing that, i think...

aaron’s picture

Status: Needs review » Needs work

pretty sure that this will choke on identical filenames as well.

JacobSingh’s picture

Status: Needs work » Needs review

I see a couple ways out here:

1). I'm not sure the uri should be unique in file. If it is, why do we even have an fid? I guess because during in import op we might move all the files. Anyway, this is a pet peeve from media, but a different topic.

2). If it stays unique, what is good error handling?

IMO, file_save should throw an exception it shouldn't let it go all the way to the PDO level and get some random DB error back. If we can bubble up from an key violation and catch it and then make sense of it fine, but that's a better way. I know Exceptions are in Exception D8, but I see no reason to even use PHP's built in Exception class, define a couple CONSTANTS for FILE_ERROR_DUPLICATE_URI, etc and let it rip.

this function simply preps a uri to be inserted. So I don't think the duplicate uri thing is its problem, that should be thrown at the time of insert, but maybe I'm missing the point.

-J

ff1’s picture

Version: 7.x-dev » 8.x-dev

No more new api's in D7, so bumping to D8.

aaron’s picture

FileSize
1.52 KB
PASSED: [[SimpleTest]]: [MySQL] 29,394 pass(es). View

this addresses some of the concerns in #3 and 4:

this will load a file object if the uri exists in the db. otherwise, it creates a new object, and sets a ->is_new flag on the new object. doesn't actually save it, as that rightfully already exists in file_save().

aaron’s picture

for reference, the media module is also using this function (and struggling with the issues here); see #1023254: Load a media object from a given URI.

Niklas Fiekas’s picture

Subscribe.

yareckon’s picture

Major missing functionality. For those needing this in D7, the media module includes this function.

geerlingguy’s picture

Subscribe.

yareckon’s picture

the file_styles module has now also implemented it's own version of this : file_styles_uri_to_object

Dave Reid’s picture

Status: Needs review » Needs work
+++ includes/file.inc	13 Jan 2011 16:24:47 -0000
@@ -2057,6 +2057,41 @@ function file_get_mimetype($uri, $mappin
+  $query = db_select('file_managed', 'f')
+    ->fields('f', array('fid'))
+    ->condition('uri', $uri)
+    ->execute()
+    ->fetchCol();
+  if (!empty($query)) {
+    $file = file_load(array_shift($query));
+  }

Could be condensed just using $files = entity_load('file', FALSE, array('uri' => $uri)); $file = !empty($files) ? reset($files) : FALSE;

Should also run $uri = file_stream_wrapper_uri_normalize($uri) prior to searching for an existing file.

+++ includes/file.inc	13 Jan 2011 16:24:47 -0000
@@ -2057,6 +2057,41 @@ function file_get_mimetype($uri, $mappin
+    $wrapper = file_stream_wrapper_get_instance_by_uri($uri);

$wrapper variable is not used. Remove this line.

+++ includes/file.inc	13 Jan 2011 16:24:47 -0000
@@ -2057,6 +2057,41 @@ function file_get_mimetype($uri, $mappin
+    $file->is_new = TRUE;

This is unnecessary as checking if empty($file->fid) is a new file.

19 days to next Drupal core point release.

lolbroek’s picture

Subscribe.

brianV’s picture

Status: Needs work » Needs review
FileSize
1.13 KB
PASSED: [[SimpleTest]]: [MySQL] 32,867 pass(es). View

Rerolled #9 with fixes suggested by Dave Reid in #15.

TR’s picture

The patch uses $file = new StdClass;

I don't know if we have a documented standard for this, but everywhere else in core we use $file = new stdClass();

brianV’s picture

FileSize
1.13 KB
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 685818-file-uri-to-object-rev2.patch. Unable to apply patch. See the log in the details link for more information. View

Good eye. Rerolled for consistency.

GuilhermePuentes’s picture

function file_uri_to_object($uri)
code below:
codigo abaixo:
===
pt-BR
PS: na linha 51 add } eu adicioneu essa tag aqui = }
rodei a atualização o erro saiu, isso esta correto?
--//--
pt-EN
PS: at line 51 add} tag I added this here =}
I ran the update the error came out, this is correct?
===

will know much about programming, so I'm taking the entirely the code that is running on my work project completion of course (CBT).
analysts so that you can take a look I just made a change and it worked, at least out of the error tela.espero not be wrong. ORIGINAL en, sorry my English.

ORIGINAL aqui-

não entendo muito de programação, então estou pegando o codigo enteiro que está rodando no meu projeto de trabalho de conclusão de curso (TCC) .
para que vocês analistas possam dar uma olhada eu fiz apenas uma modificação e funcionou, pelo menos o erro saiu da tela.espero não estar errado. ORIGINAL pt-BR , sorry my english :-( .

( - is equals / , ok )
code below:Atatach

Dave Reid’s picture

Issue tags: +Media Initiative

Marked #367121: Wrapper function to turn static file into a file object as a duplicate of this issue even though it was older, this had more work on it.

JeremyFrench’s picture

Issue tags: -Media Initiative

#19: 685818-file-uri-to-object-rev2.patch queued for re-testing.

There has been no movement on this for a while. Before doing looking at closer thought a re test was in order.

Status: Needs review » Needs work
Issue tags: +Media Initiative

The last submitted patch, 685818-file-uri-to-object-rev2.patch, failed testing.

JeremyFrench’s picture

FileSize
1.15 KB
PASSED: [[SimpleTest]]: [MySQL] 34,635 pass(es). View

This is just a reroll of the patch from #19

JeremyFrench’s picture

Status: Needs work » Needs review
JeremyFrench’s picture

FileSize
2.85 KB
FAILED: [[SimpleTest]]: [MySQL] 34,479 pass(es), 186 fail(s), and 184 exception(s). View

I have tweaked the function a little and changed the core file functions to use it. With the exception of file_scan_directory() which really didn't like using it.

Although I think if #1361226: Make the file entity a classed object happens this will be moot.

Status: Needs review » Needs work

The last submitted patch, 685818-file-uri-to-object-rev4.patch, failed testing.

Dave Reid’s picture

Issue tags: +sprint
slashrsm’s picture

Do we still need this? Now core provides entity_create(), which is used by file_save_upload() and file_save_data().

balagan’s picture

According to entity_load the third parameter you are using in the path here is deprecated.

Dave Reid’s picture

Issue summary: View changes
Issue tags: -sprint +D8Media

Yes this is still needed. Because file_save_data() in core still duplicates the code that all the contrib modules will end up duplicating in D8 as well.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

hgoto’s picture

Status: Needs work » Closed (won't fix)

After some investigation, I believe this issue can be closed because D8 already has satisfied this request.

In file_save_data():

  if ($uri = file_unmanaged_save_data($data, $destination, $replace)) {
    // Create a file entity.
    $file = File::create([
      'uri' => $uri,
      'uid' => $user->id(),
      'status' => FILE_STATUS_PERMANENT,
    ]);

In file_save_upload():

    // Begin building file entity.
    $values = array(
      'uid' => $user->id(),
      'status' => 0,
      'filename' => $file_info->getClientOriginalName(),
      'uri' => $file_info->getRealPath(),
      'filesize' => $file_info->getSize(),
    );
    $values['filemime'] = \Drupal::service('file.mime_type.guesser')->guess($values['filename']);
    $file = File::create($values);

In Drupal\file\Entity\File:

   /**
    * {@inheritdoc}
    */
   public static function preCreate(EntityStorageInterface $storage, array &$values) {
     // Automatically detect filename if not set.
     if (!isset($values['filename']) && isset($values['uri'])) {
       $values['filename'] = drupal_basename($values['uri']);
     }

     // Automatically detect filemime if not set.
     if (!isset($values['filemime']) && isset($values['uri'])) {
       $values['filemime'] = \Drupal::service('file.mime_type.guesser')->guess($values['uri']);
     }
   }

So at least we shouldn't continue on D8.

On the other hand, as with D7, I think we can add new APIs currently. Please reopen this if you want this kind of function in D7.

Dave Reid’s picture

Status: Closed (won't fix) » Needs work

The major part of this is ability to re-use an existing file (either a permanent file or a temporary file owned by the current user), which is not addressed in #34. I do not consider this resolved.

Dave Reid’s picture

Also, if an issue is still valid for D7, let's please not just close it, change the version and update it. That said, this is still valid for D8. It would be useful to have it as a method on the File entity object itself.

Dave Reid’s picture

This is what I've needed to re-use on several projects.

hgoto’s picture

@Dave Reid, thank you for your response. I got it.

jonhattan’s picture

+++ b/core/modules/file/src/Entity/File.php
@@ -277,4 +277,38 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
+        return $file->isPermanent() || $file->getOwnerId() == \Drupal::currentUser()

getOwnerId() may return null. It needs type check.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.