<p>Answering my own question for reference.</p>
<p>I was tunneling too hard on the PHP, a simple bash script takes care of the upload.</p>
<pre><code># assuming the image is already downloaded and no CP-login required
curl -F assets-upload=@/path/to/image mycraftsite/admin/actions/assets/uploadFile
</code></pre>
<h3>EDIT</h3>
<p>Better answer: <a href="https://craftcms.stackexchange.com/questions/8994/change-image-title-programatically">Thanks to this answer</a> I discovered the <code>insertFileByLocalPath()</code> function in AssetsService.</p>
<pre><code>  $entry = craft()-&gt;entries-&gt;getEntryById($id);
  if($entry &amp;&amp; isset($entry[&quot;imageFetchUrl&quot;])) {
    $url = $entry-&gt;getFieldValue(&quot;imageFetchUrl&quot;);
    $tmpfname = tempnam(&quot;/tmp&quot;, &quot;UL_IMAGE&quot;);
    $img = file_get_contents($url);
    file_put_contents($tmpfname, $img);
    craft()-&gt;assets-&gt;insertFileByLocalPath($tmpfname, 'fetchedImg.jpg', $myFolderId);
  }
</code></pre>

CC BY-SA 3.0
2015-07-23T13:04:47.143Z
2015-07-24T12:46:25.397Z
2020-06-17T08:56:27.903Z
fuling
<p>Context: we sell some magazines and other newspapers on our site, and updating all the cover images manually is a hassle.</p>

<p>I would like the ability to write a url in a field (www.myimageprovider.com/product1) and set a cron job to fetch any new images for the day, for that specific product, and update the entry with the new image.</p>

<p>I'm having a hard time figuring out how to "fake" a file upload from a craft controller/service, as if it was uploaded from the CP form. I have tried something like this:</p>

<pre><code>$file = array();
$url = $entry-&gt;getFieldValue('imagefetchurl'); // somegoogleimageurl.com/image.png
$tmpfname = tempnam("/tmp", "UL_IMAGE");
$img = file_get_contents($url);
file_put_contents($tmpfname, $img);
$file['size'] = filesize($tmpfname); // 245 kB
$file['name'] = basename($url); // image.png
$file['tmp_name'] = $tmpfname; // C:\\Windows\\Temp\\UL_XXXX.tmp

$_FILES['assets-upload'] = $file;
$assetOperationResponseModel = craft()-&gt;assets-&gt;uploadFile(1);
</code></pre>

<p>This throws an error</p>

<h1>PHP notice</h1>

<p><em>getimagesize(): Read error!</em> - in ...craft\app\services\ImagesService.php(114)</p>

<p>I can see that the image get downloaded, the size and name is correct.</p>

<p>Any pointers and ideas are greatly appreciated</p>

<h3>EDIT</h3>

<p>After some digging, looks like i have to write my own upload handler for this task. <a href="http://www.1-script.com/forums/php/simulate-file-upload-so-that-move-uploaded-file-succeeds-124012-.htm" rel="nofollow">http://www.1-script.com/forums/php/simulate-file-upload-so-that-move-uploaded-file-succeeds-124012-.htm</a></p>

<blockquote>
  <p>Basically not possible unless you change the PHP source</p>
</blockquote>

<p>I suppose i could override the function, but my instinct tells me that's a bad idea. I will have to go with an alternative approach</p>

CC BY-SA 3.0
2015-07-23T11:19:02.313Z
Very strange. First thing I'd do is go to that line (114) and dump the $filePath variable, exit, and check to see if the file exists in that location, if you haven't done so already.
Ben Fleming
CC BY-SA 3.0
2015-07-23T11:40:24.130Z
@Benjammin' thank you, that got me going! Turns out craft uses `move_uploaded_file()` to move the file to its own internal temp storage. If I change `move_uploaded_file()` to `copy()` it works. Maybe if i set some $_POST variables it will work?
fuling
CC BY-SA 3.0
2015-07-23T12:14:52.100Z
No worries, shame it wasn't easier to fix. I've built a plugin recently that upload images into the asset manager and my solution was to essentially copy the BaseAssetSourceType::uploadFile() method to my controller and tweak it to my needs. Hope you can get it working!
Ben Fleming
<plugin-development><assets>
How to upload assets without user interaction?
# How to upload assets without user interaction?

(Asked by: username_0 on 2015-07-23)

Context: we sell some magazines and other newspapers on our site, and updating all the cover images manually is a hassle.
I would like the ability to write a url in a field (www.myimageprovider.com/product1) and set a cron job to fetch any new images for the day, for that specific product, and update the entry with the new image.
I'm having a hard time figuring out how to "fake" a file upload from a craft controller/service, as if it was uploaded from the CP form. I have tried something like this:
$file = array();
$url = $entry->getFieldValue('imagefetchurl'); // somegoogleimageurl.com/image.png
$tmpfname = tempnam("/tmp", "UL_IMAGE");
$img = file_get_contents($url);
file_put_contents($tmpfname, $img);
$file['size'] = filesize($tmpfname); // 245 kB
$file['name'] = basename($url); // image.png
$file['tmp_name'] = $tmpfname; // C:\\Windows\\Temp\\UL_XXXX.tmp

$_FILES['assets-upload'] = $file;
$assetOperationResponseModel = craft()->assets->uploadFile(1);

This throws an error
PHP notice
getimagesize(): Read error! - in ...craft\app\services\ImagesService.php(114)
I can see that the image get downloaded, the size and name is correct.
Any pointers and ideas are greatly appreciated
EDIT
After some digging, looks like i have to write my own upload handler for this task. http://www.1-script.com/forums/php/simulate-file-upload-so-that-move-uploaded-file-succeeds-124012-.htm

Basically not possible unless you change the PHP source

I suppose i could override the function, but my instinct tells me that's a bad idea. I will have to go with an alternative approach

**Tags:** plugin-development, assets
> **Comments:**
> **username_1**: Very strange. First thing I'd do is go to that line (114) and dump the $filePath variable, exit, and check to see if the file exists in that location, if you haven't done so already.  
> **username_0**: @Benjammin' thank you, that got me going! Turns out craft uses `move_uploaded_file()` to move the file to its own internal temp storage. If I change `move_uploaded_file()` to `copy()` it works. Maybe if i set some $_POST variables it will work?  
> **username_1**: No worries, shame it wasn't easier to fix. I've built a plugin recently that upload images into the asset manager and my solution was to essentially copy the BaseAssetSourceType::uploadFile() method to my controller and tweak it to my needs. Hope you can get it working!  

---

## 1 answers

### Answer by username_0 on 2015-07-23. Score: 3 | Accepted answer

Answering my own question for reference.
I was tunneling too hard on the PHP, a simple bash script takes care of the upload.
# assuming the image is already downloaded and no CP-login required
curl -F assets-upload=@/path/to/image mycraftsite/admin/actions/assets/uploadFile

EDIT
Better answer: Thanks to this answer I discovered the insertFileByLocalPath() function in AssetsService.
  $entry = craft()->entries->getEntryById($id);
  if($entry && isset($entry["imageFetchUrl"])) {
    $url = $entry->getFieldValue("imageFetchUrl");
    $tmpfname = tempnam("/tmp", "UL_IMAGE");
    $img = file_get_contents($url);
    file_put_contents($tmpfname, $img);
    craft()->assets->insertFileByLocalPath($tmpfname, 'fetchedImg.jpg', $myFolderId);
  }


---

