Send an asset from a plugin controller I have a controller which fetches an asset from an entry (this is the service method that provides the asset):

public function findPoster($entryId) {
    $criteria = craft()-&gt;elements-&gt;getCriteria(ElementType::Entry);
    $criteria-&gt;id = $entryId;

    $entry = $criteria-&gt;first();

    if ($entry) {
        if ($entry-&gt;downloadItem) {
            return $entry-&gt;downloadItem-&gt;first();
        }
    }

    return null;
}


That works great, however now I need to send the asset to the browser. Having a little poke around in the method listing I see there is a CBaseController::renderFile() which sounds to be what I need, however I can't work out the correct way to build a path to the file. Accessing $url from the asset I've fetched returns a public relative path but obviously I need the path on the filesystem.



So far I've got this working:

$name = strtolower($asset-&gt;title) . '.' . $asset-&gt;extension;

header('Content-Type: ' . $asset-&gt;getMimeType());
header('Content-Disposition: attachment; filename=' . $name);

$path = realpath(craft()-&gt;basePath . '/../../public/' . $asset-&gt;url);

die(file_get_contents($path));


However this is far from ideal because:


I have to hardcode the public directory which isn't the case at any other point in Craft, so it feels really dirty.
Manually setting the headers seems like something a controller method would be able to take care of properly.
There might be a way to do this with CBaseController::renderFile(), but I'd just use craft()-&gt;request-&gt;sendFile().

The 3rd parameter is an optional $options array and you can pass a 'forceDownload' =&gt; true as one of the key => value pairs to force it to download to the browser.

Instead of hardcoding the the path to your public assets folder, you can do something like:

$path = IOHelper::getFolderName(craft()-&gt;request-&gt;getScriptFile());


That should get you the path to the folder your public index.php file is executing in and you can tack on your public asset path from there.