Completed
Push — master ( 54abba...1f2abd )
by Dmitry
05:21
created

FileRender::getRoute()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 0
cts 7
cp 0
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 1
crap 6
1
<?php
2
3
/*
4
 * HiPanel core package
5
 *
6
 * @link      https://hipanel.com/
7
 * @package   hipanel-core
8
 * @license   BSD-3-Clause
9
 * @copyright Copyright (c) 2014-2016, HiQDev (http://hiqdev.com/)
10
 */
11
12
namespace hipanel\widgets;
13
14
use hipanel\components\FileStorage;
15
use hipanel\helpers\ArrayHelper;
16
use hipanel\helpers\FileHelper;
17
use hipanel\models\File;
18
use hiqdev\assets\lightbox2\LightboxAsset;
19
use Yii;
20
use yii\base\InvalidConfigException;
21
use yii\base\Widget;
22
use yii\helpers\Html;
23
use yii\helpers\Url;
24
use yii\imagine\Image;
25
26
class FileRender extends Widget
27
{
28
    /**
29
     * @var File
30
     */
31
    public $file;
32
33
    /**
34
     * @var int
35
     */
36
    public $thumbWidth = 64;
37
38
    /**
39
     * @var int
40
     */
41
    public $thumbHeight = 64;
42
43
    /**
44
     * @var string Name of the file storage component
45
     */
46
    public $fileStorageComponent = 'fileStorage';
47
48
    /**
49
     * @var FileStorage
50
     */
51
    protected $fileStorage;
52
53
    /**
54
     * @var array Options that will be passed to [[Html::a()]] for the image lightbox
55
     */
56
    public $lightboxLinkOptions = [];
57
58
    /**
59
     * @var array
60
     */
61
    private $extMatch = [
62
        'pdf' => '<div><i class="fa fa-file-pdf-o fa-2x"></i></div>',
63
        'doc' => '<div><i class="fa fa-file-word-o fa-2x"></i></div>',
64
        'docx' => '<div><i class="fa fa-file-word-o fa-2x"></i></div>',
65
        'xls' => '<div><i class="fa fa-file-excel-o fa-2x"></i></div>',
66
        'xlsx' => '<div><i class="fa fa-file-excel-o fa-2x"></i></div>',
67
    ];
68
69
    public function init()
70
    {
71
        parent::init();
72
73
        if (!$this->file instanceof File) {
74
            throw new InvalidConfigException('The "data" property must instance of File class.');
75
        }
76
        $this->fileStorage = Yii::$app->get($this->fileStorageComponent);
77
    }
78
79
    public function run()
80
    {
81
        $this->registerClientScript();
82
        $this->renderHtml();
83
    }
84
85
    private function registerClientScript()
86
    {
87
        $view = $this->getView();
88
        LightboxAsset::register($view);
89
        // Fix: Incorrect resizing of image #122
90
        $view->registerCss('.lightbox  .lb-image { max-width: inherit!important; }');
91
    }
92
93
    private function renderHtml()
94
    {
95
        $file = $this->file;
96
97
        $filename = $this->fileStorage->get($file);
98
        $contentType = $this->getContentType($file->id);
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<hipanel\models\File>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
99
        if (mb_substr($contentType, 0, 5) === 'image') {
100
            $thumb = Image::thumbnail($filename, $this->thumbHeight, $this->thumbHeight);
0 ignored issues
show
Bug introduced by
It seems like $filename defined by $this->fileStorage->get($file) on line 97 can also be of type boolean; however, yii\imagine\BaseImage::thumbnail() does only seem to accept string|resource|object<I...e\Image\ImageInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
101
            $base64 = 'data: ' . $contentType . ';base64,' . base64_encode($thumb);
102
            echo Html::a(
103
                Html::img($base64, ['class' => 'margin']),
104
                $this->getLink(),
105
                ArrayHelper::merge(['data-lightbox' => 'file-' . $file->id], $this->lightboxLinkOptions)
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<hipanel\models\File>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
106
            );
107
        } else {
108
            echo Html::a(
109
                Html::tag('div', $this->getExtIcon($file->type), ['class' => 'margin file']),
0 ignored issues
show
Documentation introduced by
The property type does not exist on object<hipanel\models\File>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
110
                $this->getLink(true)
111
            );
112
        }
113
    }
114
115
    private function getLink($download = false)
116
    {
117
        return Url::to($this->getRoute($download));
0 ignored issues
show
Documentation introduced by
$download is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
118
    }
119
120
    /**
121
     * @param string $download whether to return route to download page
122
     *
123
     * @return array
124
     */
125
    public function getRoute($download)
126
    {
127
        if ($download) {
128
            return ['/file/get', 'id' => $this->file->id];
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<hipanel\models\File>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
129
        }
130
131
        return ['/file/view', 'id' => $this->file->id];
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<hipanel\models\File>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
132
    }
133
134
    private function getContentType($id)
135
    {
136
        $path = $this->fileStorage->get($id);
137
138
        return FileHelper::getMimeType($path);
0 ignored issues
show
Bug introduced by
It seems like $path defined by $this->fileStorage->get($id) on line 136 can also be of type boolean; however, yii\helpers\BaseFileHelper::getMimeType() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
139
    }
140
141
    private function getExtIcon($ext)
142
    {
143
        $default = '<div><i class="fa fa-file-text-o fa-2x"></i></div>';
144
        if (array_key_exists($ext, $this->extMatch)) {
145
            return $this->extMatch[$ext];
146
        } else {
147
            return $default;
148
        }
149
    }
150
}
151