ImageRenderer::render()   B
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 26
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 26
rs 8.8571
c 0
b 0
f 0
cc 2
eloc 16
nc 2
nop 2
1
<?php
2
/**
3
 * Lichtenwallner  (https://lichtenwallner.at)
4
 *
5
 * @see https://github.com/jolicht/markdown-cms for the canonical source repository
6
 * @license https://github.com/jolicht/markdown-cms/blob/master/LICENSE MIT
7
 * @copyright Copyright (c) Johannes Lichtenwallner
8
 */
9
declare(strict_types = 1);
10
namespace Jolicht\MarkdownCms\Markdown\Renderer;
11
12
use League\CommonMark\ElementRendererInterface;
13
use League\CommonMark\HtmlElement;
14
use League\CommonMark\Inline\Renderer\InlineRendererInterface;
15
use League\CommonMark\Inline\Element\AbstractInline;
16
17
class ImageRenderer implements InlineRendererInterface
18
{
19
    /**
20
     * Image caption renderer
21
     *
22
     * @var ImageCaptionRenderer
23
     */
24
    private $captionRenderer;
25
26
    /**
27
     * Url Translation
28
     *
29
     * @var array
30
     */
31
    private $urlTranslation;
32
33
    /**
34
     * Images base url
35
     *
36
     * @var string
37
     */
38
    private $imagesBaseUrl;
39
40
    /**
41
     * Images config
42
     *
43
     * @var array
44
     */
45
    private $imagesConfig;
46
47
    /**
48
     * Constructor
49
     *
50
     * @param ImageCaptionRenderer $imageCaptionRenderer
0 ignored issues
show
Documentation introduced by
There is no parameter named $imageCaptionRenderer. Did you maybe mean $captionRenderer?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
51
     * @param array $urlTranslation
52
     * @param string $imagesBaseUrl
53
     * @param array $imagesConfig
54
     */
55
    public function __construct(ImageCaptionRenderer $captionRenderer, array $urlTranslation, string $imagesBaseUrl,
56
        array $imagesConfig)
57
    {
58
        $this->captionRenderer = $captionRenderer;
59
        $this->urlTranslation = $urlTranslation;
60
        $this->imagesBaseUrl = rtrim($imagesBaseUrl, '/');
61
        $this->imagesConfig = $imagesConfig;
62
    }
63
64
    /**
65
     * Get caption renderer
66
     *
67
     * @return ImageCaptionRenderer
68
     */
69
    public function getCaptionRenderer() : ImageCaptionRenderer
70
    {
71
        return $this->captionRenderer;
72
    }
73
74
    /**
75
     * Get url translation
76
     *
77
     * @return array
78
     */
79
    public function getUrlTranslation() : array
80
    {
81
        return $this->urlTranslation;
82
    }
83
84
    /**
85
     * Get images base url
86
     *
87
     * @return string
88
     */
89
    public function getImagesBaseUrl() : string
90
    {
91
        return $this->imagesBaseUrl;
92
    }
93
94
    /**
95
     * Get images config
96
     *
97
     * @return array
98
     */
99
    public function getImagesConfig() : array
100
    {
101
        return $this->imagesConfig;
102
    }
103
104
    /**
105
     * Render image
106
     *
107
     * {@inheritDoc}
108
     * @see \League\CommonMark\Inline\Renderer\InlineRendererInterface::render()
109
     */
110
    public function render(AbstractInline $inline, ElementRendererInterface $htmlRenderer)
111
    {
112
        $id = substr($inline->getUrl(), strlen($this->getImagesBaseUrl()) + 1);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class League\CommonMark\Inline\Element\AbstractInline as the method getUrl() does only exist in the following sub-classes of League\CommonMark\Inline\Element\AbstractInline: League\CommonMark\Inline...ent\AbstractWebResource, League\CommonMark\Inline\Element\Image, League\CommonMark\Inline\Element\Link. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
113
114
        $imagesConfig = $this->getImagesConfig();
115
        $params = $imagesConfig[$id];
116
117
118
        $imgAttributes = [
119
            'src' => strtr($inline->getUrl(), $this->getUrlTranslation()),
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class League\CommonMark\Inline\Element\AbstractInline as the method getUrl() does only exist in the following sub-classes of League\CommonMark\Inline\Element\AbstractInline: League\CommonMark\Inline...ent\AbstractWebResource, League\CommonMark\Inline\Element\Image, League\CommonMark\Inline\Element\Link. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
120
            'layout' => 'responsive',
121
            'alt' => $inline->firstChild()->getContent(),
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class League\CommonMark\Node\Node as the method getContent() does only exist in the following sub-classes of League\CommonMark\Node\Node: League\CommonMark\Inline...AbstractStringContainer, League\CommonMark\Inline\Element\Code, League\CommonMark\Inline\Element\HtmlInline, League\CommonMark\Inline\Element\Text. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
122
            'width' => $params['width'],
123
            'height' => $params['height']
124
        ];
125
126
        $figureContents = [];
127
        $figureContents[] = new HtmlElement('amp-img', $imgAttributes);
128
129
        if (isset($params['caption'])) {
130
            $figureContents[] = $this->getCaptionRenderer()->__invoke($params);
131
        }
132
133
        $figure = new HtmlElement('figure', [], $figureContents);
134
        return $figure;
135
    }
136
}