date auto getter in Entity ignore my date format - tomasoma - 09-18-2020
Hello,
I just followed the documentation about the Entity getCreatedAt() function (on this page https://codeigniter4.github.io/userguide/models/entities.html#handling-business-logic) but it don't understand why the date format i set is ignored :
Model :
PHP Code: <?php namespace App\Models ;
use CodeIgniter\Model ;
class UserModel extends Model {
protected $table = 'user'; protected $primaryKey = 'id'; protected $returnType = 'App\Entities\User'; protected $useSoftDeletes = true ; protected $allowedFields = ['email','password','level','civilite','prenom','nom','sign','tel','add1','add2','cp','ville','pays'] ; protected $dateFormat = 'int' ; protected $useTimestamps = true ; protected $createdField = 'created_at' ; protected $updatedField = 'updated_at' ; protected $deletedField = 'deleted_at' ; protected $validationRules = [] ; protected $validationMessages = [] ; protected $skipValidation = false ;
}
Entity :
PHP Code: <?php namespace App\Entities ;
use CodeIgniter\Entity ; use CodeIgniter\I18n\Time;
class User extends Entity { protected $attributes = [ 'id' => null , 'email' => null , 'password' => null , 'level' => null , 'civilite' => null , 'prenom' => null , 'nom' => null , 'sign' => null , 'tel' => null , 'add1' => null , 'add2' => null , 'cp' => null , 'ville' => null , 'pays' => null , 'created_at' => null , 'updated_at' => null , 'deleted_at' => null ] ;
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
public function identite(){ return trim($this->civilite.' '.ucwords($this->prenom)).' '.strtoUpper($this->nom) ; } # /identite()
public function adresse() { $t = $this->add1 ; if(trim($this->add2) != '') $t .= '<br >/'.$this->add2 ; $t .= '<br />'.$this->cp.' '.strtoupper($this->ville) ; if(trim(strtolower($this->pays)) != 'france') $t .= '<br />'.$this->pays ; return $t ; } # /adresse()
public function getCreatedAt(string $format = 'd/m/Y H:i:s') { $this->attributes['created_at'] = $this->mutateDate($this->attributes['created_at']) ; $timezone = $this->timezone ?? app_timezone() ; $this->attributes['created_at']->setTimezone($timezone) ; return $this->attributes['created_at']->format($format) ; } # /getCreatedAt()
public function getUpdatedAt(string $format = 'd/m/Y H:i:s') { $this->attributes['updated_at'] = $this->mutateDate($this->attributes['updated_at']) ; $timezone = $this->timezone ?? app_timezone() ; $this->attributes['updated_at']->setTimezone($timezone) ; return $this->attributes['updated_at']->format($format) ; } # /getUpdatedAt
public function getDeletedAt(string $format = 'd/m/Y H:i:s') { if($this->attributes['deleted_at'] == null) return false ; $this->attributes['deleted_at'] = $this->mutateDate($this->attributes['deleted_at']) ; $timezone = $this->timezone ?? app_timezone() ; $this->attributes['deleted_at']->setTimezone($timezone) ; return $this->attributes['deleted_at']->format($format) ; } # /getDeletedAt
}
Controller :
PHP Code: <?php namespace App\Controllers;
class Home extends BaseController { public function index() {
$vars = [ 'tac' => 'blabla' ] ; return view('welcome_message',$vars); }
public function test() { $dom_id = random_string('alpha',13) ;
$config = config('Config\Database') ;
$content = '' ;
$user_model = model('App\Models\UserModel') ; $users = $user_model->findAll() ;
if($users) { $table = new \CodeIgniter\View\Table() ; $table->setTemplate(['table_open' => '<table class="table table-hover table-striped">']) ; $table->setHeading(['id','email','level','identite','adresse','tel','created_at','updated_at','deleted_at']) ; foreach($users as $user){ $table->addRow([ $user->id , $user->email , $user->level , $user->identite() , $user->adresse() , $user->tel , $user->created_at , $user->updated_at , $user->deleted_at ]) ; } $content .= $table->generate() ; } else $content .= wrap('Aucun user trouvé par le findAll',['balise' => 'code']) ;
$vars = [ 'title' => 'MON BLABLA '.__CLASS__.'::'.__FUNCTION__ , 'content' => wrap($content ,['id' => $dom_id]) ] ; $params = (object)[ 'dom_id' => $dom_id ] ;
$this->scripts->addPath(base_url('boot/not_compiled/home-test-0.0.1.js')) ; $this->scripts->init('home_test',$params) ; return $this->html($vars) ; }
}
and in the HTML table, the dates created_at and updated_at still display in the 'Y-d-m H:i:s' format.
Where did I make a mistake ?
RE: date auto getter in Entity ignore my date format - InsiteFX - 09-18-2020
You need to add them to the models allow fields array.
PHP Code: $allowedFields = ['created_at', 'updated_at'] // etc;
RE: date auto getter in Entity ignore my date format - tomasoma - 09-18-2020
(09-18-2020, 01:04 AM)InsiteFX Wrote: You need to add them to the models allow fields array.
PHP Code: $allowedFields = ['created_at', 'updated_at'] // etc;
Thanks for trying but It doesn't change anything.
I added a log_message() to check if my own function was called and it is, with or without the add in the allowedFields array.
PHP Code: public function getCreatedAt(string $format = 'd/m/Y H:i:s') { $this->attributes['created_at'] = $this->mutateDate($this->attributes['created_at']) ; $timezone = $this->timezone ?? app_timezone() ; $this->attributes['created_at']->setTimezone($timezone) ; log_message('error',__CLASS__.'::'.__FUNCTION__.'() l:'.__LINE__. ' I’m done') ; return $this->attributes['created_at']->format($format) ; } # /getCreatedAt()
I also change the return line with the string format :
PHP Code: return $this->attributes['created_at']->format('d/m/Y H:i:s') ;
and it still doesn't work
but when i include a mistake in the date format string :
PHP Code: return $this->attributes['created_at']->format('d/m/Y H:i:xs') ;
then Exception error ...
so I'm trying to find this native ...->format() function to understand why it 'partially' ignore the argument....
From the logs of the error generated by the 'mistake' in the date format, it looks like my own getCreatedAt() is called and then overridden by ??? the default one ???
Code: CRITICAL - 2020-09-18 11:01:00 --> DateTime::__construct(): Failed to parse time string (12:/04/1981 01:15:00) at position 0 (1): Unexpected character
#0 /var/www/clients/client0/common-libraries/codeigniter.versions/framework-4.0.4/system/I18n/Time.php(138): DateTime->__construct('12:/04/1981 01:...', Object(DateTimeZone))
#1 /var/www/clients/client0/common-libraries/codeigniter.versions/framework-4.0.4/system/I18n/Time.php(174): CodeIgniter\I18n\Time->__construct('12:/04/1981 01:...', 'Europe/Berlin', NULL)
#2 /var/www/clients/client0/common-libraries/codeigniter.versions/framework-4.0.4/system/Entity.php(500): CodeIgniter\I18n\Time::parse('12:/04/1981 01:...')
#3 /var/www/clients/client0/common-libraries/codeigniter.versions/framework-4.0.4/system/Entity.php(301): CodeIgniter\Entity->mutateDate('12:/04/1981 01:...')
#4 /var/www/clients/client0/web22/private/app/Controllers/Home.php(59): CodeIgniter\Entity->__get('created_at')
#5 /var/www/clients/client0/common-libraries/codeigniter.versions/framework-4.0.4/system/CodeIgniter.php(918): App\Controllers\Home->test()
#6 /var/www/clients/client0/common-libraries/codeigniter.versions/framework-4.0.4/system/CodeIgniter.php(404): CodeIgniter\CodeIgniter->runController(Object(App\Controllers\Home))
#7 /var/www/clients/client0/common-libraries/codeigniter.versions/framework-4.0.4/system/CodeIgniter.php(312): CodeIgniter\CodeIgniter->handleRequest(NULL, Object(Config\Cache), false)
#8 /var/www/clients/client0/web22/web/index.php(45): CodeIgniter\CodeIgniter->run()
#9 {main}
when i call
it works fine, but I think it was what the "auto getter" was done to avoid .?.?.
So I checked the System/Entity->__get() :
PHP Code: public function __get(string $key) { $key = $this->mapProperty($key); $result = null; // Convert to CamelCase for the method $method = 'get' . str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $key)));
// if a set* method exists for this key, // use that method to insert this value. if (method_exists($this, $method)) { $result = $this->$method(); } // Otherwise return the protected property // if it exists. else if (array_key_exists($key, $this->attributes)) { $result = $this->attributes[$key]; } // Do we need to mutate this into a date? if (in_array($key, $this->dates)) { $result = $this->mutateDate($result); } // Or cast it as something? else if ($this->_cast && ! empty($this->casts[$key])) { $result = $this->castAs($result, $this->casts[$key]); } return $result; }
it calls my method and then if the $key is in the $date array it mutates my result into a date one more time.
So I removed my $date array
PHP Code: // protected $dates = ['created_at', 'updated_at', 'deleted_at'];
... still doesn't work
So I empty my date array :
WOOOW ok finally .... I got my result !!!!
So I guess that the $useTimestamps automatically fills the $date array with the $createdField , $updatedField and the $deletedFields.
Solved.
CI4 is great but its documentation is not yet.
RE: date auto getter in Entity ignore my date format - tomasoma - 09-18-2020
Perhaps it is a dumb newbie ideas but i dare :
Wouldn't that be more logic to check the method at the end of the __get() so if it is a date it would be already mutated ?
Or to directly return the result of the method if there is a method ?
From the comment i guess the __get() has been written after the __set() method and perhaps the execution logic order has not been inverted ?
RE: date auto getter in Entity ignore my date format - nicojmb - 09-18-2020
hi, i try to do the same but does't work, can you share you working code?
Regards!
RE: date auto getter in Entity ignore my date format - InsiteFX - 09-18-2020
(09-18-2020, 11:06 AM)nicojmb Wrote: hi, i try to do the same but does't work, can you share you working code?
Regards!
PHP Code: The $useTimestamps automatically fills the $date array with the $createdField , $updatedField and the $deletedFields.
So set this to true.
PHP Code: /** * If true, will set created_at, and updated_at * values during insert and update routines. * * @var boolean */ protected $useTimestamps = false;
RE: date auto getter in Entity ignore my date format - nicojmb - 09-18-2020
(09-18-2020, 01:10 PM)InsiteFX Wrote: (09-18-2020, 11:06 AM)nicojmb Wrote: hi, i try to do the same but does't work, can you share you working code?
Regards!
PHP Code: The $useTimestamps automatically fills the $date array with the $createdField , $updatedField and the $deletedFields.
So set this to true.
PHP Code: /** * If true, will set created_at, and updated_at * values during insert and update routines. * * @var boolean */ protected $useTimestamps = false;
Not work, i use custom model extended from MyTh.
I have tried everything, $useTimestamps to "true", $useTimestamps to "false", with $dates array, etc...
PHP Code: namespace App\Models;
use Myth\Auth\Models\UserModel as BaseModel;
class UserModel extends BaseModel {
protected $dates = [];
protected $returnType = \App\Entities\User::class;
protected $useTimestamps = true; }
PHP Code: namespace App\Entities;
use \Myth\Auth\Entities\User as BaseEntity; use CodeIgniter\I18n\Time;
class User extends BaseEntity {
public function getUpdatedAt(string $format = 'd/m/y H:i') { $this->attributes['updated_at'] = $this->mutateDate($this->attributes['updated_at']);
$timezone = $this->timezone ?? app_timezone();
$this->attributes['updated_at']->setTimezone($timezone);
return $this->attributes['updated_at']->format($format); }
public function getCreatedAt(string $format = 'd/m/y H:i') { $this->attributes['created_at'] = $this->mutateDate($this->attributes['created_at']);
$timezone = $this->timezone ?? app_timezone();
$this->attributes['created_at']->setTimezone($timezone);
return $this->attributes['created_at']->format($format); } }
PHP Code: "title": "Exception", "type": "Exception", "code": 500, "message": "DateTime::__construct(): Failed to parse time string (15/09/2020 17:43:11) at position 0 (1): Unexpected character", "file": "/var/www/vhosts/nicojmb.com/yani.nicojmb.com/vendor/codeigniter4/framework/system/I18n/Time.php", "line": 138,
RE: date auto getter in Entity ignore my date format - InsiteFX - 09-18-2020
It creates the datetime on its own, if you want it different then you need to create your custom table field using an integer type.
RE: date auto getter in Entity ignore my date format - tomasoma - 09-21-2020
Ok sorry for the delay here is my working code :
Model :
PHP Code: <?php namespace App\Models ;
use CodeIgniter\Model ;
class UserModel extends Model {
protected $table = 'user'; protected $primaryKey = 'id'; protected $returnType = 'App\Entities\User'; protected $useSoftDeletes = true ; protected $allowedFields = ['email','password','level','civilite','prenom','nom','sign','tel','add1','add2','cp','ville','pays'] ; protected $dateFormat = 'int' ; protected $useTimestamps = true ; protected $createdField = 'created_at' ; protected $updatedField = 'updated_at' ; protected $deletedField = 'deleted_at' ; protected $validationRules = [] ; protected $validationMessages = [] ; protected $skipValidation = false ;
}
Controller :
PHP Code: <?php namespace App\Controllers;
class Users extends BaseController {
private $UM ; # pour le user model pas être obligé de le rappeler à chaque fonction
/***************************************************** __construct *****************************************************/ public function __construct(){ $this->UM = model('App\Models\UserModel') ; }
/***************************************************** index *****************************************************/ public function index(){ $vars = [ 'dom_id' => random_string('alpha',13) , 'table' => '' , 'pagination' => '' ] ; $users = $this->UM->findAll() ; if($users) { $table = new \CodeIgniter\View\Table() ; $table->setTemplate(['table_open' => '<table class="table table-hover table-striped">']) ; $table->setHeading(['','id','email','level','identite','adresse','tel','created_at','updated_at','deleted_at']) ; foreach($users as $user){ $table->addRow([ wrap( admin_show_btn('users',$user->id) .admin_edit_btn('users',$user->id) .admin_supprim_btn('users',$user->id) ,['class' => 'btn-group btn-group-sm'] ) , $user->id , $user->email , $user->level , $user->identite() , $user->adresse() , $user->tel , $user->created_at , $user->updated_at , $user->deleted_at ]) ; } $vars['table'] = $table->generate() ; } else $vars['table'] = alert('warning','Aucun utilisateur trouvé') ;
return $this->tpl('users/index',$vars,'content') ->set_var('title',__CLASS__.'::'.__FUNCTION__) ->html() ; } # /index
Entity :
PHP Code: <?php namespace App\Entities ;
use CodeIgniter\Entity ; use CodeIgniter\I18n\Time;
class User extends Entity { protected $attributes = [ 'id' => null , 'email' => null , 'password' => null , 'level' => null , 'civilite' => null , 'prenom' => null , 'nom' => null , 'sign' => null , 'tel' => null , 'add1' => null , 'add2' => null , 'cp' => null , 'ville' => null , 'pays' => null , 'created_at' => null , 'updated_at' => null , 'deleted_at' => null ] ;
protected $dates = [] ; # !! declare a empty array
public function identite(){ return trim($this->civilite.' '.ucwords($this->prenom)).' '.strtoUpper($this->nom) ; } # /identite()
public function adresse() { $t = $this->add1 ; if(trim($this->add2) != '') $t .= '<br >/'.$this->add2 ; $t .= '<br />'.$this->cp.' '.strtoupper($this->ville) ; if(trim(strtolower($this->pays)) != 'france') $t .= '<br />'.$this->pays ; return $t ; } # /adresse()
public function getCreatedAt(string $format = 'd/m/Y H:i:s') { $this->attributes['created_at'] = $this->mutateDate($this->attributes['created_at']) ; $timezone = $this->timezone ?? app_timezone() ; $this->attributes['created_at']->setTimezone($timezone) ; log_message('error',__CLASS__.'::'.__FUNCTION__.'() l:'.__LINE__. ' I’m done') ; return $this->attributes['created_at']->format($format) ; } # /getCreatedAt()
public function getUpdatedAt(string $format = 'd/m/Y H:i:s') { $this->attributes['updated_at'] = $this->mutateDate($this->attributes['updated_at']) ; $timezone = $this->timezone ?? app_timezone() ; $this->attributes['updated_at']->setTimezone($timezone) ; return $this->attributes['updated_at']->format($format) ; } # /getUpdatedAt
public function getDeletedAt(string $format = 'd/m/Y H:i:s') { if($this->attributes['deleted_at'] == null) return false ; $this->attributes['deleted_at'] = $this->mutateDate($this->attributes['deleted_at']) ; $timezone = $this->timezone ?? app_timezone() ; $this->attributes['deleted_at']->setTimezone($timezone) ; return $this->attributes['deleted_at']->format($format) ; } # /getDeletedAt
} # EOC Entity\User
(09-18-2020, 01:27 PM)nicojmb Wrote: (09-18-2020, 01:10 PM)InsiteFX Wrote: (09-18-2020, 11:06 AM)nicojmb Wrote: hi, i try to do the same but does't work, can you share you working code?
Regards!
PHP Code: The $useTimestamps automatically fills the $date array with the $createdField , $updatedField and the $deletedFields.
So set this to true.
PHP Code: /** * If true, will set created_at, and updated_at * values during insert and update routines. * * @var boolean */ protected $useTimestamps = false;
Not work, i use custom model extended from MyTh.
I have tried everything, $useTimestamps to "true", $useTimestamps to "false", with $dates array, etc...
PHP Code: namespace App\Models;
use Myth\Auth\Models\UserModel as BaseModel;
class UserModel extends BaseModel {
protected $dates = [];
protected $returnType = \App\Entities\User::class;
protected $useTimestamps = true; }
It is not in the model that you declare $date array empty, it is in the Entity class
It works for display but i didn't get further yet, I hope that the empty $date array will not prevent from CI to automatically update the value at creation, update and delete action as it is supposed to do ... I'll check it when I write my create,edit,delete function in my controller...
I think our problem is more from the __get() function of the system Entity class ... but noone reply on this point.
Sorry for the delay, I'm busy on many projects and I'm just working on CI4 when I have time to learn how to deal with it for the futur.
RE: date auto getter in Entity ignore my date format - nicojmb - 09-23-2020
Yes, i can confirm that empty $date array the display is correct.
|