Update process

Ok lets do this from the beginning. I made points_id primary, user_id unique. Now I have my confirm page, what should I be changing in my data writer listed below.

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, 'user_id'))
        {
            return false;
        }
        return array('xshop_points' => $this->getModelFromCache('xShop_Model_Points')->getUserPoints($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();
}
    }*/
}

Ignore the _postDelete portion as that is not going to be used at all.

Next thing, how should my data writer look and should I change anything on my actionConfirm part?

actionConfirm:
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'];

$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);
}
$points_total = $dw->get('points_total');
$new_total = $points_total - $dwInput['item_cost'];
$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::buildPublicLink('shop')
);

    }
 
And my Points model:
PHP:
<?php
class xShop_Model_Points extends XenForo_Model
{
public function getPoints()
{
$pts = $this->_getDb()->fetchAll('
SELECT member.*,  points.* FROM xshop_points AS points
LEFT JOIN xf_user AS member ON (points.user_id = member.user_id)
');

return $pts;
}

public function getPointsId($points_id)
{
$pointsById = $this->_getDb()->fetchRow('
SELECT member.*, points.*
FROM xshop_points AS points
LEFT JOIN xf_user AS member ON (points.user_id = member.user_id)
WHERE points_id = ?
', $points_id);

return $pointsById ? $pointsById : false;
}
public function getUserPointsId($points_id)
{
return $this->_getDb()->fetchRow('
SELECT *
FROM xshop_points
WHERE points_id = ?
', $points_id);

}
    public function hasData($id)
    {
        return $this->_getDb()->fetchOne('SELECT COUNT(*) FROM xshop_points WHERE points_id = ?', $id);
    }
public function getUserPoints($userId)
{
$userPoints = $this->_getDb()->fetchRow('
SELECT *
FROM xshop_points
WHERE user_id = ?
', $userId);

return $userPoints;
}
public function invStock($visitor_id)
{
$allInv = $this->_getDb()->fetchAll('
SELECT COUNT(*)
FROM xshop_stock
WHERE member_id = ?
', $visitor_id);

return $allInv;
}
public function allStock($visitor_id)
{
$stock = $this->_getDb()->fetchAll('
SELECT *
FROM xshop_stock
WHERE member_id = ?
', $visitor_id);

return $stock;
}
}
?>
 
Made a couple of changes to above post. See Capital letter comments about negative value if a new insert.
 
Ok tested, but the points_total is replacing the total with the new total. This is the issue I have had since I started on the purchasing process.
 
Like I said all along....you have points_total in the table and coming into actionConfirm()
I assume these are not the same., If so you need to rename one. Since I have no idea how all these points link together I must leave the logic of it all up to you.
 
points_total is the same, comes from the same table and only have it in one table. Points total I can remove from going into the actionConfirm and test.

Ok I removed it from the template and the action, still same issue.
 
the points_total is replacing the total with the new total.
I thought the whole idea was to save the new total in the points_total field of that specific user's table.
Someone purchased something so you reduce their total by that amount. Is that not it?
 
The only way the total amount will not change for an existing table is if the 'total_cost' was zero.
Are you passing a positive integer for that value? A negative will not work as is because your input grabs a UINT
 
Hmm, I have item_cost set for the item as 5 so it should subtract 5 from the points_total which is the points a user has remaining to spend.
 
Well since I don't have this code installed, you will have to debug it by stopping the code
1). After $points_total = $exists['points_total']; to see what value you get for $points_total
2). Then after $new_total = $points_total - $dwInput['item_cost']; for $new_total
 
Top Bottom