Completed
Push — develop ( 34a49a...d51da1 )
by
unknown
47s
created

FormFileUpload::getDefaultNotice()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/**
3
 * YAWIK
4
 *
5
 * @filesource
6
 * @copyright (c) 2013 - 2016 Cross Solution (http://cross-solution.de)
7
 * @license       MIT
8
 */
9
10
/**  */
11
namespace Core\Form\View\Helper;
12
13
use Zend\Form\View\Helper\FormFile;
14
use Zend\Form\ElementInterface;
15
use Core\Form\Element\FileUpload;
16
17
/**
18
 * View helper to render a file upload element.
19
 *
20
 * @author Mathias Gelhausen <[email protected]>
21
 * @author Miroslav Fedeleš <[email protected]>
22
 */
23
class FormFileUpload extends FormFile
24
{
25
    /**
26
     * Javascript file to inject to headscript helper
27
     *
28
     * @var string
29
     */
30
    protected $scriptFile = 'Core/js/forms.file-upload.js';
31
    
32
    /**
33
     * @var string
34
     */
35
    protected $emptyNotice;
36
    
37
    /**
38
     * @var string
39
     */
40
    protected $nonEmptyNotice;
41
    
42
    /**
43
     * @var bool
44
     */
45
    protected $allowRemove = true;
46
    
47
    /**
48
     * @var bool
49
     */
50
    protected $allowClickableDropZone = true;
51
52
    public function render(ElementInterface $element)
53
    {
54
        if (!$element instanceof FileUpload) {
55
            throw new \InvalidArgumentException('Expects element of type "Core\Form\Element\FileUpload"');
56
        }
57
58
        $markup = $this->renderMarkup($element);
59
        $markup = str_replace('__input__', $this->renderFileElement($element), $markup);
60
61
        return $markup;
62
    }
63
    
64
    /**
65
     * @param FileUpload $element
66
     * @return string
67
     * @since 0.27
68
     */
69
    public function renderFileList(FileUpload $element)
70
    {
71
        $this->setupAssets();
72
        
73
        $file       = $element->getFileEntity();
74
        $preview    = '';
75
        $translator = $this->getTranslator();
76
        $textDomain = $this->getTranslatorTextDomain();
77
78
        $template = '
79
<li class="fu-file fu-working">'.($this->allowRemove ? '
80
    <a href="#abort" class="fu-delete-button btn btn-default btn-xs">
81
        <span class="yk-icon yk-icon-minus"></span>
82
    </a>
83
    ' : '').'<div class="fu-progress">
84
        <span class="yk-icon yk-icon-spinner fa-spin"></span>
85
        <span class="fu-progress-text">0</span> %
86
    </div>
87
    <a class="fu-file-info" href="__file-uri__" target="_blank">
88
        <span class="yk-icon fa-file-o fa-4x"></span>
89
        __file-name__ <br> (__file-size__)
90
    </a>
91
    <div class="fu-errors input-error">
92
        <ul class="errors">
93
            <li class="fu-error-size">' . $translator->translate('The file is too big', $textDomain) . '</li>
94
            <li class="fu-error-type">' . $translator->translate('The file type is not supported', $textDomain) . '</li>
95
            <li class="fu-error-count">' . sprintf(
96
    $translator->translate('You may only upload %d files', $textDomain),
97
    $element->getAttribute('data-maxfilecount')
98
) . '</li><li class="fu-error-general">' . $translator->translate('An unknown error occured.') . '</li>
99
        </ul>
100
   </div>
101
</li>';
102
        /* @var $renderer \Zend\View\Renderer\PhpRenderer */
103
        /* @var $basepath \Zend\View\Helper\BasePath */
104
        $renderer          = $this->getView();
105
        $basepath          = $renderer->plugin('basepath');
106
        $createFileDisplay = function ($file) use ($template, $basepath) {
107
            /* @var $file \Core\Entity\FileInterface */
108
            $uri  = $basepath($file->getUri());
109
            $name = $file->getName();
110
            $size = $file->getPrettySize();
111
            $icon = 0 === strpos($file->getType(), 'image/')
112
                ? 'fa-file-image-o' : 'fa-file-o';
113
114
            return str_replace(
115
                array('#abort',
116
                      '__file-uri__',
117
                      '__file-name__',
118
                      '__file-size__',
119
                      'fu-working',
120
                      'fa-file-o'
121
                ),
122
                array("$uri?do=delete", $uri, $name, $size, '', $icon),
123
                $template
124
            );
125
126
        };
127
128
        if ($element->isMultiple()) {
129
            if (count($file)) {
130
                foreach ($file as $f) {
0 ignored issues
show
Bug introduced by
The expression $file of type null|object<Doctrine\Com...e\Entity\FileInterface> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
131
                    $preview .= $createFileDisplay($f);
132
                }
133
            }
134
        } else {
135
            if ($file) {
136
                $preview = $createFileDisplay($file);
137
            }
138
        }
139
140
        $nonemptynotice =
141
            '<div class="fu-nonempty-notice"' . ('' == trim($preview) ? ' style="display:none;"' : '') . '>'
142
            . $this->getNonEmptyNotice() . '</div>';
143
        $emptynotice    = '<div class="fu-empty-notice"'
144
                          . ('' == trim($preview) ? '' : ' style="display: none;"') . '>
145
                       ' . $this->getEmptyNotice() . '
146
                  </div>';
147
148
        $markup = '
149
    <span class="fu-template" data-template="%2$s"></span>
150
    %4$s
151
    <ul class="fu-files">
152
    %1$s
153
    </ul>
154
    %3$s';
155
156
        $markup = sprintf(
157
            $markup,
158
            $preview,
159
            $renderer->escapeHtmlAttr(trim($template)),
160
            $emptynotice,
161
            $nonemptynotice
162
        );
163
164
        return $markup;
165
    }
166
    
167
    /**
168
     * @param FileUpload $element
169
     * @return string
170
     * @throws \DomainException
171
     * @since 0.27
172
     */
173
    public function renderFileElement(FileUpload $element)
174
    {
175
        $name = $element->getName();
176
        if ($name === null || $name === '') {
177
            throw new \DomainException(
178
                sprintf(
179
                    '%s requires that the element has an assigned name; none discovered',
180
                    __METHOD__
181
                )
182
            );
183
        }
184
        
185
        $attributes         = $element->getAttributes();
186
        $attributes['type'] = $this->getType($element);
187
        $attributes['name'] = $name;
188
189
        return sprintf(
190
            '<input %s%s',
191
            $this->createAttributesString($attributes),
0 ignored issues
show
Bug introduced by
It seems like $attributes defined by $element->getAttributes() on line 185 can also be of type object<Traversable>; however, Zend\Form\View\Helper\Ab...reateAttributesString() does only seem to accept array, 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...
192
            $this->getInlineClosingBracket()
193
        );
194
    }
195
196
    /**
197
     * Renders the markup for the file upload element.
198
     *
199
     * @param FileUpload $element
200
     *
201
     * @return string
202
     */
203
    protected function renderMarkup(FileUpload $element)
204
    {
205
        $markup = '
206
<div class="%s" id="%s-dropzone">
207
    %s
208
   __input__
209
</div>';
210
        
211
        return sprintf(
212
            $markup,
213
            $this->getDropZoneClass($element),
214
            $element->getAttribute('id'),
215
            $this->renderFileList($element)
216
        );
217
    }
218
    
219
    /**
220
     * @param FileUpload $element
221
     * @return string
222
     * @since 0.27
223
     */
224
    public function getDropZoneClass(FileUpload $element)
225
    {
226
        return sprintf('fu-dropzone fu-%s%s',
227
            $element->isMultiple() ? 'multiple' : 'single',
228
            $this->allowClickableDropZone ? '' : ' fu-non-clickable'
229
        );
230
    }
231
    
232
    /**
233
	 * @param string $emptyNotice
234
	 * @return FormFileUpload
235
	 * @since 0.27
236
	 */
237
	public function setEmptyNotice($emptyNotice)
238
	{
239
		$this->emptyNotice = $emptyNotice;
240
		
241
		return $this;
242
	}
243
    
244
    /**
245
	 * @return string
246
	 * @since 0.27
247
	 */
248
	protected function getEmptyNotice()
249
	{
250
	    if (!isset($this->emptyNotice))
251
	    {
252
	        $this->emptyNotice = '
253
	            <div class="pull-left">
254
                    <span class="yk-icon fa-files-o fa-5x"></span>
255
                </div>' . $this->getDefaultNotice();
256
	    }
257
	    
258
		return $this->emptyNotice;
259
	}
260
261
    /**
262
	 * @param string $nonEmptyNotice
263
	 * @return FormFileUpload
264
	 * @since 0.27
265
	 */
266
	public function setNonEmptyNotice($nonEmptyNotice)
267
	{
268
		$this->nonEmptyNotice = $nonEmptyNotice;
269
		
270
		return $this;
271
	}
272
273
    /**
274
	 * @return string
275
	 * @since 0.27
276
	 */
277
	protected function getNonEmptyNotice()
278
	{
279
	    if (!isset($this->nonEmptyNotice))
280
	    {
281
	        $this->nonEmptyNotice = $this->getDefaultNotice();
282
	    }
283
	    
284
		return $this->nonEmptyNotice;
285
	}
286
287
    /**
288
	 * @return string
289
	 * @since 0.27
290
	 */
291
	protected function getDefaultNotice()
292
	{
293
		return '<small>' . $this->getTranslator()->translate('Click here to add files or use drag and drop.') . '</small>';
294
	}
295
	
296
    /**
297
	 * @param boolean $allowRemove
298
	 * @return FormFileUpload
299
	 * @since 0.27
300
	 */
301
	public function setAllowRemove($allowRemove)
302
	{
303
		$this->allowRemove = (bool)$allowRemove;
304
		
305
		return $this;
306
	}
307
	
308
    /**
309
	 * @param boolean $allowClickableDropZone
310
	 * @return FormFileUpload
311
	 * @since 0.27
312
	 */
313
	public function setAllowClickableDropZone($allowClickableDropZone)
314
	{
315
		$this->allowClickableDropZone = (bool)$allowClickableDropZone;
316
		
317
		return $this;
318
	}
319
	
320
	/**
321
	 * @since 0.27
322
	 */
323
	protected function setupAssets()
324
	{
325
	    /* @var $renderer \Zend\View\Renderer\PhpRenderer */
326
        /* @var $basepath \Zend\View\Helper\BasePath */
327
        $renderer = $this->getView();
328
        $basepath = $renderer->plugin('basepath');
329
        $renderer->headscript()
330
            ->appendFile($basepath('js/jquery-file-upload/vendor/jquery.ui.widget.js'))
331
            ->appendFile($basepath('js/jquery-file-upload/jquery.iframe-transport.js'))
332
            ->appendFile($basepath('js/jquery-file-upload/jquery.fileupload.js'))
333
            ->appendFile($basepath($this->scriptFile));
334
	}
335
}
336