Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Entities errors #1727

Closed
keulu-ing opened this issue Feb 16, 2019 · 6 comments
Closed

Entities errors #1727

keulu-ing opened this issue Feb 16, 2019 · 6 comments

Comments

@keulu-ing
Copy link

keulu-ing commented Feb 16, 2019


name: Bug report
about: Help us improve the framework by reporting bugs!


Describe the bug
Entities Getter & Setter not set automatically

CodeIgniter 4 version
alpha-5

Affected module(s)
Model / Entities

Expected behavior, and steps to reproduce if appropriate
i'd folow this example : https://codeigniter4.github.io/CodeIgniter4/models/entities.html#handling-business-logic.

2 things :

  • created_at, updated_at, deleted_at are not cast to Date Object
  • call $userEntity->getCreatedAt(); and i got an error about $this->timezone;

see screenshot
capture du 2019-02-16 14-27-58

cheers :)

Context

  • OS: linux mint debian edition 2
  • Web server : nginx
  • PHP version : php7.1
@keulu-ing
Copy link
Author

keulu-ing commented Feb 16, 2019

and the complete $_options don't seems to work.

protected $_options = [
        'datamap' => [
            'full_name' => 'username' // nothing desplayed about that
        ],
        'dates' => ['created_at', 'updated_at', 'deleted_at'], //dates are not casted to DateTime
        'casts' => [
            'deleted' => 'boolean' // deleted is still "0" and not false
        ],
    ];

@lonnieezell
Copy link
Member

Please show all relevant code to show how we can replicate it working without going through an entire tutorial.

@keulu-ing
Copy link
Author

keulu-ing commented Feb 17, 2019

here is my complete 1st REST test

*** Controller/Users.php ***

<?php
namespace App\Controllers;

use CodeIgniter\Controller;
use CodeIgniter\API\ResponseTrait;

use Restserver\Libraries\Format;

use App\Models\UserModel;
use App\Entities\User;

class Users extends Controller
{

    /**
     * Entry point for users listing
     */
    public function index()
    {
        $userModel = new UserModel();
        $users = $userModel->findAll();

        $data = [
            'success' => true,
            'message' => '',
            'data' => $users,
        ];

        return $this->response->setStatusCode(Format::HTTP_OK)->setJSON($data);
    }

    /**
     * Entry point for specific user
     */
    public function show($id)
    {
        $userModel = new UserModel();
        $user = $userModel->find($id);

        if ($user){
            $data = [
                'success' => true,
                'message' => '',
                'data' => $user,
            ];

            return $this->response->setStatusCode(Format::HTTP_OK)->setJSON($data);
        }else{
            $data = [
                'success' => false,
                'message' => 'user_not_found',
                'data' => []
            ];

            return $this->response->setStatusCode(Format::HTTP_NOT_FOUND)->setJSON($data);
        }

    }

    /**
     * Entry point for user creation
     */
    public function create()
    {
        $data = $this->request->getPost();

        // var_dump($data);die;

        $userModel = new UserModel();
        $userEntity = new User();

        if ($userEntity->fill($data)){
            if ($userModel->save($userEntity) !== false){

                $data = [
                    'success' => true,
                    'message' => 'resources_created',
                    'data' => [],
                ];

                return $this->response->setStatusCode(Format::HTTP_CREATED)->setJSON($data);
            }else{
                $data = [
                    'success' => false,
                    'message' => 'resources_not_created',
                    'data' => $userModel->errors(),
                ];

                return $this->response->setStatusCode(Format::HTTP_NOT_ACCEPTABLE)->setJSON($data);
            }
        }else{
            $data = [
                'success' => false,
                'message' => 'resource_dont_match',
                'data' => [],
            ];

            return $this->response->setStatusCode(Format::HTTP_BAD_REQUEST)->setJSON($data);
        }

    }

    /**
     * Entry point for user update
     */
    public function update($id)
    {
        $data = $this->request->getRawInput();

        $userModel = new UserModel();
        $userEntity = new User();

        if ($userEntity->fill($data)){

            if ($userModel->save($userEntity) !== false){
                $data = [
                    'success' => true,
                    'message' => 'resources_updated',
                    'data' => ['id' => $id],
                ];

                return $this->response->setStatusCode(Format::HTTP_OK)->setJSON($data);
            }else{
                $data = [
                    'success' => false,
                    'message' => 'resource_not_updated',
                    'data' => $userModel->errors(),
                ];

                return $this->response->setStatusCode(Format::HTTP_NOT_ACCEPTABLE)->setJSON($data);
            }
        }else{
            $data = [
                'success' => false,
                'message' => 'resource_dont_match',
                'data' => [],
            ];

            return $this->response->setStatusCode(Format::HTTP_BAD_REQUEST)->setJSON($data);
        }
    }

    /**
     * Entry point for user delete
     */
    public function delete($id)
    {
        $userModel = new UserModel();

        if ($userModel->delete($id) !== false){
            $data = [
                'success' => true,
                'message' => 'resources_deleted',
                'data' => ['id' => $id],
            ];

            return $this->response->setStatusCode(Format::HTTP_OK)->setJSON($data);
        }else{
            $data = [
                'success' => false,
                'message' => 'resource_not_deleted',
                'data' => [],
            ];

            return $this->response->setStatusCode(Format::HTTP_NOT_ACCEPTABLE)->setJSON($data);
        }
    }


    //--------------------------------------------------------------------
    // End of file Users.php
    //--------------------------------------------------------------------
}

*** Models/UserModel.php ***

<?php namespace App\Models;

use CodeIgniter\Model;

class UserModel extends Model
{

    /**
     * Model Configuration
     */
    protected $table      = 'users';
    protected $primaryKey = 'id';
    protected $returnType = '\App\Entities\User';
    protected $allowedFields = ['firstname', 'lastname', 'username', 'email', 'password'];

    protected $useSoftDeletes = true;
    protected $dateFormat = 'datetime';
    protected $useTimestamps = true;

    protected $skipValidation     = false;
    protected $validationRules    = [
        'firstname'    => 'required|min_length[3]',
        'lastname'     => 'required|min_length[3]',
        'username'     => 'required|alpha_numeric_space|min_length[3]',
        'email'        => 'required|valid_email|is_unique[users.email,id,{$id}]',
        'password'     => 'required|min_length[8]',
        // 'password_confirm' => 'required_with[password]|matches[password]'
        // 'password_confirm' => 'matches[password]'
    ];

    protected $validationMessages = [
        'email'        => [
            'is_unique' => 'Sorry. That email has already been taken. Please choose another.'
        ]
    ];

    protected $afterDelete = ['updateDeletedAt'];


    /**
     * Protected & internals methods
     */

    protected function updateDeletedAt(array $data)
    {
        if (! isset($data['id']) ) return $data;

        $this->builder()
            ->whereIn('id', $data['id'])
            ->set(['deleted_at' => date('Y-m-d H:i:s')])
            ->update();

        return $data;
    }
}

*** Entities/User.php ***

<?php namespace App\Entities;

use CodeIgniter\Entity;

class User extends Entity
{
    protected $id;
    public $firstname;
    public $lastname;
    public $username;
    public $email;
    protected $password;
    public $created_at;
    protected $updated_at;
    public $deleted;
    protected $deleted_at;

    protected $_options = [
        'datamap' => [
            'full_name' => 'username'
        ],
        'dates' => ['created_at', 'updated_at', 'deleted_at'],
        'casts' => [
            'deleted' => 'boolean'
        ],
    ];

    public function setPassword(string $pass)
    {
        $this->password = password_hash($pass, PASSWORD_BCRYPT);
        return $this;
    }

    public function setCreatedAt(string $dateString)
    {
        $this->created_at = new \DateTime($datetime, new \DateTimeZone('UTC'));
        return $this;
    }

    public function getCreatedAt(string $format = 'Y-m-d H:i:s')
    {
        $timezone = isset($this->timezone)
            ? $this->timezone
            : app_timezone();

        $this->created_at->setTimezone($timezone);

        return $this->created_at->format($format);
    }

}

*** Database/Migrations/Add_Users.php ***

<?php namespace App\Database\Migrations;

class Migration_Add_Users extends \CodeIgniter\Database\Migration
{
    private $attributes = [
        'ENGINE' => 'InnoDB',
        'CHARACTER SET' => 'utf8mb4',
        'COLLATE' => 'utf8mb4_general_ci',
    ];
    private $table_name = 'users';

    public function up()
    {
        $this->forge->addField([
            'id' => [
                'type'           => 'INT',
                'constraint'     => 11,
                'unsigned'       => true,
                'auto_increment' => true
            ],
            'firstname' => [
                'type'           => 'VARCHAR',
                'constraint'     => '127',
                'comment'        => 'Prénom de l\'utilisateur admin',
            ],
            'lastname' => [
                'type'           => 'VARCHAR',
                'constraint'     => '127',
                'comment'        => 'Nom de l\'utilisateur admin',
            ],
            'username' => [
                'type'           => 'VARCHAR',
                'constraint'     => '63',
                'comment'        => 'Pseudo de l\'utilisateur admin',
            ],
            'email' => [
                'type'           => 'VARCHAR',
                'constraint'     => '255',
                'comment'        => 'Email de l\'utilisateur admin',
            ],
            'password' => [
                'type'           => 'VARCHAR',
                'constraint'     => '31',
                'comment'        => 'Mot de passe de l\'utilisateur admin',
            ],
            'created_at' => [
                'type'           => 'DATETIME',
                'comment'        => 'Date de création du compte',
            ],
            'updated_at' => [
                'type'           => 'DATETIME',
                'null'           => true,
                'default'        => null,
                'comment'        => 'Date de modification du compte',
            ],
            'deleted' => [
                'type'           => 'TINYINT',
                'constraint'     => '1',
                'default'        => 0,
                'comment'        => 'Utilisateur supprimé ?',
            ],
            'deleted_at' => [
                'type'           => 'DATETIME',
                'null'           => true,
                'default'        => null,
                'comment'        => 'Date de suppression du compte',
            ]
        ]);
        $this->forge->addKey('id', true);
        $this->forge->createTable($this->table_name, true, $this->attributes);
    }

    public function down()
    {
        $this->forge->dropTable($this->table_name);
    }
}

*** Database/Seeds/UsersSeeder.php ***

<?php

use \CodeIgniter\Database\Seeder;

class UsersSeeder extends Seeder
{
    public $table = 'users';

    public function run()
    {
        $data = [
            [
                'firstname' => 'Darth',
                'lastname' => 'Vader',
                'username' => 'darth',
                'email' => 'darth@theempire.com',
                'password' => hash('sha256', 'password'),
                'created_at' => date('Y-m-d H:i:s')
            ],
            [
                'firstname' => 'Darth2',
                'lastname' => 'Vader2',
                'username' => 'darth2',
                'email' => 'darth2@theempire.com',
                'password' => hash('sha256', 'password2'),
                'created_at' => date('Y-m-d H:i:s')
            ]
        ];

        // Using Query Builder
        $this->db->table($this->table)->insertBatch($data);
    }
}

@bangbangda
Copy link
Contributor

bangbangda commented Feb 18, 2019

@keulu-ing

  • created_at, updated_at, deleted_at are not cast to Date Object

About this thing, cast to \CodeIgniter\I18n\Time Object is ok.

add code to show() method of Controller/Users.php file.
echo $user->created_at->humanize();

this returns a string that displays the difference between the times in a human readable format that is geared towards being easily understood.

@bangbangda
Copy link
Contributor

bangbangda commented Feb 18, 2019

  • call $userEntity->getCreatedAt(); and i got an error about $this->timezone;

About this thing, add code to getCreatedAt() method of Entities/User.php.
$this->created_at = $this->mutateDate($this->created_at);

1212

I tested is ok. a better solution makes me think about it.

@lonnieezell
Copy link
Member

@bangbangda Thanks for checking that out and providing fixes. I've updated the docs to reflect.

lonnieezell added a commit that referenced this issue Feb 19, 2019
Update entity docs for current framework state. Fixes #1727
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants