-
JoomGuy
-
-
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!!!
|
-
admin
-
-
Offline
-
Administrator
-
-
Chef
- Posts: 3711
- Thank you received: 987
-
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
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.
|
-
JoomGuy
-
-
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!!!
|
-
JoomGuy
-
-
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!!!
|
-
admin
-
-
Offline
-
Administrator
-
-
Chef
- Posts: 3711
- Thank you received: 987
-
Karma: 140
-
|
Sorry, in MODEL.
Bit confused me too.
|
Coding is now a piece of cake
|
-
admin
-
-
Offline
-
Administrator
-
-
Chef
- Posts: 3711
- Thank you received: 987
-
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
|
-
JoomGuy
-
-
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!!!
|
-
admin
-
-
Offline
-
Administrator
-
-
Chef
- Posts: 3711
- Thank you received: 987
-
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.
|
-
JoomGuy
-
-
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!!!
|
-
VeCrea
-
-
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.
|
|
-
admin
-
-
Offline
-
Administrator
-
-
Chef
- Posts: 3711
- Thank you received: 987
-
Karma: 140
-
|
Can you test it directly in table store function ?
|
Coding is now a piece of cake
|
-
VeCrea
-
-
Offline
-
Platinum Member
-
-
Absolute JCook fan
- Posts: 473
- Thank you received: 100
-
Karma: 30
-
|
It is in my table store function
|
|
-
admin
-
-
Offline
-
Administrator
-
-
Chef
- Posts: 3711
- Thank you received: 987
-
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
|
-
JoomGuy
-
-
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!!!
|
-
VeCrea
-
-
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...
|
|
|