Completed
Push — master ( 522199...324a18 )
by Dmitry
04:01
created

FileRender::getPathToFile()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 4
ccs 0
cts 4
cp 0
crap 2
rs 10
c 0
b 0
f 0
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
        if (!$this->file instanceof File) {
73
            throw new InvalidConfigException('The "data" property must instance of File class.');
74
        }
75
        $this->fileStorage = Yii::$app->get($this->fileStorageComponent);
76
77
        $this->registerClientScript();
78
        $this->renderHtml();
79
    }
80
81
    private function registerClientScript()
82
    {
83
        $view = $this->getView();
84
        LightboxAsset::register($view);
85
        // Fix: Incorrect resizing of image #122
86
        $view->registerCss('.lightbox  .lb-image { max-width: inherit!important; }');
87
    }
88
89
    private function renderHtml()
90
    {
91
        $file = $this->file;
92
93
        $filename = $this->fileStorage->get($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...
94
        $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...
95
        if (mb_substr($contentType, 0, 5) === 'image') {
96
            $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->id) on line 93 can also be of type boolean; however, yii\imagine\BaseImage::thumbnail() 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...
97
            $base64 = 'data: ' . $contentType . ';base64,' . base64_encode($thumb);
98
            echo Html::a(
99
                Html::img($base64, ['class' => 'margin']),
100
                $this->getLink($file['id']),
101
                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...
102
            );
103
        } else {
104
            echo Html::a(
105
                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...
106
                $this->getLink($file->id, true)
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...
107
            );
108
        }
109
    }
110
111
    private function getLink($id, $download = false)
112
    {
113
        if (!$download) {
114
            return Url::to(['/file/view', 'id' => $id]);
115
        } else {
116
            return Url::to(['/file/get', 'id' => $id]);
117
        }
118
    }
119
120
    private function getContentType($id)
121
    {
122
        $path = $this->fileStorage->get($id);
123
124
        return FileHelper::getMimeType($path);
0 ignored issues
show
Bug introduced by
It seems like $path defined by $this->fileStorage->get($id) on line 122 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...
125
    }
126
127
    private function getExtIcon($ext)
128
    {
129
        $default = '<div><i class="fa fa-file-text-o fa-2x"></i></div>';
130
        if (array_key_exists($ext, $this->extMatch)) {
131
            return $this->extMatch[$ext];
132
        } else {
133
            return $default;
134
        }
135
    }
136
}
137