Welcome, Guest
Username: Password: Remember me

TOPIC: Version 2 - Manipulating data upon save

Version 2 - Manipulating data upon save 07 Nov 2012 21:38 #5058

  • JoomGuy
  • JoomGuy's Avatar
  • Offline
  • Moderator
  • Joomla Enthusiast, Lover of Cooking
  • Posts: 1115
  • Thank you received: 195
  • Karma: 64
Hi @admin,

I know that you've mentioned in a previous post that to perform any changes to data before a save, it should be done in the prepareQuery() but I'm confused as to how to do this...

EX:
Say I have 2 fields - type (dropdown with 1 or 2) and price (decimal),

I know that this is a pretty silly example as it has no real application but, If I wanted to always double price if the type was 2, how would I do it?

It just looks so different to the way it was done in 1.5.

Thanks

Gez
Need help with your Cook/Joomla Project? . PM me to find out what I can help with. NO time wasters please!!!
The administrator has disabled public write access.

Re: Version 2 - Manipulating data upon save 07 Nov 2012 22:31 #5072

  • admin
  • admin's Avatar
  • Offline
  • Administrator
  • Chef
  • Posts: 3711
  • Thank you received: 984
  • Karma: 140
You do not write it in prepareQuery().

prepareQuery() is only for loading the datas. (SELECT)

For updates (save, apply, ...) it must be done in the MVC.

A. If you want that this functionality works everywhere as a security rule, do it in the table class. store() function.

B. If you want it only for a particular layout, then you write in the controller save() function, and you can also test the layout with a switch in the function.

EDIT : IN MODEL, not in controller :oops:
EDIT 2 : In model, in prepareTable() function, not save()

In these both functions, read the received datas, and update them before to continue the process. Catch and change the datas before to save.

Hope it helps.
Coding is now a piece of cake
Last Edit: 07 Nov 2012 23:50 by admin.
The administrator has disabled public write access.

Re: Version 2 - Manipulating data upon save 07 Nov 2012 22:37 #5073

  • JoomGuy
  • JoomGuy's Avatar
  • Offline
  • Moderator
  • Joomla Enthusiast, Lover of Cooking
  • Posts: 1115
  • Thank you received: 195
  • Karma: 64
Sorry,

Must have got the wrong end of the stick - I read it in a reply to @jcbenton's post... I wondered how it was supposed to work there because the query was clearly for getting data...

I don't seem to have a save() or apply() function in my controllers???

Gez
Need help with your Cook/Joomla Project? . PM me to find out what I can help with. NO time wasters please!!!
The administrator has disabled public write access.

Re: Version 2 - Manipulating data upon save 07 Nov 2012 23:00 #5077

  • JoomGuy
  • JoomGuy's Avatar
  • Offline
  • Moderator
  • Joomla Enthusiast, Lover of Cooking
  • Posts: 1115
  • Thank you received: 195
  • Karma: 64
I just read the other post - your reply to @jcbenton too...

I can't see anything in any of them - not even in my model... BTW model is what I have set in my config for DB automation...

Do I need to create these functions or should they exist already???

Here's the code for my products (item):

My controller:
// no direct access
defined('_JEXEC') or die('Restricted access');

require_once(JPATH_ADMIN_JSTORESOCIAL .DS. "classes" .DS. "jcontroller.item.php");


/**
* Jstoresocial Product Controller
*
* @package	Jstoresocial
* @subpackage	Product
*/
class JstoresocialControllerProduct extends JstoresocialControllerItem
{
	/**
	* The context for storing internal data, e.g. record.
	*
	* @var string
	*/
	protected $context = 'product';

	/**
	* The URL view item variable.
	*
	* @var string
	*/
	protected $view_item = 'product';

	/**
	* The URL view list variable.
	*
	* @var string
	*/
	protected $view_list = 'products';

	/**
	* Constructor
	*
	* @access	public
	* @param	array	$config	An optional associative array of configuration settings.
	* @return	void
	*/
	public function __construct($config = array())
	{
		parent::__construct($config);
		$app = JFactory::getApplication();



	}

	/**
	* Return the current layout.
	*
	* @access	protected
	* @param	bool	$default	If true, return the default layout.
	*
	* @return	string	Requested layout or default layout
	*/
	protected function getLayout($default = null)
	{
		if ($default === 'edit')
			return 'product';

		if ($default)
			return 'product';

		$jinput = JFactory::getApplication()->input;
		return $jinput->get('layout', 'product', 'CMD');
	}


}
My Table:
// no direct access
defined('_JEXEC') or die('Restricted access');

cimport('classes.jtable');


/**
* Jstoresocial Table class
*
* @package	Jstoresocial
* @subpackage	Product
*/
class JstoresocialTableProduct extends JstoresocialTable
{
	/**
	* Constructor
	*
	* @access	public
	* @param	object	&$db	Database connector object
	* @return	void
	*/
	public function __construct(&$db)
	{
		parent::__construct('#__jstoresocial_products', 'id', $db);
	}


}
Need help with your Cook/Joomla Project? . PM me to find out what I can help with. NO time wasters please!!!
The administrator has disabled public write access.

Re: Version 2 - Manipulating data upon save 07 Nov 2012 23:03 #5078

  • admin
  • admin's Avatar
  • Offline
  • Administrator
  • Chef
  • Posts: 3711
  • Thank you received: 984
  • Karma: 140
Sorry, in MODEL.

Bit confused me too.
Coding is now a piece of cake
The administrator has disabled public write access.

Re: Version 2 - Manipulating data upon save 07 Nov 2012 23:04 #5080

  • admin
  • admin's Avatar
  • Offline
  • Administrator
  • Chef
  • Posts: 3711
  • Thank you received: 984
  • Karma: 140
Well, it can be done either in table, or in model.

The choice you make before in the config is creating the space for that.

Table : store() function
Model : sav() function

There you can catch and update your datas before to save.
Coding is now a piece of cake
The administrator has disabled public write access.

Re: Version 2 - Manipulating data upon save 07 Nov 2012 23:06 #5081

  • JoomGuy
  • JoomGuy's Avatar
  • Offline
  • Moderator
  • Joomla Enthusiast, Lover of Cooking
  • Posts: 1115
  • Thank you received: 195
  • Karma: 64
Should a save() and update() function already exist there?

Here's what I have (just the standard, untouched)...
/**
* Jstoresocial Item Model
*
* @package	Jstoresocial
* @subpackage	Classes
*/
class JstoresocialModelProduct extends JstoresocialModelItem
{
	/**
	* View list alias
	*
	* @var string
	*/
	protected $view_item = 'product';

	/**
	* View list alias
	*
	* @var string
	*/
	protected $view_list = 'products';

	/**
	* Constructor
	*
	* @access	public
	* @param	array	$config	An optional associative array of configuration settings.
	* @return	void
	*/
	public function __construct($config = array())
	{
		parent::__construct();
	}

	/**
	* Method to delete a product
	*
	* @access	public
	* @param	array	&$pks	The Ids of elements to delete.
	*
	* @return	boolean	True on success
	*/
	public function delete(&$pks = array())
	{
		if (!count( $pks ))
			return true;


		if (!parent::delete($pks))
			return false;



		return true;
	}

	/**
	* Method to get the layout (including default).
	*
	* @access	public
	*
	* @return	string	The layout alias.
	*/
	public function getLayout()
	{
		$jinput = JFactory::getApplication()->input;
		return $jinput->get('layout', 'product', 'STRING');
	}

	/**
	* Returns a Table object, always creating it.
	*
	* @access	public
	* @param	string	$type	The table type to instantiate.
	* @param	string	$prefix	A prefix for the table class name. Optional.
	* @param	array	$config	Configuration array for model. Optional.
	*
	* @return	JTable	A database object
	*
	* @since	1.6
	*/
	public function getTable($type = 'Product', $prefix = 'JstoresocialTable', $config = array())
	{
		return JTable::getInstance($type, $prefix, $config);
	}

	/**
	* Method to increment hits (check session and layout)
	*
	* @access	public
	*
	* @return	boolean	Null if skipped. True when incremented. False if error.
	*
	* @since	11.1
	*/
	public function hit()
	{
		return parent::hit(array());
	}

	/**
	* Method to get the data that should be injected in the form.
	*
	* @access	protected
	*
	* @return	mixed	The data for the form.
	*/
	protected function loadFormData()
	{
		// Check the session for previously entered form data.
		$data = JFactory::getApplication()->getUserState('com_jstoresocial.edit.product.data', array());

		if (empty($data)) {
			//Default values shown in the form for new item creation
			$data = $this->getItem();

			// Prime some default values.
			if ($this->getState('product.id') == 0)
			{
				$jinput = JFactory::getApplication()->input;

				$data->id = 0;
				$data->params = null;
				$data->title = null;
				$data->alias = null;
				$data->category = $jinput->get('filter_category', $this->getState('filter.category'), 'INT');
				$data->product_code = null;


			}
		}
		return $data;
	}

	/**
	* Method to auto-populate the model state.
	* 
	* This method should only be called once per instantiation and is designed to
	* be called on the first call to the getState() method unless the model
	* configuration flag to ignore the request is set.
	* 
	* Note. Calling getState in this method will result in recursion.
	*
	* @access	public
	* @param	string	$ordering	
	* @param	string	$direction	
	* @return	void
	*
	* @since	11.1
	*/
	public function populateState($ordering = null, $direction = null)
	{
		$app = JFactory::getApplication();
		$session = JFactory::getSession();



		parent::populateState($ordering, $direction);
	}

	/**
	* Preparation of the query.
	*
	* @access	protected
	* @param	object	&$query	returns a filled query object.
	* @param	integer	$pk	The primary id key of the product
	* @return	void
	*/
	protected function prepareQuery(&$query, $pk)
	{

		//FROM : Main table
		$query->from('#__jstoresocial_products AS a');

		switch($this->getState('context'))
		{
			case 'product.product':

				//BASE FIELDS
				$query->select(	'a.id,'
							.	'a.alias,'
							.	'a.category,'
							.	'a.product_code,'
							.	'a.title');

				//SELECT
				$query->select('_category_.title AS `_category_title`');
				$query->select('_category_.section AS `_category_section`');
				$query->select('_category_section_.title AS `_category_section_title`');

				//JOIN
				$query->join('LEFT', '`#__jstoresocial_categories` AS _category_ ON _category_.id = a.category');
				$query->join('LEFT', '`#__jstoresocial_sections` AS _category_section_ ON _category_section_.id = _category_.section');

				break;
			default:
				//SELECT : raw complete query without joins
				$query->select('a.*');
				break;
		}

		//SELECT : Instance Add-ons
		foreach($this->getState('query.select', array()) as $select)
			$query->select($select);

		//JOIN : Instance Add-ons
		foreach($this->getState('query.join.left', array()) as $join)
			$query->join('LEFT', $join);

		//WHERE : Item layout (based on $pk)
		$query->where('a.id = ' . (int) $pk);		//TABLE KEY


		//WHERE : Access
		//WHERE : Publish, publish date (state field)
	}

	/**
	* Prepare and sanitise the table prior to saving.
	*
	* @access	protected
	* @param	JTable	&$table	A JTable object.
	*
	* @return	void	
	* @return	void
	*
	* @since	1.6
	*/
	protected function prepareTable(&$table)
	{


		if (empty($table->id)){

		}
		else{

		}
		//Alias
		if (empty($table->alias))
			$table->alias = JApplication::stringURLSafe($table->title);
	}


}
Need help with your Cook/Joomla Project? . PM me to find out what I can help with. NO time wasters please!!!
The administrator has disabled public write access.

Re: Version 2 - Manipulating data upon save 07 Nov 2012 23:13 #5083

  • admin
  • admin's Avatar
  • Offline
  • Administrator
  • Chef
  • Posts: 3711
  • Thank you received: 984
  • Karma: 140
So create them ...

Well, check in the parent classes (Inheritance)

/com_xxxx/classes/jmodel.item.php

-> libraries/..../application/component/modeladmin.php
...

When you create and catch the save() function, you may not break the original call :
public function save($data)
{
	//Do what you want before. Work with [b]$data[/b]
	
	$result = parent::save($data)	// Keep the original call
	
	//Do what you want after. Read and work on [b]$result[/b]
	// Redirection must be in controller only (catch this $result (integer))

	return $result;
}

Simple !
Coding is now a piece of cake
Last Edit: 07 Nov 2012 23:16 by admin.
The administrator has disabled public write access.
The following user(s) said Thank You: organicwebs

Re: Version 2 - Manipulating data upon save 07 Nov 2012 23:19 #5084

  • JoomGuy
  • JoomGuy's Avatar
  • Offline
  • Moderator
  • Joomla Enthusiast, Lover of Cooking
  • Posts: 1115
  • Thank you received: 195
  • Karma: 64
Great!

Thanks Jocelyn!

I was confused because in the previous version (1.5) the save() function was right in the controller...

Thanks again,

Geraint
Need help with your Cook/Joomla Project? . PM me to find out what I can help with. NO time wasters please!!!
The administrator has disabled public write access.

Re: Version 2 - Manipulating data upon save 07 Nov 2012 23:28 #5085

  • VeCrea
  • VeCrea's Avatar
  • Offline
  • Platinum Member
  • Absolute JCook fan
  • Posts: 473
  • Thank you received: 100
  • Karma: 30
admin wrote:
Well, it can be done either in table, or in model.

The choice you make before in the config is creating the space for that.

Table : store() function
Model : sav() function

There you can catch and update your datas before to save.

Well it works for the most part, but not for this :
we already had this discussion, but when you use an ajax cascading combo box, it only saves the value of the last combo (say Country -> City, it only saves City, but i need to save Country too, in another field of the table)
So if add something like this :
		if ($this->city!= null){
		  $maDB = $this->getDbo(); $requete = $maDB->getQuery(true);
		  $maDB->setQuery ("SELECT m.country FROM #__xxx_cities AS m WHERE m.id = $this->city");
		  $resultat = $maDB->loadResult(); $this->country = $resultat;
		}
When i CREATE the new item, it doesn't work. If i save the item, then i edit it, then i save it again, then it works and the country appears. Can't figure out why.
The administrator has disabled public write access.

Re: Version 2 - Manipulating data upon save 07 Nov 2012 23:35 #5086

  • admin
  • admin's Avatar
  • Offline
  • Administrator
  • Chef
  • Posts: 3711
  • Thank you received: 984
  • Karma: 140
Can you test it directly in table store function ?
Coding is now a piece of cake
The administrator has disabled public write access.

Re: Version 2 - Manipulating data upon save 07 Nov 2012 23:36 #5087

  • VeCrea
  • VeCrea's Avatar
  • Offline
  • Platinum Member
  • Absolute JCook fan
  • Posts: 473
  • Thank you received: 100
  • Karma: 30
It is in my table store function
The administrator has disabled public write access.

Re: Version 2 - Manipulating data upon save 07 Nov 2012 23:43 #5088

  • admin
  • admin's Avatar
  • Offline
  • Administrator
  • Chef
  • Posts: 3711
  • Thank you received: 984
  • Karma: 140
So I don't know.
It is in your hands. You will find.
Dump is your friend ;-)

Table > store() is the last call before the physical write in DB.
Coding is now a piece of cake
The administrator has disabled public write access.

Re: Version 2 - Manipulating data upon save 07 Nov 2012 23:44 #5089

  • JoomGuy
  • JoomGuy's Avatar
  • Offline
  • Moderator
  • Joomla Enthusiast, Lover of Cooking
  • Posts: 1115
  • Thank you received: 195
  • Karma: 64
I don't mean to be impertinent but, do you really need to store the country and city codes? I mean, if cities are 'children' of countries, isn't it just as easy to traverse the related tables to get the country id? Also, wouldn't this lower redundancy?

Gez
Need help with your Cook/Joomla Project? . PM me to find out what I can help with. NO time wasters please!!!
The administrator has disabled public write access.

Re: Version 2 - Manipulating data upon save 07 Nov 2012 23:45 #5090

  • VeCrea
  • VeCrea's Avatar
  • Offline
  • Platinum Member
  • Absolute JCook fan
  • Posts: 473
  • Thank you received: 100
  • Karma: 30
That's all the discussion. But if need to filter by country, i can't do it. I know it's against rules of redundancy, but i need to be able to filter by country OR by city...
The administrator has disabled public write access.
Time to create page: 0.189 seconds

Get Started