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: * @param string label
25: * @param bool allows to upload multiple files
26: */
27: public function __construct($label = NULL, $multiple = FALSE)
28: {
29: parent::__construct($label);
30: $this->control->type = 'file';
31: $this->control->multiple = (bool) $multiple;
32: $this->setOption('type', 'file');
33: $this->addCondition(Forms\Form::FILLED)
34: ->addRule([$this, 'isOk'], Forms\Validator::$messages[self::VALID]);
35: }
36:
37:
38: /**
39: * This method will be called when the component (or component's parent)
40: * becomes attached to a monitored object. Do not call this method yourself.
41: * @param Nette\ComponentModel\IComponent
42: * @return void
43: */
44: protected function attached($form)
45: {
46: if ($form instanceof Nette\Forms\Form) {
47: if (!$form->isMethod('post')) {
48: throw new Nette\InvalidStateException('File upload requires method POST.');
49: }
50: $form->getElementPrototype()->enctype = 'multipart/form-data';
51: }
52: parent::attached($form);
53: }
54:
55:
56: /**
57: * Loads HTTP data.
58: * @return void
59: */
60: public function loadHttpData()
61: {
62: $this->value = $this->getHttpData(Nette\Forms\Form::DATA_FILE);
63: if ($this->value === NULL) {
64: $this->value = new FileUpload(NULL);
65: }
66: }
67:
68:
69: /**
70: * Returns HTML name of control.
71: * @return string
72: */
73: public function getHtmlName()
74: {
75: return parent::getHtmlName() . ($this->control->multiple ? '[]' : '');
76: }
77:
78:
79: /**
80: * @return self
81: * @internal
82: */
83: public function setValue($value)
84: {
85: return $this;
86: }
87:
88:
89: /**
90: * Has been any file uploaded?
91: * @return bool
92: */
93: public function isFilled()
94: {
95: return $this->value instanceof FileUpload
96: ? $this->value->getError() !== UPLOAD_ERR_NO_FILE // ignore NULL object
97: : (bool) $this->value;
98: }
99:
100:
101: /**
102: * Have been all files succesfully uploaded?
103: * @return bool
104: */
105: public function isOk()
106: {
107: return $this->value instanceof FileUpload
108: ? $this->value->isOk()
109: : $this->value && array_reduce($this->value, function ($carry, $fileUpload) {
110: return $carry && $fileUpload->isOk();
111: }, TRUE);
112: }
113:
114: }
115: