Update process

Cupara

Well-known member
I'm trying to add a value of 1 to an existing number from a row in the database. How can I get this to work? I have tried the get existing data, it will update it but not do an addition or subtraction process as I have it coded.

Any suggestions?
 
It is not very clear what it is you are trying to do.
Some more information or code sample would help.
Using get() and then set() does not work for you (if you are using a DataWriter that is)?
 
xShop_DateWriter_UserPoints:
PHP:
class xShop_DataWriter_UserPoints extends XenForo_DataWriter
{
    protected function _getFields()
    {
        return array(
            'xshop_points' => array(
                'points_id' => array('type' => self::TYPE_UINT, 'autoIncrement' => true),
                'user_id' => array('type' => self::TYPE_UINT),
      'points_total' => array('type' => self::TYPE_UINT),
      'points_earned' => array('type' => self::TYPE_UINT)
            )
        );
    }

    protected function _getExistingData($data)
    {
        if (!$userid = $this->_getExistingPrimaryKey($data, 'member_id'))
        {
            return false;
        }
        return array('xshop_points' => $this->getModelFromCache('xShop_Model_Points')->getUserPointsId($userid));
    }

    protected function _getUpdateCondition($tableName)
{
return 'points_id = ' . $this->_db->quote($this->getExisting('points_id'));
}

/*    protected function _postDelete()
{

$model = $this->getModelFromCache('xShop_Model_Stock');

$deletedId = $this->_existingData['xshop_stock']['member_id'];
if ($model->hasData($deletedId))
{
$dw->delete();
}
    }*/

xShop_ControllerPublic_Index_Buy: This is the confirm function that does the data writing. I removed the data set and such to test other things.
PHP:
    public function actionConfirm()
    {
  $this->_assertPostOnly();

  $dwInput = $this->_input->filter(array(
'item_id' => XenForo_Input::UINT,
'item_name' => XenForo_Input::STRING,
'item_cost' => XenForo_Input::UINT,
'points_id' => XenForo_Input::UINT,
'points_total' => XenForo_Input::UINT,
  'points_earned' => XenForo_Input::UINT,
'stock_order' => XenForo_Input::UINT,
  'member_id' => XenForo_Input::UINT,
  'stock_id' => XenForo_Input::UINT
));

$dw = XenForo_DataWriter::create('xShop_DataWriter_UserPoints'); if ($dwInput['points_id']) $dw->setExistingData($dwInput['points_id']);
 
$new_total = $dwInput['points_total'] - $dwInput['item_cost'];
$dw->set('points_id', $dwInput['points_id']); $dw->set('user_id', $dwInput['user_id']); $dw->set('points_total', $new_total); $dw->save();

$redirectType = ($dwInput['points_id'] ? XenForo_ControllerResponse_Redirect::RESOURCE_UPDATED : XenForo_ControllerResponse_Redirect::RESOURCE_CREATED);

return $this->responseRedirect( $redirectType, XenForo_Link::buildPublicLink('shop') );

    }
protected function _getPointsModel()
{
return $this->getModelFromCache('xShop_Model_Points');
}
 
I'm doing both, when I get stuck on one I move to another then come back later otherwise I will get so annoyed I won't work one for a week or two. So I try to keep things going smoothly so I only work on one every other day.
 
Perfect, I will test it out tonight and get back to you after class. Thanks for the help Syndol.
 
The input type I have in the template has <input type="hidden" name="member_id" value="$userId" /> hence the member_id instead. But I never thought to make the user_id a unique key, I will do that as well. Thanks
 
Ok can't really test at the moment as I keep getting this error:
No controller response from xShop_ControllerPublic_Index_Buy::actionConfirm
XenForo_FrontController->_handleControllerResponse() in XenForo/FrontController.php at line 318
XenForo_FrontController->dispatch() in XenForo/FrontController.php at line 132
XenForo_FrontController->run() in /home/xen/public_html/index.php at line 13

Here is the complete function for my buy page:
PHP:
public function actionConfirm()
{
    $this->_assertPostOnly();
 
    $dwInput = $this->_input->filter(array(
'item_id' => XenForo_Input::UINT,
 'item_name' => XenForo_Input::STRING,
 'item_cost' => XenForo_Input::UINT,
 'points_id' => XenForo_Input::UINT,
 'points_total' => XenForo_Input::UINT,
    'points_earned' => XenForo_Input::UINT,
 'stock_order' => XenForo_Input::UINT,
    'member_id' => XenForo_Input::UINT,
    'stock_id' => XenForo_Input::UINT
 ));

 $userId = $dwInput['member_id'];
 $new_total = $dwInput['points_total'] - $dwInput['item_cost'];
 $pointsModel = $this->_getPointsModel();

 $exists = $pointsModel->getUserPoints($userId); // whatever function you use for this

 $dw = XenForo_DataWriter::create('xShop_DataWriter_UserPoints');

 if ($exists) // update
 {
     $dw->setExistingData($userId);
 }

 $vars = array('user_id' => $userId, 'points_total' => $new_total);

 $dw->bulkSet($vars);

 $dw->preSave();

 if ($dw->hasErrors())
 {
     $errors = $dw->getErrors();
     $errorKey = reset($errors);
     return false;
 }
 
 $dw->save();

 $redirectType = ($userId ?
             XenForo_ControllerResponse_Redirect::RESOURCE_UPDATED :
             XenForo_ControllerResponse_Redirect::RESOURCE_CREATED);

 return $this->responseRedirect(
 $redirectType,
 XenForo_Link::buildAdminLink('shop')
 );
 
     }
 
Ok I didn't change that line, I changed it to user_id. The problem now is it won't do the subtraction I have setup.

PHP:
$new_total = $dwInput['points_total'] - $dwInput['item_cost'];
 
In your code, those two values are sent into the actionConfirm() function.
Are you sure their values are correct?
Or are you wanting to subtract the value of item_cost from the value of points_total in the DataWriter after you've set it to an existing user?
 
I'm wanting to subtract the value of item_cost from the value of points_total after setting it to a user.
 
Well I am a little confused as to why/where does the $dwInput['points_total'] comes from, but to get that value from the DataWriter after calling setExistingData:
PHP:
$points_total = $dw->get('points_total');
$new_total = $points_total - $dwInput['item_cost'];
 
The values come from the confirm page which has <input> fields hidden but gathers the data. I made sure they worked and data was being added. I'll give that a try.
 
If user_id is Unique in your table then you would have gotten an error.
_getFields() should mimic your MySQL table exactly and
_getExistingData() should return true if you are passing it a Unique combination of rows or a primary key - depends on the table

I'm afraid that I have lost the plot of what it is you are doing here along the way.
It would help to see what you are doing prior to this function call as well as the MySQL table being used.
 
Top Bottom