1

I'm writing a custom helper that extends HtmlHelper and overriding the \HtmlHelper::image() method to calculate the image dimensions and add them as HTML attributes. What I have so far works fine for regular pictures:

public function image($path, $options = array()) {
    if (!array_key_exists('width', $options) && !array_key_exists('height', $options)) {
        $stamp = Configure::read('Asset.timestamp');
        Configure::write('Asset.timestamp', false);

        $path = $this->assetUrl($path, $options + array('pathPrefix' => Configure::read('App.imageBaseUrl')));
        list($width, $height) = @getimagesize(rtrim(WWW_ROOT, '\\/') . $path);
        if (!is_null($width)) {
            $options['width'] = $width;
        }
        if (!is_null($height)) {
            $options['height'] = $height;
        }

        Configure::write('Asset.timestamp', $stamp);
    }
    return parent::image($path, $options);
}

… but has these flaws:

  • Pictures from plug-ins can't be located on disk (and they should), e.g.:

    echo $this->Html->image('/debug_kit/img/cake.icon.png', array('alt' => 'CakePHP'));
    

    … produces this file system path:

    …\src\webroot/debug_kit/img/cake.icon.png
    

    … thus getimagesize() fails because actual location is:

    …\src\Plugin\DebugKit\webroot\img\cake.icon.png"
    
  • External pictures (which should be ignored) go through the full process:

    echo $this->Html->image('http://placekitten.com/200/300');
    …\src\webroothttp://placekitten.com/200/300
    

I've been looking for a builtin method to convert a CakePHP picture URL (in any format accepted by \HtmlHelper::image() into a file system path (o something like null when doesn't apply) but I couldn't find any. Native features that need a disk path, such as \Helper::assetTimestamp() are wrapped in tons of non-reusable code.

Is there an elegant solution?

Álvaro González
  • 142,137
  • 41
  • 261
  • 360

2 Answers2

1

I'd say that there are pretty much only 3 options:

  • Submit a patch to add asset filesystem path retrieval functionality to the core.
  • Copy a lot of code from the helper (assetUrl(), webroot(), and assetTimestamp()).
  • Use web requests for local URLs (ideally combined with caching).
ndm
  • 59,784
  • 9
  • 71
  • 110
0

Try using DS rather than using \ or /, they sometime can cause problems with the OS. DS is directory separator provided by cakephp Short for PHP’s DIRECTORY_SEPARATOR, which is / on Linux and \ on Windows. Check the doc

Daljeet Singh
  • 704
  • 3
  • 7
  • 17
  • I don't think that's true. PHP can handle both without any issue. Path separators won't change the fact that path is missing several components (e.g. `Plugin\DebugKit`). (BTW, I'm using CakePHP/2, not 3.) – Álvaro González Jun 07 '17 at 09:57
  • Have you tried using it with Plugin name.path, refer this doc:- https://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::image – Daljeet Singh Jun 07 '17 at 10:00
  • Not sure what you mean exactly. I don't have any problem with the `image()` method itself, plug-in pictures work just fine. I want to do some additional processing for which I need the full file system path of the asset. I could write 50 lines of code duplicating core PHP functionality but I want to avoid that. – Álvaro González Jun 07 '17 at 10:06