Symfony4 Serviceクラスを使用してみる ～CURD編～ 【3】

## CREATEを作成してみる

UserTypeの記述を行っていく。

```php:srv/Form/UserType.php
<?php

namespace App\Form;

use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;

class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('user_name', TextType::class, array(
                'label' => 'ユーザー名',
                'required' => true,
                //'max_length' => 3,
            ))
            ->add('password', RepeatedType::class, array(
                'type' => PasswordType::class,
                'required' => true,
                'invalid_message' => '再入力されたパスワードと一致しません。',
                'first_options'  => ['label' => 'パスワード'],
                'second_options' => ['label' => 'パスワード（確認） ※同じパスワードを入力してください'],
            ))
            ->add('email', EmailType::class, array(
                'label' => 'メールアドレス',
                'required' => true,
            ))
            ->add('age', IntegerType::class, array(
                'label' => '年齢',
                'required' => false,
            ))
            ->add('保存', SubmitType::class, array())
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => User::class,
        ]);
    }
}
```

UserServiceにメソッドの追記を行う
※ユーザーを作成するメソッドとエラー判定するメソッド

```php:src/Service/UserService.php
<?php

namespace App\Service;

use App\Service\CommonService;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

class UserService
{
    private $manager;

    public function __construct(EntityManagerInterface $manager)
    {
        $this->manager = $manager;
    }

    (省略)

    /**
     * ユーザーを作成するメソッド
     */
    public function createUser(User $user, object $form, UserPasswordEncoderInterface $passwordEncoder)
    {
        // 現在の日付取得
        $common_serivce = new CommonService;
        $date = $common_serivce->getDate();

        $user = $form->getData();
        $password = $passwordEncoder->encodePassword($user, $user->getPassword());
        $user->setPassword($password);
        $user->setRole('normal');
        $user->setIsActive(true);
        $user->setCreatedAt($date);
        $user->setUpdatedAt($date);

        $this->manager->persist($user);
        $this->manager->flush();
    }

    /**
     * エラーチェックのメソッド
     */
    public function checkUser(object $form)
    {
        if (!$form->isValid()) {
            return false;
        }

        return true;
        
    }
}
```

↓ 上記に伴い記述が必要なファイル

※パスワードが必要なので、security.yamlを変更する

```yaml:config/package/security.yaml
security:
    # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
    providers:
        our_db_provider:
            entity:
                class: App\Entity\User
                property: username

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            anonymous: ~
            pattern: ^/
            provider: our_db_provider

            form_login:
                login_path: login
                check_path: login
            logout:
                path:   logout
                target: login
                invalidate_session: false

            # activate different ways to authenticate
            # https://symfony.com/doc/current/security.html#firewalls-authentication

            # https://symfony.com/doc/current/security/impersonating_user.html
            # switch_user: true

    # Easy way to control access for large sections of your site
    # Note: Only the *first* access control that matches will be used
    access_control:
        - { path: ^/admin, roles: ROLE_ADMIN }
        # - { path: ^/profile, roles: ROLE_USER }

    encoders:
        App\Entity\User:
            algorithm: bcrypt
```

※CommonServiceを作成して、日付を取得するメソッド

```php:src/Service/CommonService.php
<?php

namespace App\Service;

class CommonService
{
    /**
     * 日付を取得するメソッド
     */
    public function getDate() {
        $utc_time = new \DateTime('@'.strtotime('now'));
        $timezone = new \DatetimeZone(timezone: "japan");
        $now_time_japan = $utc_time->setTimezone($timezone);

        return $now_time_japan;
    }
}
```

テンプレートを作成する

```php:templates/user/form.html.twig
{% extends 'base.html.twig' %}

{% block title %}Hello UserController!{% endblock %}

{% block body %}
<style>
    .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; }
    .example-wrapper code { background: #F5F5F5; padding: 2px 6px; }
</style>

<div class="example-wrapper">
    <h2>{{ title }}</h2>
    
    {{ form(form) }}
</div>
{% endblock %}
```

### 以下目次

|タイトル|URL|
|----|----|
|タイトルページ|https://qiita.com/RyotaIhara/items/6159bbc38a729293fde0|
|READを作成してみる|https://qiita.com/RyotaIhara/items/ec5a5dff9bf00de87af7|
|CREATEを作成してみる|https://qiita.com/RyotaIhara/items/54942b2122d05ed561b1|
|UPDATEを作成してみる|https://qiita.com/RyotaIhara/items/f1fd3c17d6fa5ef78d34|
|DELETEを作成してみる|https://qiita.com/RyotaIhara/items/f1fd3c17d6fa5ef78d34|