How can I prevent that every time at saving the created_time is overwritten?

163 views
Skip to first unread message

Nico van de Kamp

unread,
Nov 5, 2020, 3:40:27 PM11/5/20
to Joomla! General Development
Hello,

I have the issue that every time when I save the record the created_time is overwritten. But how can I prevent this?

I thought that I saw the trick but I understand that this is not solving the issue. But how than?

I have added the function check to the model file with this:
// instance varibles
    // new record defaults
    var $id             = 0;
    var $created_by     = 0;
    var $created_time   = '';
    var $modified_by    = 0;
    var $modified_time  = '';

public function check() {
       
// dates
        $this
->modified_by      = JFactory::getUser()->get('id');
        $this
->modified_time    = JFactory::getDate()->toSql();
       
if (empty($this->created_by)) {
            $this
->created_by   = $this->modified_by;
            $this
->created_time = $this->modified_time;
       
}

       
return parent::check();
   
}

But offcourse the instance variable
$this->created_by

is empty, so that will be overwritten, at least it does not have the database value when the record is created. How is that realized normally in Joomla. I have been looking in article but I didn't see the trick, sorry.

One remark, I have written my own save function in the controller which is saving the record with:
if (!(parent::save($data))) {
   
return false;
}

which saving the parent record. I have written in the $model->save() also that a child table records are saved. But the issue is with parent table!

But the issue is with parent table!

Roger Creagh

unread,
Nov 8, 2020, 3:18:39 AM11/8/20
to joomla-de...@googlegroups.com
On Thu, 2020-11-05 at 12:40 -0800, Nico van de Kamp wrote:
I have the issue that every time when I save the record the created_time is overwritten. But how can I prevent this?

Sorry Nico, I am confused by your question and what you are trying to achieve. 

Normally created (datetime) and created_by (user id) default to the current time and user when you save a new record. You can arrange to allow the user to overwrite them by including them in the form (see the com_content article for example). Once they are set they will be loaded with the form and the values not overwritten unless the user manually does so. If you don't want the user to overwrite them then make the form fields hidden, or read only, and set them in code the first time they are saved.

modified (datetime) and modified_by (user id) are set automatically to the time the item is saved and the user id who saved it at every save.

created_by_alias is a text field that you can use to set and display an alternative name for the originator (creator) of the article. This is useful if you want to credit an article (or any item) to some other name who is not a user on your system.

Maybe your problem is that you are using 'created_time' and 'modified_time' as the field names rather than 'created' and 'modified' so Joomla is not handling them in the default way.

Or maybe you simply haven't included them in your form?

Slightly confusingly the standard fields that flag if a user has an item open for editing are called 'checked_out_time' (datetime) and 'checked_out' (userid)  rather than checked_out for the time and checked_out_by for the user.

All of these can be handled automatically by Joomla if you let it.  

Naturally you don't have to use these fields in a custom table for your extension, but it can often be useful to do so. If you are using 'created' for the created datetime field then it shouldn't be getting changed on save unless the user changes the value (if you have given her that option)

There is a further quirk that historically Joomla has used a value of '0000-00-00 00:00:00' as the empty default for created, modified and checked_out - this is no longer valid in MySql and can cause problems if you use phpmyadmin (for example) to examine/edit the data.

I do like your questions even when they confuse me as they force me to think about things that perhaps I don't fully understand. As always others may correct some of what I've said as I'm not an authority.

Cheers
Roger

Nico van de Kamp

unread,
Nov 21, 2020, 11:21:54 AM11/21/20
to Joomla! General Development
Hi Roger,

Sorry that I confused you by my question, but thanks for the compliment that you like my question(s). But many thanks that you try to help by trying to answer my question although it did confused you.

I've been working on other project and now I'm working on this project further.

Goal/what I try to achieve:
  • I want to save by default the created-/modified_by and the time when it is created and/or modified. And I want to show this on the details screen (edit.php).
  • The field created_by does have a button to choose an other user, the other fields created(_time), modified_by, modified(_time) are readonly
  • If the user opens the first time the details page, then the user created-by/modified_by are filled in with you user who opens the page. the other free fields are empty at the first time\
  • The other times the fields do have the value's at the lasttime it is saved, and the button for the created_by 'hidden' if the user still exist.
  • I don't want to make them hidden because I want to inform the different users when it is created and by whom. Identically when it is modified and by whom.
  • On this moment I don't use created_by_alias
  • My screen format is dd-mm-yyyy hh2mm:ss while the database format is: yyyy-mm-dd hh:mm:ss
  • Ok, some other little requirements as when the user created_by is removed. But first this than  I will try to find out this by my own.

I have build a new backend menu item with:
  • 4 fields and the 4 fields created_by, created, modified_by and modified. (in total 8 fields)
  • Define the <form>.xml without the four fields: created_by, created, modified_by and modified
  • I have tried the field created and created_time. The same for modified and modified_time.
  • Checked_out and checked_out_time is working (see attachement)
  • I'm building from the book "Learning Joomla 3 Extension Development". That's the basic and I'm looking at other backend components like com_content, com_user
  • When I save a details page, everything is saved except the four fields: created_by, created, modified_by and modified.

Back to my problem:
  • If I read you're answer correctly than it is not necessary to define this fields in the models/<form>.xml. If you don't define there the fields than the time is automatically saved. That's Right I think?
  • And I have already earlier been looking at com_content to find how they do it there. I'm looking in the model article.php, but till now I can't find how they do it there wtih updating these fields.
Here my form.xml:
[code]
<form>
    <fieldset name="catfields">
        <field  name="id"
                type="text"
                default="0"
                label="JGLOBAL_FIELD_ID_LABEL"
                readonly="true"
                class="readonly"
                description="JGLOBAL_FIELD_ID_DESC"
        />
        <field  name="tcnr"
                type="text"
                class="inputbox"
                size="8"
                required="true"
        />
        <field  name="tctc"
                type="text"
                class="inputbox"
                size="16"
                required="true"
        />
        <field  name="tctn"
                type="text"
                class="inputbox"
                size="64"
                required="true"
        />
                
        <field  name="info"
                type="textarea"
                class="inputbox"
                rows="3"
                cols="30"
        />
        <!-- </fieldset> -->

        <!-- <fieldset name="details"> -->
        <field  name="state"
                type="list"
                label="JSTATUS"
                description="JFIELD_PUBLISHED_DESC"
                class="chzn-color-state"
                filter="intval"
                size="1"
                default="1"
            >
                    <option value="1">JPUBLISHED</option>
                    <option value="0">JUNPUBLISHED</option>
                    <option value="2">JARCHIVED</option>
                    <option value="-2">JTRASHED</option>
        </field>
    </fieldset>
</form>
[/code]

--
Something total different and maybe stupid, but may ask:
It seems that the old groups is replaced by these new groups. But do I something wrong, I mean I can't add code blocks, quote blocks and that kind of things which was normal at the classic groups.
Another thing, at the classic groups it was not possible and now also not, but I can't edit a conversation. Is that right, or did I missed something.

Am I the only one or this the default behaviour?
(A few weeks ago I was going back from the new conversation to the classic conversatiron. Google is asking you than WHY? My answer was about the conversation editor. But maybe I do something wrong)
2020-11-21 17_07_31-Sreenshot.jpg

venomDev

unread,
Nov 22, 2020, 7:49:48 AM11/22/20
to Joomla! General Development
Hi Nico, you could set the default value in the database to be the current date and time. This should automatically set the created date once when the record is created and then you never touch it again.

Nico van de Kamp

unread,
Nov 22, 2020, 12:34:54 PM11/22/20
to Joomla! General Development
Hi VenomDev,

Yeh, but than I'm not using the 'power' of the framework. I want to use the Joomla framework.

I have just export the joomla database, there is not an table using default now() or default_current_timestamp. So I don't want to go that way and I want to understand how it works

I have used looked at the catergories table and there they use:
  • `created_user_id` int(10) UNSIGNED NOT NULL DEFAULT '0',
  • `created_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  • `modified_user_id` int(10) UNSIGNED NOT NULL DEFAULT '0',
  • `modified_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
For the banners they have defined it:
  • `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  • `created_by` int(10) UNSIGNED NOT NULL DEFAULT '0',
  • `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  • `modified_by` int(10) UNSIGNED NOT NULL DEFAULT '0',
But if they are not defined now in the <form>.xml, the joomla framework should save it by default, because they are not in $data array. And if defined the fields than the <form>.xml, than I should be added to the $data, but than I have to change the $data['modified'] by the sql format and the current time because my screen value is dd-mm-yyyy hh:mm:ss. On this moment I do not exactly know were. I think in tablels <item>.php, in the method Check, or save.

I hope that I can find how it works, so that I learn a little bit more of the framework

Nico van de Kamp

unread,
Nov 26, 2020, 4:49:11 AM11/26/20
to Joomla! General Development
Hello,

Although it's a thread of 2012 I have found this: https://forum.joomla.org/viewtopic.php?t=750048.

I have added this, and now these fields are populated in the database!!!

So I'm still doubting if these fields are populated by default! And I'm agree with all of you, I can't find this for the com_content or com_categories.
So it is still not clear how it should work or what the default behavior is for these fields.

The problem for me these is: Joomla is not always easy to follow, it has a very high learning curve and I do not know what I not know. But for now I'm a little bit further.

Nico.

Roger Creagh

unread,
Nov 26, 2020, 4:36:08 PM11/26/20
to joomla-de...@googlegroups.com
Hi Nico

In your table include this:
...
  `created` datetime,
  `created_by` int(10) NOT NULL DEFAULT '0',
  `created_by_alias` varchar(255) NOT NULL DEFAULT '',
  `modified` datetime ,
  `modified_by` int(10) NOT NULL  DEFAULT '0',

plus checkout and version fields if you are using them.
NB some examples include a default value of '00-00-0000 00:00:00' for the datetimes, this is invalid in some versions of mysql and may throw errors - particularly if you try to edit stuff in phpmyadmin. Safer not to set a default and make sure your code always gives a value.

In component/admin/models/forms/editviewname.php include this:
<fieldset>
...
<field name="created" type="calendar"
label="JGLOBAL_FIELD_CREATED_LABEL" description="JGLOBA_FIELD_CREATED_DESC"
class="inputbox" size="20" format="%Y-%m-%d %H:%M:%S" filter="user_utc" />

<field name="created_by" type="user"
label="JGLOBA_FIELD_CREATED_BY_LABEL" description="JGLOBA_FIELD_CREATED_BY_DESC" />
<field name="created_by_alias" type="text"
label="JGLOBA_FIELD_CREATED_BY_ALIAS_LABEL" description="JGLOBA_FIELD_CREATED_BY_ALIAS_DESC"
class="inputbox" size="20" />

<field name="modified" type="calendar"
label="JGLOBA_FIELD_MODIFIED_LABEL" description="JGLOBA_FIELD_MODIFIED_DESC"
class="inputbox" size="20" format="%Y-%m-%d %H:%M:%S" filter="user_utc" />

<field name="modified_by" type="user"
label="JGLOBA_FIELD_MODIFIED_BY_LABEL" description="JGLOBA_FIELD_MODIFIED_BY_DESC" />
</fieldset>
that will give you the standard fields to put in your edit form, but you don't have to add them explicitly, see next bit. You might want/need to create your own component language strings for the fields.:

In component/admin/views/editviewname/default.edit.php include this:
<div class="span3">
  <?php echo JLayoutHelper::render('joomla.edit.global', $this); ?>
</div>
that will add all and any of the standard fields that you have defined  in the sql and in your xml for the edit form - create, modified, versioning, category, tags, note, and maybe others...

In component/admin/models/editviewname.php include this:

in     protected function prepareTable($table) {
...
        // Set the default values
        if (empty($table->created)) { //there is no preexisting value set so provide one
             $table->created = $date->toSql();  //NB The user can edit this on the form, make it readonly in the xml if you don't want them to
        }
        if (empty($table->created_by)) { //ditto
         $table->created_by = Factory::getUser()->id; //NB as above
         }
         if (empty($table->created_by_alias)) {  //I tend to set this to a default of username/name, but it is not necessary         
         $table->created_by_alias = Factory::getUser()->username;   //make it an option to use name instead of username or simply don't preset this at all
         }
         if (empty($table->id)) {           
             // Set ordering to the last item if not set
...
         } else { // if id is set then this is not a new item so set the modified by
            $table->modified    = $date->toSql();  //NB as above
            $table->modified_by = $user->id; //NB as above
         }
...
}
That sets the defaults every time the edit form is opened - created only set on a new item, modified if it is existing item

That's about it, you dont need to do anything in the admin/tables/editviewname.php - the values from the form will just get saved or updated. You can always make the fields in the xml readonly or even hidden if you don't want the user to change them or even see them. It is also consistent with the way all? the inbuilt components do it.

This is kind of the other way around to the old forum link you posted - here the defaults are set when the form is loaded (if needed) rather than when the table is saved - this allows you the option of letting the user change things if you want. You are right they are not automatically populated by default - they do need to be set to default values 

Hope this helps
Roger
--
You received this message because you are subscribed to the Google Groups "Joomla! General Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to joomla-dev-gene...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/joomla-dev-general/8c568554-fd5a-4a0d-848b-db060cadad8dn%40googlegroups.com.

Nico van de Kamp

unread,
Feb 14, 2021, 3:52:26 PM2/14/21
to Joomla! General Development
Hello,

due to some frustration of this and work on an other JAVA job, I had decided to leave it for a while and do some other things first. But now I try to make progress again.

I don't how it exactly works, but I have add two lines to add publishing data in the edit.php:
[CODE]
echo JLayoutHelper::render('joomla.edit.global', $this);                     // state field
echo JLayoutHelper::render('joomla.edit.publishingdata', $this);     // created_by, created_time, modified_by, modified_time
[/CODE]

This is working so far for adding a new record or updating a record.

When I add a new record I like to pre-populate the field 'created_by' in the method protected function loadFormData() of the components/component/models/*.php with:
[CODE]
$user = JFactory::getUser();
echo "Data: ".var_dump($data)." user: ".$user->id;
$data->set('created_by', $user->id, 'int');
[/CODE]
(My idea is, if someone creates a new record, than he/she creates it, no one else, so why does he need to search and select/fill in his own name?)

I have three fields defined in the table from the database, which should have a unique value. So if you fill in on the detail page (edit.php) a value which already exist in the dB, the save will fail, which is correct.

But the remarkable thing is that the field created_by is not in the $data array set at the time of loadFormData():
[CODE]
array (size=12)
'id' => int 61
'canr' => string '5' (length=1)
'catc' => string 'NN' (length=2)
'catn' => string 'Test' (length=4)
'cmin' => int 0
'cmax' => string '0' (length=1)
'info' => string '' (length=0)
'state' => int 1
'created_time' => string '2021-02-14 17:29:46' (length=19)
'modified_by' => string '150' (length=3)
'modified_time' => string '2021-02-14 17:29:46' (length=19)
'tags' => null
[/CODE]
This is a var_dump at the time of loadformData()  and as you can see 'created_by' is lost in this situation. And as said with creating a record or updating a record, it is working fine.

Has somebody an idea why the field 'created_by' why it could be lost from the $data array, when a record could not be saved due to it is not unique in the database? And has somebody an idea if there is an opportunity to solve this and how to solve it?
Maybe another question: were is $data created/populated in Joomla? (Which method I mean)

Nico

Roger Creagh

unread,
Feb 14, 2021, 4:13:45 PM2/14/21
to joomla-de...@googlegroups.com
The user should not be having to select their name on the created_by field. You set the default in the model prepareTable($table) function
...
        if (empty($table->created_by)) {
         $table->created_by = Factory::getUser()->id;
        }
        if (empty($table->created_by_alias)) {           
         $table->created_by_alias = Factory::getUser()->username;    //make it an option to use name instead of username
        }
...

I like to set the text alias to the username or name by default (an option setting which to use, not shown here), so that if I want to display who created it I just have to get the one field.

Glenn Arkell

unread,
Feb 14, 2021, 5:14:28 PM2/14/21
to Joomla! General Development
Hi Nico & Roger,
I actually do my created_by field in the bind within the table file.

    public function bind($array, $ignore = '')
    {
        $date = Factory::getDate();
        $input = Factory::getApplication()->input;
        $task = $input->get('task');

        if ($array['id'] == 0 && empty($array['created_by']))
        {
            $array['created_by'] = Factory::getUser()->id;
        }

Hope this helps rather than confuses.  Cheers.
Glenn

Roger Creagh

unread,
Feb 15, 2021, 4:05:45 AM2/15/21
to joomla-de...@googlegroups.com
On Sun, 2021-02-14 at 14:14 -0800, Glenn Arkell wrote:
Hi Nico & Roger,
I actually do my created_by field in the bind within the table file.

Hope this helps rather than confuses.  Cheers.

Yes indeed, thanks Glen. It seems more logical to do it in the table file. Any other particular advantage to doing it there?
Roger

Glenn Arkell

unread,
Feb 15, 2021, 4:43:45 AM2/15/21
to Joomla! General Development
Hi Roger,
Not that I know of, just makes sense.  I can't actually claim credit for the idea because I've used Component Creator to start off many of my components and that's where they do it.  So I've just followed suit ever since.  Cheers.
Glenn

nicova...@gmail.com

unread,
Feb 15, 2021, 4:38:06 PM2/15/21
to Joomla! General Development
Hello Roger and Glenn,

Thanks for you're help, but unfortunately doesn't help at the moment. The issue is not that the data is not saved into the database. It is saved into the database with the right values

If I save or update my record than it works perfectly. See here my $data array at the time of loadformData (var_dump($data))
[CODE]
object(Joomla\CMS\Object\CMSObject)[465]
  protected '_errors' => 
    array (size=0)
      empty
  public 'id' => string '61' (length=2)
  public 'created_by' => string '150' (length=3)
  public 'created_time' => string '2021-02-14 17:29:46' (length=19)
  public 'modified_by' => string '150' (length=3)
  public 'modified_time' => string '2021-02-15 21:19:11' (length=19)
  public 'canr' => string '88' (length=2)
  public 'catc' => string 'NN' (length=2)
  public 'catn' => string 'Test' (length=4)
  public 'info' => string 's' (length=1)
  public 'cmin' => string '0' (length=1)
  public 'cmax' => string '0' (length=1)
  public 'checked_out' => string '150' (length=3)
  public 'checked_out_time' => string '2021-02-15 21:19:11' (length=19)
  public 'state' => string '1' (length=1)
  public 'ordering' => string '0' (length=1)
[CODE]
As you can see the field  'created_by' is in the $data array. This is when I add a new record or update the record.

The field canr has now the value 88. If I change to 5 for example which does already exist in the database I get the error : " Saving fails due to the following error: Duplicate entry '5' for key 'idx_canr' ".  This is what I expect, but why is not the $data now different when do save of a new recore or update a record?

It returns to the detail page, but if I make dump of the $data array, the field  'created_by' is not in the $data array!!!????
[CODE]
array (size=12)
  'id' => int 61
  'canr' => string '5' (length=1)
  'catc' => string 'NN' (length=2)
  'catn' => string 'Test' (length=4)
  'cmin' => int 0
  'cmax' => string '0' (length=1)
  'info' => string 's' (length=1)
  'state' => int 1
  'created_time' => string '2021-02-14 17:29:46' (length=19)
  'modified_by' => string '150' (length=3)
  'modified_time' => string '2021-02-15 21:19:11' (length=19)
  'tags' => null
[/CODE]
You see, the field  'created_by' is not in the array when it fails to save because of duplicate entry of the canr value. The ordering is different as well.

But now I see another difference. When the saving action is successful, than it is an object. But when it fails, it's an array at least not an object array. That's strange or not?
And saving fails due to an unique index in the database and not by Joomla itself. If it is not allowed to have double value's do I need to do something different, probably in the field.xml file?

Op maandag 15 februari 2021 om 10:43:45 UTC+1 schreef glenn...@gmail.com:
Reply all
Reply to author
Forward
0 new messages