hsz
hsz

Reputation: 152294

Get path of image in specified bundle

In my bundle I have a Resources/public/images/image.jpg file.

This image is accessible via http://localhost/bundles/mybundle/images/image.jpg

How can I get this /bundles/mybundle prefix from a controller?
I want to be able to generate the path to the public file without hardcoding /bundles/mybundle prefix.

Upvotes: 3

Views: 3312

Answers (3)

Touki
Touki

Reputation: 7525

I'd create a service which would do this

Create the service

The main responsibility of this class, is to get the default web path of any bundle for any resource.
As defined in assets:install command, relative paths for each bundle are expected to be /bundles/foobar/ for a given FooBarBundle

Acme\FooBundle\WebPathResolver

use Symfony\Component\HttpKernel\Bundle\BundleInterface;

class WebPathResolver
{
    /**
     * Gets the prefix of the asset with the given bundle
     *
     * @param BundleInterface $bundle Bundle to fetch in
     *
     * @throws \InvalidArgumentException
     * @return string Prefix
     */
    public function getPrefix(BundleInterface $bundle)
    {
        if (!is_dir($bundle->getPath().'/Resources/public')) {
            throw new \InvalidArgumentException(sprintf(
                'Bundle %s does not have Resources/public folder',
                $bundle->getName()
            ));
        }

        return sprintf(
            '/bundles/%s',
            preg_replace('/bundle$/', '', strtolower($bundle->getName()))
        );
    }

    /**
     * Get path
     *
     * @param BundleInterface $bundle   Bundle to fetch in
     * @param string          $type     Which folder to fetch in (image, css..)
     * @param string          $resource Resource (image1.png)
     *
     * @return string Resolved path
     */
    public function getPath(BundleInterface $bundle, $type, $resource)
    {
        $prefix = $this->getPrefix($bundle);

        return sprintf('%s/%s/%s', $prefix, $type, $resource);
    }
}

Declare it in your service.yml

Nothing special, but an usual service

@AcmeFooBundle/Resources/config/services.yml

services:
    acme_foo.webpath_resolver:
        class: Acme\FooBundle\WebPathResolver

Usage

You can then use it in your controller like this

Acme\FooBundle\Controller\BarController::bazAction

$bundle = $this->get('http_kernel')->getBundle('AcmeFooBundle');
$path   = $this->get('acme.webpath_resolver')->getPath($bundle, 'image', 'foo.png');

echo $path; // Outputs /bundles/acmefoo/image/foo.png

Upvotes: 4

COil
COil

Reputation: 7606

You could use something like this, but is assumes the path is the lowercased bundle name.

    $controller = $request->attributes->get('_controller');
    $regexp = '/(.*)\\\Bundle\\\(.*)\\\Controller\\\(.*)Controller::(.*)Action/';
    preg_match($regexp, $controller, $matches);
    $imagePath = '/bundles/'. strtolower($matches[2]). '/images/image.jpg';

Upvotes: 0

Piotr Pasich
Piotr Pasich

Reputation: 2639

You use assets in templates, like this:

{% image '@AcmeFooBundle/Resources/public/images/example.jpg' %}
    <img src="{{ asset_url }}" alt="Example" />
{% endimage %}

or directly in src:

<img src="{{ asset('@AcmeFooBundle/Resources/public/images/example.jpg') }}" alt="Example" />

In css files you need to use relative paths.

From controller you can get full path in the same way by:

$this->container->get('templating.helper.assets')->getUrl('@AcmeFooBundle/Resources/public/images/example.jpg');

Upvotes: 1

Related Questions