Passed
Push — assets ( e484a3...a30644 )
by Arnaud
25:41 queued 23:17
created

Asset::offsetSet()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
c 0
b 0
f 0
nc 2
nop 2
dl 0
loc 4
rs 10
1
<?php
2
/**
3
 * This file is part of the Cecil/Cecil package.
4
 *
5
 * Copyright (c) Arnaud Ligny <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Cecil\Assets;
12
13
use Cecil\Builder;
14
use Cecil\Config;
15
use Cecil\Exception\Exception;
16
use Cecil\Util;
17
18
class Asset implements \ArrayAccess
19
{
20
    /** @var Builder */
21
    protected $builder;
22
    /** @var Config */
23
    protected $config;
24
    /** @var array */
25
    protected $properties = [];
26
27
    /**
28
     * Loads a file.
29
     *
30
     * @param Builder
31
     * @param string     $path
32
     * @param array|null $options
33
     */
34
    public function __construct(Builder $builder, string $path, array $options = null)
35
    {
36
        $this->builder = $builder;
37
        $this->config = $builder->getConfig();
38
39
        if (false === $filePath = $this->findFile($path)) {
40
            throw new Exception(sprintf('Asset file "%s" doesn\'t exist.', $path));
41
        }
42
43
        // handles options
44
        $canonical = null;
45
        $attributs = null;
46
        extract(is_array($options) ? $options : [], EXTR_IF_EXISTS);
47
        // url
48
        $baseurl = (string) $this->config->get('baseurl');
49
        $base = '';
50
        if ((bool) $this->config->get('canonicalurl') || $canonical === true) {
51
            $base = rtrim($baseurl, '/');
52
        }
53
        if ($canonical === false) {
54
            $base = '';
55
        }
56
57
        // prepares properties
58
        $this->properties['file'] = $filePath;
59
        $this->properties['path'] = '/'.ltrim($path, '/');
60
        $this->properties['url'] = $base.'/'.ltrim($path, '/');
61
        $this->properties['ext'] = pathinfo($filePath, PATHINFO_EXTENSION);
62
        $this->properties['type'] = explode('/', mime_content_type($filePath))[0];
63
        if ($this->properties['type'] == 'text') {
64
            $this->properties['content'] = file_get_contents($filePath);
65
        }
66
        $this->properties['attributs'] = $attributs;
67
    }
68
69
    /**
70
     * @return string
71
     */
72
    public function __toString(): string
73
    {
74
        return $this->properties['path'];
75
    }
76
77
    /**
78
     * Implements \ArrayAccess.
79
     */
80
    public function offsetSet($offset, $value)
81
    {
82
        if (!is_null($offset)) {
83
            $this->properties[$offset] = $value;
84
        }
85
    }
86
87
    /**
88
     * Implements \ArrayAccess.
89
     */
90
    public function offsetExists($offset)
91
    {
92
        return isset($this->properties[$offset]);
93
    }
94
95
    /**
96
     * Implements \ArrayAccess.
97
     */
98
    public function offsetUnset($offset)
99
    {
100
        unset($this->properties[$offset]);
101
    }
102
103
    /**
104
     * Implements \ArrayAccess.
105
     */
106
    public function offsetGet($offset)
107
    {
108
        return isset($this->properties[$offset]) ? $this->properties[$offset] : null;
109
    }
110
111
    /**
112
     * Returns as HTML tag.
113
     *
114
     * @return string
115
     */
116
    public function getHtml(): string
117
    {
118
        if ($this->properties['type'] == 'image') {
119
            return \sprintf(
120
                '<img src="%s" title="%s" alt="%s">',
121
                $this->properties['path'],
122
                $this->properties['attributs']['title'],
123
                $this->properties['attributs']['alt']
124
            );
125
        }
126
127
        switch ($this->properties['ext']) {
128
            case 'css':
129
                return \sprintf('<link rel="stylesheet" href="%s">', $this->properties['path']);
130
            case 'js':
131
                return \sprintf('<script src="%s"></script>', $this->properties['path']);
132
        }
133
134
        throw new Exception(\sprintf('%s is available only with CSS, JS and images files.', '.html'));
135
    }
136
137
    /**
138
     * Returns file's content.
139
     *
140
     * @return string
141
     */
142
    public function getInline(): string
143
    {
144
        if (!array_key_exists('content', $this->properties)) {
145
            throw new Exception(\sprintf('%s is available only with CSS et JS files.', '.inline'));
146
        }
147
148
        return $this->properties['content'];
149
    }
150
151
    /**
152
     * Try to find a static file (in site or theme(s)) if exists or returns false.
153
     *
154
     * @param string $path
155
     *
156
     * @return string|false
157
     */
158
    private function findFile(string $path)
159
    {
160
        $filePath = Util::joinFile($this->config->getStaticPath(), $path);
161
        if (Util::getFS()->exists($filePath)) {
162
            return $filePath;
163
        }
164
165
        // checks in each theme
166
        foreach ($this->config->getTheme() as $theme) {
167
            $filePath = Util::joinFile($this->config->getThemeDirPath($theme, 'static'), $path);
168
            if (Util::getFS()->exists($filePath)) {
169
                return $filePath;
170
            }
171
        }
172
173
        return false;
174
    }
175
}
176