先决条件
public $var;
现在在 public 和 $var 之间插入类型化属性,即 public ?string $var = ''
排除其他类型。类型前的问号允许空值输入。所以只有两种选择。dateHelper.php(改编自 Invoiceplane)
/**
* @return string|null
*/
public function date_from_mysql($date, $s)
{
//if previous input was not a date mySql would have input '0000-00-00'
if ($date <> '0000-00-00') {
//CYCLE converts all dates to DateTimeImmutable
$date = DateTime::createFromImmutable($date);
//$date = DateTime::createFromFormat('Y-m-d', $date);
//eg. $date->format('Ymd')
return $date->format($s->setting('date_format'));
}
return $date;
}
return '';
}
__form.php 标题
<div class="mb-3 form-group has-feedback">
<label form-label for="client_birthdate"><?= $s->trans('birthdate'); ?></label>
<?php
$bdate = $body['client_birthdate'] ?? null;
if ($bdate && $bdate != "0000-00-00") {
//use the DateHelper
$datehelper = new DateHelper();
$bdate = $datehelper->date_from_mysql($bdate, false, $s);
} else {
$bdate = null;
}
?>
<div class="input-group">
<input type="text" name="client_birthdate" id="client_birthdate" placeholder="1900/12/01"
class="form-control data-datepicker"
value="<?= Html::encode($bdate); ?>">
<span class="input-group-addon">
<i class="fa fa-calendar fa-fw"></i>
</span>
</div>
</div>
Entity/Client.php
declare(strict_types=1);
namespace App\Invoice\Entity;
use \DateTime;
/**
* @Entity(
* repository="App\Invoice\Client\ClientRepository",
* mapper="App\Invoice\Client\ClientMapper",
* constrain="App\Invoice\Client\Scope\activeScope"
* )
* @Table(
* indexes={
* @Index(columns={"client_active"}),
* }
* )
*/
class Client
{
/**
* @Column(type="date", nullable=true)
*/
private $client_birthdate = '';
//CYCLE converts all date formats ie. DATE, DATETIME, to DateTimeImmutable so
work with DateTimeImmutable
public function __construct($client_birthdate = '')
public function getClient_birthdate() : ?DateTimeImmutable
{
if (isset($this->client_birthdate) && !empty($this->client_birthdate)){
return $this->client_birthdate;
}
if (empty($this->client_birthdate)){
return $this->client_birthdate = null;
}
}
public function setClient_birthdate(?\DateTime $client_birthdate): void
{
$this->client_birthdate = $client_birthdate;
}
客户端/ClientForm.php
declare(strict_types=1);
namespace App\Invoice\Client;
use Yiisoft\Form\FormModel;
use Yiisoft\Validator\Rule\Required;
use \DateTimeImmutable;
use \DateTime;
final class ClientForm extends FormModel {
private ?string $client_birthdate = null;
public function getClient_birthdate(): ?\DateTime
{
if (isset($this->client_birthdate) && !empty($this->client_birthdate)){
return new DateTime($this->client_birthdate);
}
if (empty($this->client_birthdate)){
return $this->client_birthdate = null;
}
}
客户端/客户端服务
<?php
declare(strict_types=1);
namespace App\Invoice\Client;
use App\Invoice\Entity\Client;
use App\User\User;
final class ClientService
{
private ClientRepository $repository;
public function __construct(ClientRepository $repository)
{
$this->repository = $repository;;
}
public function saveClient(User $user, Client $model, ClientForm $form): void
{
$model->setClient_birthdate($form->getClient_birthdate());
注意事项:
提示
use \DateTime;
。不要忘记反斜杠来指示 DateTime 是一个不在当前命名空间中的 php 类。* @Column(type="date", nullable=true)
否则Cycle将无法读取它。.../Entity/Client.php
public function getClient_birthdate() : ?\DateTimeImmutable
和
public function setClient_birthdate(?\DateTime $client_birthdate): void
...src/Invoice/Entity/Client.php...
/**
* @Column(type="date", nullable=true)
*/
private $client_birthdate = '';
private ?string $client_birthdate = null
不是日期时间函数。...src/Invoice/Client/ClientForm.php
public function getClient_birthdate(): ?\DateTime
{
if (isset($this->client_birthdate) && !empty($this->client_birthdate)){
return new DateTime($this->client_birthdate);
}
if (empty($this->client_birthdate)){
return $this->client_birthdate = null;
}
}
上面的代码可以简化为:
public function getClient_birthdate() : ?\DateTime
{
// convert the input string on the form received by means of '$this->client_birthdate'
// back into DateTime so that Cycle can deal with it and
// save it in 'date' format in mysql behind the scenes
return new DateTime($this->client_birthdate);
}
本质上,要在表单上表示 DateTimeImmutable,必须使用 ->format() 命令来呈现。合适的日期样式必须位于括号之间,例如。 Y-m-d 甚至 d-m-Y。为了实现这一点,可以使用额外的代码,例如。
__form.php
<div class="mb-3 form-group has-feedback">
<?php
$bdate = $datehelper->get_or_set_with_style($body['client_birthdate']);
?>
<label form-label for="client_birthdate"><?= $s->trans('birthdate') .' ('.$datehelper->display().')'; ?></label>
<div class="input-group">
<input type="text" name="client_birthdate" id="client_birthdate" placeholder="<?= ' ('.$datehelper->display().')';?>"
class="form-control input-sm datepicker" readonly
value="<?= null!== $bdate ? Html::encode($bdate instanceof \DateTimeImmutable ? $bdate->format($datehelper->style()) : $bdate) : null; ?>" role="presentation" autocomplete="off">
<span class="input-group-text">
<i class="fa fa-calendar fa-fw"></i>
</span>
</div>
</div>
<?php
// https://api.jqueryui.com/datepicker
$js1 = "$(function () {".
'$(".form-control.input-sm.datepicker").datepicker({dateFormat:"'.$datehelper->datepicker_dateFormat()
.'", firstDay:'.$datehelper->datepicker_firstDay()
.', changeMonth: true'
.', changeYear: true'
.', yearRange: "-50:+10"'
.', clickInput: true'
.', constrainInput: false'
.', highlightWeek: true'
.' });'.
'});';
echo Html::script($js1)->type('module');
?>
2024 年 3 月 13 日更新 客户端实体client.php
<?php
declare(strict_types=1);
namespace App\Invoice\Entity;
use Cycle\Annotated\Annotation\Column;
use Cycle\Annotated\Annotation\Entity;
use Cycle\ORM\Entity\Behavior;
use \DateTime;
use \DateTimeImmutable;
#[Entity(repository:\App\Invoice\Client\ClientRepository::class)]
#[Behavior\CreatedAt(field: 'client_date_created', column: 'client_date_created')]
#[Behavior\UpdatedAt(field: 'client_date_modified', column: 'client_date_modified')]
class Client
{
#[Column(type: 'primary')]
public ?int $id = null;
#[Column(type: 'datetime')]
private DateTimeImmutable $client_date_created;
#[Column(type: 'datetime')]
private DateTimeImmutable $client_date_modified;
#[Column(type:'date', nullable: true)]
private mixed $client_birthdate;
public function __construct(
// treat as firstname
mixed $client_birthdate=null,
{
$this->client_birthdate = $client_birthdate;
$this->client_date_created = new \DateTimeImmutable();
$this->client_date_modified = new \DateTimeImmutable();
}
public function getClient_id(): ?int
{
return $this->id;
}
public function getClient_date_created(): DateTimeImmutable
{
/** @var DateTimeImmutable $this->client_date_created */
return $this->client_date_created;
}
public function getClient_date_modified(): DateTimeImmutable
{
/** @var DateTimeImmutable $this->client_date_created */
return $this->client_date_modified;
}
//cycle
public function getClient_birthdate() : DateTimeImmutable|string|null
{
/** @var DateTimeImmutable|string|null $this->client_birthdate */
return $this->client_birthdate;
}
public function setClient_birthdate(?DateTime $client_birthdate): void
{
$this->client_birthdate = $client_birthdate;
}
}
表单.php
<?php
declare(strict_types=1);
namespace App\Invoice\Client;
use App\Invoice\Entity\Client;
use Yiisoft\FormModel\FormModel;
use Yiisoft\Validator\Rule\Required;
use Yiisoft\Validator\Rule\Integer;
use \DateTimeImmutable;
final class ClientForm extends FormModel
{
private mixed $client_birthdate;
public function __construct(Client $client) {
$this->client_birthdate = $client->getClient_birthdate();
}
public function getClient_birthdate() : string|null|DateTimeImmutable
{
/**
* @var string|null|DateTimeImmutable $this->client_birthdate
*/
return $this->client_birthdate;
}
/**
* @return string
*
* @psalm-return ''
*/
public function getFormName(): string
{
return '';
}
}
<?php
declare(strict_types=1);
namespace App\Invoice\Client;
use App\Invoice\Entity\Client;
use App\Invoice\Helpers\DateHelper;
use App\Invoice\Setting\SettingRepository;
final class ClientService
{
private ClientRepository $repository;
public function __construct(ClientRepository $repository)
{
$this->repository = $repository;
}
/**
*
* @param Client $model
* @param array $body
* @param SettingRepository $s
* @return int|null
*/
public function saveClient(Client $model, array $body, SettingRepository $s): int|null
{
$datehelper = new DateHelper($s);
$datetime = new \DateTime();
isset($body['client_birthdate']) ? $model->setClient_birthdate($datetime::createFromFormat($datehelper->style(),(string)$body['client_birthdate'])) : '';
$this->repository->save($model);
return $model->getClient_id();
}
}
form.php
<?php
declare(strict_types=1);
use Yiisoft\FormModel\Field;
use Yiisoft\Html\Html;
use Yiisoft\Html\Tag\Form;
use Yiisoft\Arrays\ArrayHelper;
/**
* @var \Yiisoft\View\View $this
* @var \Yiisoft\Router\UrlGeneratorInterface $urlGenerator
* @var string $csrf
* @var string $action
* @var string $title
*/
?>
<?= Html::openTag('div',['class'=>'container py-5 h-100']); ?>
<?= Html::openTag('div',['class'=>'row d-flex justify-content-center align-items-center h-100']); ?>
<?= Html::openTag('div',['class'=>'col-12 col-md-8 col-lg-6 col-xl-8']); ?>
<?= Html::openTag('div',['class'=>'card border border-dark shadow-2-strong rounded-3']); ?>
<?= Html::openTag('div',['class'=>'card-header']); ?>
<?= Html::openTag('h1',['class'=>'fw-normal h3 text-center']); ?>
<?= $translator->translate('i.client_form'); ?>
<?= Html::closeTag('h1'); ?>
<?=
Form::tag()
->post($urlGenerator->generate(...$action))
->enctypeMultipartFormData()
->csrf($csrf)
->id('ClientForm')
->open()
?>
<?=
$alert;
?>
<?= Field::errorSummary($form)
->errors($errors)
->header($translator->translate('invoice.client.error.summary'))
->onlyProperties(...['client_name', 'client_surname', 'client_email', 'client_age'])
->onlyCommonErrors()
?>
<?=
Html::openTag('div', ['class'=> 'card']),
Html::openTag('div', ['class'=>'card-header d-flex justify-content-between']),
$translator->translate('i.personal_information'),
Html::openTag('div', ['class' => 'p-2']),
Field::checkbox($form, 'client_active')
->inputLabelAttributes(['class' => 'form-check-label'])
->enclosedByLabel(true)
->inputClass('form-check-input')
->ariaDescribedBy($translator->translate('i.client_active')),
Html::closeTag('div'),
Html::closeTag('div'),
Html::closeTag('div')
?>
<?php
$bdate = $datehelper->get_or_set_with_style($form->getClient_birthdate() ?? new \DateTimeImmutable('now'));
echo Field::text($form, 'client_birthdate')
->label($translator->translate('i.birthdate'), ['class' => 'form-label'])
->addInputAttributes([
'placeholder' => $translator->translate('i.birthdate'),
'class' => 'form-control input-sm datepicker',
'id' => 'client_birthdate',
'role' => 'presentation',
'autocomplete' => 'off'
])
->value($bdate)
->required(false)
->readonly(true)
->hint($translator->translate('invoice.hint.this.field.is.not.required'));
?>
<?= Html::closeTag('div'); ?>
<?= Html::closeTag('div'); ?>
<?= Html::closeTag('div'); ?>
<?= Html::closeTag('div'); ?>
<?php endif; ?>
<?= Html::closeTag('div'); ?>
<?= Html::closeTag('div'); ?>
<?= Html::closeTag('div'); ?>
<?= $button::back_save(); ?>
<?= Form::tag()->close(); ?>
<?= Html::closeTag('div'); ?>
<?= Html::closeTag('div'); ?>
<?= Html::closeTag('div'); ?>
<?= Html::closeTag('div'); ?>
<?= Html::closeTag('div'); ?>
发票平面解决方案
发生数据库错误 错误号:1525 不正确的日期值:'0000-00-00'修复错误 58 El error se debe al modo sql, que puede ser un modo estricto
解决方案永久为错误的日期值:'0000-00-00'更改此数据示例> 1970-01-01
发票平面/应用程序/模块/发票/模型/Mdl_invoices.php
或临时解决方案 mysql SET GLOBAL sql_mode = '';
ubuntu 20.04 mysql 8