The php web script that I’m using, and trying to modify, allows video purchases successfully and splits the paid amount with the video uploader.
When UserA purchases a video for 2 Credits (for example); the code successfully deducts 2 Credits from UserA web site Credit balance, and successfully adds 1 Credit (50%) to UserB’s (video uploader) Credit balance.
However, currently, if UserA purchases a video (his own video) for 2 Credits (for example); the code successfully deducts 2 Credits from UserA web site Credit balance, but does not add 1 Credit (50%) to UserA’s (video uploader) Credit balance.
I’d like help to remedy this so that when a User purchases his own video (for whatever reason) the code will successfully add the (50%) Credit to his own User (video uploader) Credit balance, (just like it does when another User purchases).
Here’s the current code:
$db->startTransaction();
$inserted_records = 0;
foreach ($id_array as $id){
$video_id = (int)PT_Secure($id);
// get video data
$video = $db->where('id', $id)->getOne(T_VIDEOS);
// use the video play price if any, or the default price
$video_cost_new = $video->video_play_price?$video->video_play_price:$video_cost;
// credit the user 50% of the video cost
$uploader_amount = $video_cost_new *0.50;
$time_start = microtime(true);
// add data to paid table
$insert_buy = $db->insert('paid_videos', [
'id_user' => $user_id,
'video_play_price' => (string)$video_cost,
'id_video' => $video_id,
'user_id_uploaded' => $video->user_id, // user who uploaded video
'video_title' => $video->title,
'earned_amount' => $uploader_amount,
'time' => $time_start,
'session_key' => $_SESSION['session_key']
]);
// count successful inserted records
if ($insert_buy) {
$inserted_records++;
}
//update the 'balance' of the user who uploaded video
// get the user's record
$userwallet = $db->where('id', $video->user_id)->getOne(T_USERS);
// add to the balance
$videouserwallet = $userwallet->balance+$uploader_amount;
// update the record
$db->where('id', $video->user_id);
$update_balance = $db->update(T_USERS, [
'balance' => number_format($videouserwallet, 1, '.', ''),
]);
}
It might be me, but I can’t see anything in that code that has any awareness of whether the uploader is the same user as the downloader, and can’t see any reason that it wouldn’t work the same way if it is as it does when it is not.
First, a laundry list of problems in just the posted code (probably repeating some things you have already been told) -
The query that deducts the credits from the purchaser’s wallet needs to be part of the transaction you are showing in this code. All these related queries must either succeed or they must all be rolled-back.
While I doubt the PT_Secure function is actually as secure as the original author of this script thinks, casting the value to an int at least means the submitted value is safe to use in the rest of the code. The rest of the posted code should use $video_id, not $id.
$video_cost_new should be used in the rest of the code. The current code is inserting the default $video_cost into the paid_videos table. It would probably help if most of these variables were better named as to the meaning of the data in them.
The 50% multiplier should be a configuration value, not hard-coded.
The INSERT query contains derived/redundant/unnecessary values. This query is recording the information about the purchase of an item. It should have just the unique/one-time - who (purchased the item), what (was purchased), when (the purchase was made), where (the purchase was made from - it’s customary to record the visitor’s ip address for just about everything that occurs on the web), and why (a status/memo value) information. For the posted code, the video_pay_price, user_id_uploaded, video_title, and earned_amount are all derived values and are known based on the video id (since this script lacks any way of tracking price changes or the earned amount percentage change, you may need to record some of these values with the purchase to provide an audit trail.) Any data related to the purchase of an item should use the last insert id from this INSERT query (see the next point.)
Next, on to what could be occurring. Sometime in the last few months, you were told that every operation that modifies the credits/money of a user needs to be done by inserting a row into an ‘accounting’ table, rather than to just update a value in a column. The reason you were given for doing this was so that you have a record, an audit trail, of everything that modifies the value, and were further told this is so that you can detect if a programming mistake, a duplicate form submission, or nefarious activity modified a value. Since the code isn’t doing that, you don’t really know why the data isn’t what you expect. All you are seeing is the end result of all the code running or not running. It could be that the UPDATE query is adding the amount to the wallet, but some other code could be deducting the amount or could be updating the amount back to the original value.
Since ti is doubtful you will (be able to) change the design to do this, to debug this problem, you will need to add logic at each update query in the code that is modifying the user’s wallet amount so that you can log all the relevant information so that you can see what is actually occurring.
You probably have nested transactions, where the commit for the query that’s deducting the amount from the purchaser’s wallet is updating the amount back to the deducted value (for all we know, that query could be after the posted code.) When the purchase user and the upload user are different, these are two different rows. When the users are the same, this is a single row. The last commit ‘wins’.
This in itself points out a problem with the use of this code’s database layer. If you did have a good reason to modify a value in a column, you would not first select it, modify it, then update it. You would just update the value directly in one query by adding or subtracting from the current value. The update method apparently doesn’t support doing anything like this and you would need to use the ‘raw’ (I don’t remember what it is actually called) query method.
Again, your posting of out of context snippets of code doesn’t tell the whole story and you are somehow thinking we are aware of everything this code is doing. This makes it difficult to help you.