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\Application\UI;
9:
10: use Nette;
11:
12:
13: /**
14: * Web form adapted for Presenter.
15: *
16: * @author David Grudl
17: */
18: class Form extends Nette\Forms\Form implements ISignalReceiver
19: {
20:
21: /**
22: * Application form constructor.
23: */
24: public function __construct(Nette\ComponentModel\IContainer $parent = NULL, $name = NULL)
25: {
26: parent::__construct();
27: if ($parent !== NULL) {
28: $parent->addComponent($this, $name);
29: }
30: }
31:
32:
33: /**
34: * @return void
35: */
36: protected function validateParent(Nette\ComponentModel\IContainer $parent)
37: {
38: parent::validateParent($parent);
39: $this->monitor('Nette\Application\UI\Presenter');
40: }
41:
42:
43: /**
44: * Returns the presenter where this component belongs to.
45: * @param bool throw exception if presenter doesn't exist?
46: * @return Presenter|NULL
47: */
48: public function getPresenter($need = TRUE)
49: {
50: return $this->lookup('Nette\Application\UI\Presenter', $need);
51: }
52:
53:
54: /**
55: * This method will be called when the component (or component's parent)
56: * becomes attached to a monitored object. Do not call this method yourself.
57: * @param Nette\ComponentModel\IComponent
58: * @return void
59: */
60: protected function attached($presenter)
61: {
62: if ($presenter instanceof Presenter) {
63: $name = $this->lookupPath('Nette\Application\UI\Presenter');
64:
65: if (!isset($this->getElementPrototype()->id)) {
66: $this->getElementPrototype()->id = 'frm-' . $name;
67: }
68:
69: if (iterator_count($this->getControls()) && $this->isSubmitted()) {
70: foreach ($this->getControls() as $control) {
71: if (!$control->isDisabled()) {
72: $control->loadHttpData();
73: }
74: }
75: }
76:
77: if (!$this->getAction()) {
78: $this->setAction(new Link($presenter, 'this', array()));
79: $signal = new Nette\Forms\Controls\HiddenField($name . self::NAME_SEPARATOR . 'submit');
80: $signal->setOmitted()->setHtmlId(FALSE);
81: $this[Presenter::SIGNAL_KEY] = $signal;
82: }
83: }
84: parent::attached($presenter);
85: }
86:
87:
88: /**
89: * Tells if the form is anchored.
90: * @return bool
91: */
92: public function isAnchored()
93: {
94: return (bool) $this->getPresenter(FALSE);
95: }
96:
97:
98: /**
99: * Internal: returns submitted HTTP data or NULL when form was not submitted.
100: * @return array|NULL
101: */
102: protected function receiveHttpData()
103: {
104: $presenter = $this->getPresenter();
105: if (!$presenter->isSignalReceiver($this, 'submit')) {
106: return;
107: }
108:
109: $isPost = $this->getMethod() === self::POST;
110: $request = $presenter->getRequest();
111: if ($request->isMethod('forward') || $request->isMethod('post') !== $isPost) {
112: return;
113: }
114:
115: if ($isPost) {
116: return Nette\Utils\Arrays::mergeTree($request->getPost(), $request->getFiles());
117: } else {
118: return $request->getParameters();
119: }
120: }
121:
122:
123: /********************* interface ISignalReceiver ****************d*g**/
124:
125:
126: /**
127: * This method is called by presenter.
128: * @param string
129: * @return void
130: */
131: public function signalReceived($signal)
132: {
133: if ($signal === 'submit') {
134: if (!$this->getPresenter()->getRequest()->hasFlag(Nette\Application\Request::RESTORED)) {
135: $this->fireEvents();
136: }
137: } else {
138: $class = get_class($this);
139: throw new BadSignalException("Missing handler for signal '$signal' in $class.");
140: }
141: }
142:
143: }
144: