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