Completed
Push — master ( 312aa1...eb49de )
by Paul
9s
created

IcoFileService   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 5
dl 0
loc 127
ccs 27
cts 27
cp 1
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 3
A renderImage() 0 7 2
A from() 0 7 2
A fromFile() 0 8 2
A fromString() 0 4 1
A extractIcon() 0 10 2
1
<?php
2
3
namespace Elphin\IcoFileLoader;
4
5
/**
6
 * Provides a service for loading .ico files from files or from binary strings
7
 * If fopen wrappers are enabled, you can load from a URL also
8
 */
9
class IcoFileService
10
{
11
    /**
12
     * @var ParserInterface
13
     */
14
    protected $parser;
15
16
    /**
17
     * @var RendererInterface
18
     */
19
    protected $renderer;
20
21
    /**
22
     * IcoFileService constructor
23
     *
24
     * You can inject alternative implementations of the renderer or parser, but for most
25
     * typical uses, you can accept the defaults
26
     *
27
     * @param RendererInterface|null $renderer
28
     * @param ParserInterface|null $parser
29
     */
30 6
    public function __construct(RendererInterface $renderer = null, ParserInterface $parser = null)
31
    {
32 6
        $this->parser = $parser ?: new IcoParser();
33 6
        $this->renderer = $renderer ?: new GdRenderer();
34 6
    }
35
36
    /**
37
     * This is a useful one-stop function for obtaining the best possible icon of a particular size from an .ico file
38
     *
39
     * As icons are often hand-crafted to look good at particular sizes, this will try to use the best quality image
40
     * in the icon at the required size. If it can't be found, then it will resize the largest icon it can find.
41
     *
42
     * This will either return a valid image, or will throw an \InvalidArgumentException in the event of the file
43
     * being unreadable.
44
     *
45
     * @param string $dataOrFile either a filename to a .ico file, or binary data from an .ico file in a string
46
     * @param integer $w desired width. The class tries to locate the best quality image at this size, but
47
     *                            if not found, the largest available icon will be used and resized to fit
48
     * @param integer $h desired height - as icons are usually square, this should be same as $w
49
     * @param array $opts array of renderer options. The built in renderer supports an optional 'background'
50
     *                            elemen in this array. Normally, the result will use alpha transparency, but you can
51
     *                            pass a hex colour to choose the colour of the transparent area instead, e.g.
52
     *                            ['background=>'#ffffff'] for a white background
53
     * @return mixed              the built in renderer will return a gd image resource, which you could save with
54
     *                            the gd function imagepng(), for example. If you swap in an alternative renderer,
55
     *                            the result is whatever that renderer returns.
56
     * @throws \InvalidArgumentException if file is not found or is invalid
57
     */
58 1
    public function extractIcon($dataOrFile, $w, $h, array $opts = null)
59
    {
60 1
        $icon = $this->from($dataOrFile);
61 1
        $image = $icon->findBestForSize($w, $h);
62 1
        if (!$image) {
63
            //nothing at our required size, so we'll find the highest quality icon
64 1
            $image = $icon->findBest();
65 1
        }
66 1
        return $this->renderImage($image, $w, $h, $opts);
0 ignored issues
show
Bug introduced by
It seems like $image can be null; however, renderImage() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
67
    }
68
69
    /**
70
     * Renders an IconImage at a desired width and height
71
     *
72
     * @param IconImage $image image obtained from an Icon object
73
     * @param integer $w desired width - if null, width of IconImage is used
74
     * @param integer $h desired height - if null, height of IconImage is used
75
     * @param array $opts array of renderer options. The built in renderer supports an optional 'background'
76
     *                            elemen in this array. Normally, the result will use alpha transparency, but you can
77
     *                            pass a hex colour to choose the colour of the transparent area instead, e.g.
78
     *                            ['background=>'#ffffff'] for a white background
79
     * @return mixed              the built in renderer will return a gd image resource, which you could save with
80
     *                            the gd function imagepng(), for example. If you swap in an alternative renderer,
81
     *                            the result is whatever that renderer returns.
82
     * @throws \InvalidArgumentException if IconImage or options are invalid
83
     */
84 1
    public function renderImage(IconImage $image, $w = null, $h = null, array $opts = null)
85
    {
86 1
        $opts = is_array($opts) ? $opts : [];
87 1
        $opts['w'] = $w;
88 1
        $opts['h'] = $h;
89 1
        return $this->renderer->render($image, $opts);
90
    }
91
92
    /**
93
     * Parses a .ico file from a pathname or binary data string and return an Icon object
94
     *
95
     * This is a useful lower level member which can be used to inspect an icon before
96
     * rendering a particular image within it with renderImage
97
     *
98
     * @param string $dataOrFile either filename or binary data
99
     * @return Icon
100
     * @throws \InvalidArgumentException if file is not found or invalid
101
     */
102 4
    public function from($dataOrFile)
103
    {
104 4
        if ($this->parser->isSupportedBinaryString($dataOrFile)) {
105 1
            return $this->parser->parse($dataOrFile);
106
        }
107 3
        return $this->fromFile($dataOrFile);
108
    }
109
110
    /**
111
     * Loads icon from file
112
     * @param string $file filename or URL (if fopen wrappers installed)
113
     * @return Icon
114
     * @throws \InvalidArgumentException if file is not found or invalid
115
     */
116 4
    public function fromFile($file)
117
    {
118 4
        if (file_exists($file)) {
119 2
            $data = file_get_contents($file);
120 2
            return $this->parser->parse($data);
121
        }
122 2
        throw new \InvalidArgumentException("file was not found");
123
    }
124
125
    /**
126
     * Loads icon from string
127
     * @param string $data binary data string containing a .ico file
128
     * @return Icon
129
     * @throws \InvalidArgumentException if file is not found or invalid
130
     */
131 2
    public function fromString($data)
132
    {
133 2
        return $this->parser->parse($data);
134
    }
135
}
136