Task #4268

handle model-attributes, that are not of type string, but user-input

Added by Irene Höppner about 12 years ago. Updated about 10 years ago.

Status:
Rejected
Priority:
Must have
Assignee:
-
Category:
MVC
Target version:
-
Start date:
Due date:
% Done:

0%

Estimated time:
6.00 h
Sprint:
PHP Version:
Has patch:
Complexity:

Description

I'm not sure, if this is a problem or something, I just didn't understand yet...

We have some attribute ("orderdate") in the model that is of type \DateTime and we want the user to add a date for that in the new-/edit-forms.

What we did and what happened:

1. Added the attribute + getter-/setter-method to the model class and an input-field to new.html:

/**
 *
 * @var \DateTime
 */
protected $orderdate = '';

/**
 *
 * @param \DateTime $orderdate
 * @return void
 */
public function setOrderdate(\DateTime $orderdate) {
    $this->orderdate = $orderdate;
}

/**
 *
 * @return \DateTime
 */
public function getOrderdate() {
    return $this->orderdate;
}
<label for="orderdate">Orderdate</label><br />
<f:form.textbox property="orderdate" id="orderdate" />

Result: Exception: Catchable Fatal Error: Argument 1 passed to F3\Blog\Domain\Model\Blog::setOrderdate() must be an instance of DateTime, string given in C:\Programme\xampp\htdocs\flow3\blog\Packages\Application\Blog\Classes\Domain\Model\Blog.php line 127

2. Removed the type hint from the setter:

/**
 *
 * @param \DateTime $orderdate
 * @return void
 */
public function setOrderdate($orderdate) {
    $this->orderdate = $orderdate;
}

Result: Exception: 1244465558: Expected property of type DateTime, but got string

3. Added a validator the the attribute:

/**
 *
 * @var \DateTime
 * @validate DateTime
 */
protected $orderdate = '';

Result: error-message:
orderdate: The given subject was not a valid DateTime. Got: "string"

But: We get that message, no matter what we entered into the input-field.

4. Created the \DateTime-object in the setter, if the parameter is of type string:

/**
 *
 * @param \DateTime $orderdate
 * @return void
 */
public function setOrderdate($orderdate) {
    if (is_string($orderdate)) {
        $orderdate = new \DateTime($orderdate);
    }
    $this->orderdate = $orderdate;
}

Result: Cool, works - as long as the string in the input-form has a proper format like yyyy-mm-dd.
Otherwise another exception: DateTime::__construct() [datetime.--construct]: Failed to parse time string (fgsdfasdfa) at position 0 (f): The timezone could not be found in the database

Ok, could check the string for a proper format in the setter... but we need the same check for several attributes in several classes...

5. What about writing our own validator?

Doesn't help because the setter comes first and needs a correct string already to create the datetime-object. Same exception like above.

6. Entered the orderdate-field to edit.html

<label for="orderdate">Orderdate</label><br />
<f:form.textbox property="orderdate" id="orderdate" />

Result: Exception: Warning: htmlspecialchars() expects parameter 1 to be string, object given in C:\Programme\xampp\htdocs\flow3\blog\Packages\Framework\Fluid\Classes\Core\ViewHelper\TagBuilder.php line 161

Added some short hand Fluid-syntax helps in that case:

<label for="orderdate">Auftragsdatum:<br />
<f:form.textbox property="orderdate" value="{f:format.date('{job.orderdate}' format='d.m.Y')}" />(Format: dd.mm.yyyy)<br />

Conclusion:

There has to be done some conversion between the strings coming from html-forms and attributes of the model that are not of type string. Before that conversion the strings probably have to be validated.
No idea where to do that best :-).

Also available in: Atom PDF