Welcome, Guest
Username: Password: Remember me

TOPIC: Last SAVE id

Last SAVE id 27 Oct 2015 12:09 #13618

  • MorganL
  • MorganL's Avatar
  • Offline
  • Platinum Member
  • Posts: 438
  • Thank you received: 53
  • Karma: 16
In J-Cook components, is the method of getting the last saved ID the same as the recommended default
$db->query();
$lastRowId = $db->insertid();

I need to fire a process after the save of a NEW item, and whereas I can usually just determine the existence of data{'id} to see if the record is new or updated, in this instance I absolutely need the ID of the newly created record, with no chance it can accidentally be grabbed from another user who may be doing something on the same part of the component elsewhere
Morgan Leecy MCSE

Novell / Linux
PHP. MYSQL, Apache, node.js
Coldfusion, JQuery, HTML5
Joomla
The administrator has disabled public write access.

Last SAVE id 27 Oct 2015 12:51 #13620

  • Romkabouter
  • Romkabouter's Avatar
  • Offline
  • Elite Member
  • Posts: 310
  • Thank you received: 131
  • Karma: 48
Hi,

I think you should fork the controller for the item (singular)
Copy paste the save function.

In there, there is
			$result = parent::save();
			//Get the model through postSaveHook()
			if ($this->model)
			{
				$model = $this->model;
				$item = $model->getItem();	
			}
So, your $item will hold the saved data, you can then user $item->id and that will hold the inserted ID

Using insertid() can lead to problems if you have a lot of activity with users saving items.

You say you need to fire a process after the saving of a new item.
In my opinion iyou can do that in a controller, but maybe in your case this is not possible
The administrator has disabled public write access.
The following user(s) said Thank You: admin

Last SAVE id 27 Oct 2015 13:51 #13629

  • MorganL
  • MorganL's Avatar
  • Offline
  • Platinum Member
  • Posts: 438
  • Thank you received: 53
  • Karma: 16
Seriously awesome, you are an amazing asset to J-Cook, brilliant support. Thanks
Morgan Leecy MCSE

Novell / Linux
PHP. MYSQL, Apache, node.js
Coldfusion, JQuery, HTML5
Joomla
The administrator has disabled public write access.
The following user(s) said Thank You: Romkabouter

Last SAVE id 29 Oct 2015 09:34 #13643

  • MorganL
  • MorganL's Avatar
  • Offline
  • Platinum Member
  • Posts: 438
  • Thank you received: 53
  • Karma: 16
Struggling to get this to work.. here is my model and the ONLY attempt that gets response
$bemodel = CkJModel::getInstance('bidelement', 'MycomponentModel');
                            $result1 = $bemodel ->save(
                                    array(
                                        'associated_bid' => $data['id'],
                                        'film' => $data['film'],
                                        'global' => 0,
                                        'regional_purchase' => 1,
                                        'territorial_purchase' => 0,
                                        'region' => $region
                                    )
                                );

                            $db->query();
                            $lastRowId = $db->insertid();

This actually returns a value.. but it ALSO refires the save task so I get 2 records. The id returned IS the last ID in the table

I have tried various derivations of rom's suggestion and this just returns null.

What code can I type into the above snippet instead of
$db->query();
                            $lastRowId = $db->insertid();

That will return the ID of the newely created ID from bidelement
Morgan Leecy MCSE

Novell / Linux
PHP. MYSQL, Apache, node.js
Coldfusion, JQuery, HTML5
Joomla
The administrator has disabled public write access.

Last SAVE id 29 Oct 2015 12:04 #13644

  • Romkabouter
  • Romkabouter's Avatar
  • Offline
  • Elite Member
  • Posts: 310
  • Thank you received: 131
  • Karma: 48
I am going to try this one myself, sounds like a nice challenge.
I will create a testcomponent, but I need some more info.

Can you describe your functionality?
When saving an item, you say you want to fire another process.
Is the other process another screen or something?
Last Edit: 29 Oct 2015 12:14 by Romkabouter.
The administrator has disabled public write access.

Last SAVE id 29 Oct 2015 12:25 #13646

  • MorganL
  • MorganL's Avatar
  • Offline
  • Platinum Member
  • Posts: 438
  • Thank you received: 53
  • Karma: 16
I have a component where a user creates a BID and the first thing they do on creating the bid is save it to get an ID.. thats the easy bit, and this opens up the rest of the form.

One of the things they do is choose the SCOPE of the bid by a checkbox group of regions.

As soon as they click NEXT, the model loops through all the checked boxes and creates a record in the

BIDELEMENT table which is linked to BID via an FK (so if they choose 3 regions, three bidelements are added)

HOWEVER there is a THIRD table which is a XREF which basically allows a user to use the RIGHTS they want against each regions (i.e BIDELEMENT)

1 BID -> x BIDELEMENTS -> x RIGHTS

BIDELEMENTS are created fresh every time (there can be a lot of changes, so I just purge the elements each save and re-add them. Not efficient, but does the job

This means that during the form save the BIDELEMENT is always created afresh, and then the rights that have been ticked are generated against a fresh BIDELEMENT record. I have not done this loop yet, but once I get this id thing sorted, that will not actually be a problem

So the full code AS IT STANDS is (regionchoice is the checkbox group regionschoiuce[]) which works lovely)

NOTE : this ALL works apart from just not grabbing that ID
foreach ($_POST['regionchoice'] as $region) {

                            $bemodel = CkJModel::getInstance('bidelement', 'MycomponentModel');
                            $result1 = $bemodel ->save(
                                    array(
                                        'associated_bid' => $data['id'],
                                        'film' => $data['film'],
                                        'global' => 0,
                                        'regional_purchase' => 1,
                                        'territorial_purchase' => 0,
                                        'region' => $region
                                    )
                                );



                            $db->query();
                            $lastRowId = $db->insertid();

                           // this will eventually also be a loop of the rights to the element
                            $rdmodel = CkJModel::getInstance('xrightdesired', 'MycomponentModel');
                            $result2 = $rdmodel ->save(
                                array(
                                    'associated_bid' => $data['id'],
                                    'bid_element' => $lastRowId,
                                    'right' => 1 //this is just a test figure for now
                                )
                            );
                           // end the loop when defined

                        }

Maybe you will be able to see the problem without actually coding anything
Morgan Leecy MCSE

Novell / Linux
PHP. MYSQL, Apache, node.js
Coldfusion, JQuery, HTML5
Joomla
The administrator has disabled public write access.

Last SAVE id 29 Oct 2015 12:50 #13647

  • Romkabouter
  • Romkabouter's Avatar
  • Offline
  • Elite Member
  • Posts: 310
  • Thank you received: 131
  • Karma: 48
When seeing this code, I also think I see your problem.
I thought you were not using insertid() anymore, but I see it in your code.
isertid() does not work on DB level, but on table level.

So don't use
$db->query();
$lastRowId = $db->insertid();

Instead use
$table = JTable::getInstance('bidelement', 'MycomponentTable');
$newid = $table->getDBO()->insertid(),

That will probably fix your problem
The administrator has disabled public write access.
The following user(s) said Thank You: admin, MorganL, koenvdz

Last SAVE id 29 Oct 2015 13:26 #13648

  • MorganL
  • MorganL's Avatar
  • Offline
  • Platinum Member
  • Posts: 438
  • Thank you received: 53
  • Karma: 16
You sir.. are a genius

Worked
Morgan Leecy MCSE

Novell / Linux
PHP. MYSQL, Apache, node.js
Coldfusion, JQuery, HTML5
Joomla
The administrator has disabled public write access.

Last SAVE id 25 Mar 2016 18:12 #13873

  • krasy
  • krasy's Avatar
  • Offline
  • Premium Member
  • Posts: 90
  • Thank you received: 8
  • Karma: 5
Romkabouter wrote:
Hi,

I think you should fork the controller for the item (singular)
Copy paste the save function.

In there, there is
			$result = parent::save();
			//Get the model through postSaveHook()
			if ($this->model)
			{
				$model = $this->model;
				$item = $model->getItem();	
			}
So, your $item will hold the saved data, you can then user $item->id and that will hold the inserted ID

Using insertid() can lead to problems if you have a lot of activity with users saving items.

You say you need to fire a process after the saving of a new item.
In my opinion iyou can do that in a controller, but maybe in your case this is not possible

thx ;) hey man that was user useful :)
Happy Easter! btw
The administrator has disabled public write access.

Last SAVE id 08 Jan 2017 23:02 #14925

  • vlemos
  • vlemos's Avatar
  • Online
  • Elite Member
  • Posts: 295
  • Thank you received: 41
  • Karma: 21
Hello Admin / Cooks

I am not sure if this is a bug or my inability to use the save method.

I have a service page which loads a record from a services table. On that same page I have a note textarea which loads an empty body field from a notes table. These fields all play nicely together until I try to save a note. On "Enter", the note body is sent to the server along with the service id and everything works:
	$note = CkJModel::getInstance('Note', 'BookingsModel');
	$result = $note->save(
		array(
			'service_id' => $sid,
			'body' => $body,
		)
	);

Until we reach: libraries/legacy/model/admin.php
	/**
	 * Method to save the form data.
	 *
	 * @param   array  $data  The form data.
	 *
	 * @return  boolean  True on success, False on error.
	 *
	 * @since   12.2
	 */
	public function save($data)
	{
		$dispatcher = JEventDispatcher::getInstance();
		$table      = $this->getTable();
		$context    = $this->option . '.' . $this->name;

		if ((!empty($data['tags']) && $data['tags'][0] != ''))
		{
			$table->newTags = $data['tags'];
		}

		$key = $table->getKeyName();
		$pk = (!empty($data[$key])) ? $data[$key] : (int) $this->getState($this->getName() . '.id');
		$isNew = true;

The line:
$pk = (!empty($data[$key])) ? $data[$key] : (int) $this->getState($this->getName() . '.id');

Calls populateState on the note model, which then returns the cid of the service, which is not good! This results in an update once a note with the returned $pk value exists. If I change $pk = null, a new note is inserted as expected.

I can find a solution; however, I am not sure if this is a problem or if I am simply not asking Cook to save my data using the correct tone of voice. :)

Any feedback would be appreciated. . .

Thanks as always
vlemos
The administrator has disabled public write access.

Last SAVE id 09 Jan 2017 12:52 #14926

  • admin
  • admin's Avatar
  • Offline
  • Administrator
  • Chef
  • Posts: 3711
  • Thank you received: 984
  • Karma: 140
This is normal because Joomla automatically load the ID from the URL (since ORM you can change that, but not in the controller)

Well, you can do this to solve your problem :
	$note = CkJModel::getInstance('Note', 'BookingsModel');
	$result = $note->save(
		array(
//HERE
			'id' => 0,

			'service_id' => $sid,
			'body' => $body,
		)
	);
Coding is now a piece of cake
Last Edit: 09 Jan 2017 12:53 by admin.
The administrator has disabled public write access.
The following user(s) said Thank You: vlemos

Last SAVE id 09 Jan 2017 15:49 #14928

  • vlemos
  • vlemos's Avatar
  • Online
  • Elite Member
  • Posts: 295
  • Thank you received: 41
  • Karma: 21
Thanks Admin, you are the best. . .

Instinctively, I tried 'id' => null and it didn't work so I hacked the State while waiting for feedback. Would not have tried assigning any number tho.

Thanks again
vlemos
The administrator has disabled public write access.

Last SAVE id 21 Feb 2017 15:47 #15006

  • vlemos
  • vlemos's Avatar
  • Online
  • Elite Member
  • Posts: 295
  • Thank you received: 41
  • Karma: 21
Hello Cooks

I had the issue of getting the inserted ID a few hours ago. And although this thread is almost a year old I thought it may help if I posted my findings to assist future cooks.

As above, my save routine is called from the "Notes" collection model like:
	$note = CkJModel::getInstance('Note', 'BookingsModel');
	$note->setState('note.id', 0);
	$item = $note->save(
		array(
			"service_id" => $sid,
			"body" => $body,
			"ordering" => 0,
			"created_on" => date("Y-m-d H:i:s")
		)
	);

This calls the save method on the Item-model, which calls the same method on the Item class model on the admin-side of the component. The component then passes the request to core Joomla.

In other words, my call calls "save" in this sequence, 1 -> 2 -> 3:
1). . . ./components/com_xxxxx/models/note.php
2). . . ./administrator/components/com_xxxxx/classes/model/item .php
3). . . ./libraries/legacy/model/admin.php => JModelAdmin->save()

Joomla actually returns the ID of the inserted record to "item .php", and it is available in the Item state var. The ID is now publicly available and can be accessed via "components/com_xxxxx/models/note.php" as $note->getState('note.id');
	/**
	 * Save an item.
	 *
	 * @access	public
	 * @param	array	$data	The post values.
	 *
	 * @return	boolean	True on success.
	 */
	public function save($data)
	{
		.
		.
		.

		if (parent::save($data)) {
			// For more processing, the ID is available here.
			// and $note->getState('note.id') for wider scope.
			$inserted_id = $this->getState('note.id');
			
		
		
			return true;
		}
		return false;
	
	
	}

WARNING: this is not a forked solution! This will only work on the core component files. If you need to move it to your fork-files, it requires a bit more work related to the calls to "parent::". Would be happy to share if someone wants.

Warm regards
vlemos
Last Edit: 22 Feb 2017 03:11 by vlemos.
The administrator has disabled public write access.
Time to create page: 0.216 seconds

Get Started