1: <?php
2:
3: /**
4: * This file is part of the Nette Framework (https://nette.org)
5: * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6: */
7:
8: namespace Nette\Forms\Controls;
9:
10: use Nette;
11: use Nette\Forms;
12: use Nette\Http\FileUpload;
13:
14:
15: /**
16: * Text box and browse button that allow users to select a file to upload to the server.
17: */
18: class UploadControl extends BaseControl
19: {
20: /** validation rule */
21: const VALID = ':uploadControlValid';
22:
23:
24: /**
25: * @param string|object
26: * @param bool
27: */
28: public function __construct($label = null, $multiple = false)
29: {
30: parent::__construct($label);
31: $this->control->type = 'file';
32: $this->control->multiple = (bool) $multiple;
33: $this->setOption('type', 'file');
34: $this->addCondition(Forms\Form::FILLED)
35: ->addRule([$this, 'isOk'], Forms\Validator::$messages[self::VALID]);
36: }
37:
38:
39: /**
40: * This method will be called when the component (or component's parent)
41: * becomes attached to a monitored object. Do not call this method yourself.
42: * @param Nette\ComponentModel\IComponent
43: * @return void
44: */
45: protected function attached($form)
46: {
47: if ($form instanceof Nette\Forms\Form) {
48: if (!$form->isMethod('post')) {
49: throw new Nette\InvalidStateException('File upload requires method POST.');
50: }
51: $form->getElementPrototype()->enctype = 'multipart/form-data';
52: }
53: parent::attached($form);
54: }
55:
56:
57: /**
58: * Loads HTTP data.
59: * @return void
60: */
61: public function loadHttpData()
62: {
63: $this->value = $this->getHttpData(Nette\Forms\Form::DATA_FILE);
64: if ($this->value === null) {
65: $this->value = new FileUpload(null);
66: }
67: }
68:
69:
70: /**
71: * Returns HTML name of control.
72: * @return string
73: */
74: public function getHtmlName()
75: {
76: return parent::getHtmlName() . ($this->control->multiple ? '[]' : '');
77: }
78:
79:
80: /**
81: * @return static
82: * @internal
83: */
84: public function setValue($value)
85: {
86: return $this;
87: }
88:
89:
90: /**
91: * Has been any file uploaded?
92: * @return bool
93: */
94: public function isFilled()
95: {
96: return $this->value instanceof FileUpload
97: ? $this->value->getError() !== UPLOAD_ERR_NO_FILE // ignore null object
98: : (bool) $this->value;
99: }
100:
101:
102: /**
103: * Have been all files succesfully uploaded?
104: * @return bool
105: */
106: public function isOk()
107: {
108: return $this->value instanceof FileUpload
109: ? $this->value->isOk()
110: : $this->value && array_reduce($this->value, function ($carry, $fileUpload) {
111: return $carry && $fileUpload->isOk();
112: }, true);
113: }
114: }
115: