Form.php 7.03 KB
Newer Older
1
2
3
4
5
6
7
8
<?php
/**
 * Created by PhpStorm.
 * User: ep
 * Date: 12/23/15
 * Time: 6:33 PM
 */

Carsten  Rose's avatar
Carsten Rose committed
9

10
11
namespace qfq;

Carsten  Rose's avatar
Carsten Rose committed
12
use qfq;
Carsten  Rose's avatar
Carsten Rose committed
13
use qfq\exceptions\UserException;
14
15
use qfq\exceptions\CodeException;
use qfq\exceptions\DbException;
16
use qfq\helper;
17
use qfq\store;
Carsten  Rose's avatar
Carsten Rose committed
18

19
require_once(__DIR__ . '/../qfq/store/Store.php');
Carsten  Rose's avatar
Carsten Rose committed
20
require_once(__DIR__ . '/../qfq/Constants.php');
Carsten  Rose's avatar
Carsten Rose committed
21
require_once(__DIR__ . '/../qfq/helper/KeyValueStringParser.php');
Carsten  Rose's avatar
Carsten Rose committed
22
require_once(__DIR__ . '/../qfq/exceptions/UserException.php');
23
24
require_once(__DIR__ . '/../qfq/exceptions/CodeException.php');
require_once(__DIR__ . '/../qfq/exceptions/DbException.php');
25
require_once(__DIR__ . '/../qfq/Database.php');
26
require_once(__DIR__ . '/../qfq/FormBuildPlain.php');
27

28
29
30
31
32
33
34
35
36
37
38
39
/*
 * Form will be called
 * a) with a SIP identifier, or
 * b) without a SIP identifier (form setting has to allow this) and will create on the fly a new SIP.
 *
 * The SIP-Store stores:
 *  form=<formname>
 *  r=<record id>  (table.id for a single record form)
 *  keySemId,keySemIduser
 *  <further individual variables>
 */

40
class Form {
Carsten  Rose's avatar
Carsten Rose committed
41

Carsten  Rose's avatar
Carsten Rose committed
42
    protected $store = null;
43
    protected $db = null;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
    protected $formDef = array();  // Form Definition: copy of the loaded form
    protected $feDefAction = array(); // FormEelement Definition: all formElement.class='action' of the loaded form
    protected $feDefNative = array(); // FormEelement Definition: all formElement.class='native' of the loaded form

    /*
     * TODO:
     *  Preparation: setup logging, database access, record locking
     *  fill stores
     *  Check permission_create / permission_update
     *  Multi: iterate over all records, Single: activate record
     *      Check mode: Load | Save
     *      doActions 'Before'
     *      Do all FormElements
     *      doActions 'After'
     */
59
60


61
62
63
64
65
66
//    protected $formElements = null;
//    protected $userLog = null;

    /*
     *
     */
67
    public function __construct($bodytext = '') {
68

69
        $this->store = \qfq\store\Store::getInstance($bodytext);
70
        $this->db = new Database();
Carsten  Rose's avatar
Carsten Rose committed
71
72
    }

73
74
    /**
     * @return string
Carsten  Rose's avatar
Carsten Rose committed
75
     */
76
    public function process() {
77
78
        $html = '';
        $build = null;
79
        $master = null;
80
81
82
83
84
85
86
87
88

//        render:
//        plain
//        multimode: none

        try {
            // Form action: load or save?
            $mode = ($this->store->getVar(CLIENT_POST_SIP, STORE_CLIENT) === false) ? FORM_LOAD : FORM_SAVE;

89
90
91
92
93
94
            $formName = $this->loadFormDefinition();

            $sipFound = $this->checkFormLoad();
            if (!$sipFound) {
                $this->store->createFakeSipAfterFormLoad($formName);
            }
95
96
97
98
99
100
101
102
103

            // TODO: replace switch() by Marschaller
            // render: FormPlain | FormBootstrap
            switch ($this->formDef['render']) {
                case 'Plain':
                    $build = new FormBuildPlain($this->formDef, $this->feDefAction, $this->feDefNative);
                    break;
                case 'Bootstrap':
                    //TODO: implement bootstrap rendering: FormBuildBootstrap
104
//                    $build = new FormBuildBootstrap($this->formDef, $this->feDefAction, $this->feDefNative);
105
106
                    break;
                default:
107
                    throw new CodeException("This statement should never be reached", ERROR_CODE_SHOULD_NOT_HAPPEN);
108
109
110
111
112
113
114
115
116
117
118
119
120
            }

            switch ($mode) {
                case FORM_LOAD:
//                    $this->formActionBefore();
                    $html .= $build->head();
                    $html .= $build->elements();
                    $html .= $build->tail();
//                    $this->formActionAfter();
                    break;
                case FORM_SAVE:
                    break;
                default:
121
                    throw new CodeException("This statement should never be reached", ERROR_CODE_SHOULD_NOT_HAPPEN);
122
123
124
125
126
127
128
129
130
131
132
133
            }
            return $html;

        } catch (UserException $e) {
            echo $e->formatMessage();
        } catch (CodeException $e) {
            echo $e->formatMessage();
        } catch (DbException $e) {
            echo $e->formatMessage();
        } catch (\Exception $e) {
            echo "Generic Exception: " . $e->getMessage();
        }
Carsten  Rose's avatar
Carsten Rose committed
134

135
        return $html;
136
137
    }

138
    /**
139
     * @return string formName
140
     * @throws DbException
141
     * @throws UserException
142
     */
Carsten  Rose's avatar
Carsten Rose committed
143
    private function loadFormDefinition() {
Carsten  Rose's avatar
Carsten Rose committed
144

Carsten  Rose's avatar
Carsten Rose committed
145
        $formName = $this->getFormName();
146
        $this->formDef = $this->db->sql("SELECT * FROM Form AS f WHERE f.name LIKE ? AND f.deleted='no'", ROW_EXACT_1, [$formName]);
Carsten  Rose's avatar
Carsten Rose committed
147

148
149
150
        $sql = "SELECT * FROM FormElement AS fe WHERE fe.formId = ? AND fe.deleted='no' AND fe.class = ? AND fe.enabled='yes' ORDER BY fe.order, fe.id";
        $this->feDefAction = $this->db->sql($sql, ROW_REGULAR, [$this->formDef["id"], 'action']);
        $this->feDefNative = $this->db->sql($sql, ROW_REGULAR, [$this->formDef["id"], 'native']);
151
152

        return $formName;
Carsten  Rose's avatar
Carsten Rose committed
153
154
    }

Carsten  Rose's avatar
Carsten Rose committed
155
156
157
158
    /**
     * @return string
     * @throws UserException
     * @throws exceptions\CodeException
Carsten  Rose's avatar
Carsten Rose committed
159
160
     */

Carsten  Rose's avatar
Carsten Rose committed
161
162
    private function getFormName() {

163
        $formName = $this->store->getVar(T3_BODYTEXT_FORM, STORE_T3_BODYTEXT . STORE_SIP . STORE_CLIENT);
Carsten  Rose's avatar
Carsten Rose committed
164
165
166
        if ($formName !== false)
            return $formName;

167
168
169
        // TODO: phpunit tests all - missing formname always fires this exception
        throw new CodeException("Missing form name. Not found in T3_BODYTEXT / SIP / GET", ERROR_MISSING_FORM_NAME);
    }
Carsten  Rose's avatar
Carsten Rose committed
170

171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
    /**
     * @return bool - 'true' if SIP exists, else 'false'
     * @throws CodeException
     * @throws UserException
     */
    private function checkFormLoad() {

        // Retrieve record_id either from SIP (prefered) or via URL
        $r = $this->store->getVar(SIP_RECORD_ID, STORE_SIP . STORE_CLIENT);

        // If there is a record_id>0: EDIT else NEW
        $mode = ($r > 0) ? $this->formDef['permitEdit'] : $this->formDef['permitNew'];

        $feUserLoggedIn = isset($GLOBALS["TSFE"]->fe_user->user["uid"]) && $GLOBALS["TSFE"]->fe_user->user["uid"] > 0;

        $sipFound = $this->store->getVar(SIP_SIP, STORE_SIP) !== false;

        switch ($mode) {
            case  FORM_PERMISSION_SIP:
                if (!$sipFound) {
                    throw new UserException("SIP Parameter needed for this form.", ERROR_SIP_NEEDED_FOR_THIS_FORM);
                }
                break;
            case  FORM_PERMISSION_LOGGED_IN:
                if (!$feUserLoggedIn) {
                    throw new UserException("User not logged in.", ERROR_USER_NOT_LOGGED_IN);
                }
                break;
            case FORM_PERMISSION_LOGGED_OUT:
                if ($feUserLoggedIn) {
                    throw new UserException("User logged in.", ERROR_USER_LOGGED_IN);
                }
                break;
            case FORM_PERMISSION_ALWAYS:
                break;
            case FORM_PERMISSION_NEVER:
                throw new UserException("Loading form forbidden.", ERROR_FORM_FORBIDDEN);
            default:
                throw new CodeException("Unknown permission mode: '" . $mode . "'", ERROR_FORM_UNKNOWN_PERMISSION_MODE);
        }
Carsten  Rose's avatar
Carsten Rose committed
211

212
        return $sipFound;
213
    }
Carsten  Rose's avatar
Carsten Rose committed
214

215
}