Simple Machines Community Forum

Customizing SMF => SMF Coding Discussion => Aiheen aloitti: The Wizard - helmikuu 17, 2014, 07:51:01 AP

Otsikko: Database advice
Kirjoitti: The Wizard - helmikuu 17, 2014, 07:51:01 AP
Hello:

Objective: Allow the admin to change the "prices" or quantity of toys in "stock".

Below is what I have so far in writing the Subs code, and the completed template function code I have written.

My question - will it allow the admin to change the data of a single toy, or will it allow the admin to change the data on multiple toys at once?

As you might have guessed I want  to change the data on multiple toys at once.

I am a little leery of just testing this idea as I don't want to screw up the tables and have to do a lot of unnecessary work fixing them.
So I am asking here first.

Thanks

Wiz



Subs-Toy_Shop_Admin

$_POST['price'] = (int) $_POST['price'];
$_POST['stock'] = (int) $_POST['stock'];

$smcFunc['db_query']('', "
UPDATE {db_prefix}shop_items
SET stock = stock, price = price
array(
'price' => $_POST['price'],
'stock' => $_POST['stock'],
));



Template Function Code

function toy_shop_admin_edit_toy()
{
global $txt, $context, $boardurl, $modSettings, $scripturl;

echo '
<div class="cat_bar">
<h3 class="catbg" align="center">', $txt['toy_shop_admin_items_edit'], '</h3>
</div>
<div class="windowbg">
<span class="topslice"><span></span></span>
<div class="content" style="height:auto;min-height:', $context['toy_shop_box_height'],'px;">

<form action="', $scripturl, '?action=admin;area=toyshop;sa=shop_admin_items_edit_part_2" method="post">
<table align="center" class="wizards_shop_5px_padding">
<tr valign="top">
';

$i = 0;

foreach ($context['toy_shop_inv']['items'] as $item)
{
if (empty($item))
continue;

$i++;

$name  = $item['name'];

echo "
<td>
<script language='javascript' type='text/javascript'>
function load".$i."(){
var load = window.open('" . $boardurl . "/Themes/default/toy shop images/big/" . $item['image'] . "', ' ', 'scrollbars=no,menubar=no,height=300,width=300,resizable=no,toolbar=no,location=no,status=no');
}
</script></td>
";

echo '
<td align="left" valign="top">
<a href="javascript:load'.$i.'()">
<img width="', $modSettings['shopImageWidth'], '" height="', $modSettings['shopImageHeight'], '" src="' . $boardurl . '/Themes/default/toy shop images/small/' . $item['image'] . '" align="left" alt="Item Image"/>
</a>
</td>
<td>
', $name, '
<br /><font color="green"><label for="price">', $txt['toy_shop_price'], ' : </label></font>
<input type="text" size="5" name="price" id="price" value="', $item['price'], '" />
<br /><font color="orange"><label for="stock">', $txt['toy_shop_stock'], ': </label></font>
<input type="text" size="5" name="stock" id="stock" value="', $item['stock'],'" /><br />
</td>
';

$wiz = 3;

if ($i % $wiz == 0)
echo '</tr><tr>';
}

// Do not remove code <td></td></tr></table> or The W3C validator will be very unhappy!
echo '<td></td></tr></table>
<center>
<input type="submit" value="', $txt['toy_shop_admin_save_changes'], '" />
</center>
</form>
<br />';

if (isset($context['toy_shop_inv']['pages']['current']) && isset($context['toy_shop_inv']['pages']['total']))
{
echo '
<table align="center"><tr><td><strong>', $txt['toy_shop_pages'] ,'</strong>';

if ($context['toy_shop_inv']['pages']['current'] != 1)
{
$prevPage = $context['toy_shop_inv']['pages']['current'] - 1;
echo '
<a href="', $context['toy_shop_inv']['pages']['link'], ';page=', $prevPage, '">', $txt['toy_shop_back'], '</a>';
}
else
echo '
', $txt['toy_shop_back'], '';

for ($x = 1; $x <= $context['toy_shop_inv']['pages']['total']; $x++)
{
if ($x == $context['toy_shop_inv']['pages']['current'])
echo '
<strong>', $x, '</strong>';
else
echo '
<a href="', $context['toy_shop_inv']['pages']['link'], ';page=', $x, '">', $x, '</a> ';
}

if ($context['toy_shop_inv']['pages']['current'] != $context['toy_shop_inv']['pages']['total'])
{
$nextPage = $context['toy_shop_inv']['pages']['current'] + 1;
echo '
<a href="', $context['toy_shop_inv']['pages']['link'], ';page=', $nextPage, '">', $txt['toy_shop_next2'], '</a> ';
}
else
echo '
', $txt['toy_shop_next2'], ' ';
}

echo '
</td>
</tr>
</table>
</div>
<span class="botslice"><span></span></span>
</div>
';
}
Otsikko: Re: Database advice
Kirjoitti: margarett - helmikuu 17, 2014, 09:30:07 AP
You need to do some extra work to allow it to change all at once...

The way you have it:
<input type="text" size="5" name="price" id="price" value="', $item['price'], '" />
All your "prices" will be the same (as all the inputs have the same name) so you will only get one after submit.

You need to so something like:
<input type="text" size="5" name="price_', $item['id'], '" id="price_', $item['id'], '" value="', $item['price'], '" />
So each input is unique. When you submit, your $_POST will have some "price_xx" variables. You can then use something like "stristr" to extract the ID of the price input and deal with it accordingly.

Also, you need a WHERE clause. The way to have it right now it will put the same value in all the items. Plus, you need to
SET stock = {int:stock}, price = {int:price}
And you should probably $smcFunc with insert/replace instead...

LainaaI am a little leery of just testing this idea as I don't want to screw up the tables and have to do a lot of unnecessary work fixing them.
And, at the 7th day, God invented backups ;D ;D ;D
Otsikko: Re: Database advice
Kirjoitti: The Wizard - helmikuu 17, 2014, 07:14:17 IP
Ok I tryed this -

<input type="text" size="5" name="',$item['id'],'" value="', $item['stock'], '" /><br />



$smcFunc['db_query']('', "
UPDATE {db_prefix}shop_items
SET stock = {int:stock}
WHERE id = {int:id}",array(
'id' => $_POST['id'],
));


and got this error - Numeric request keys are invalid.

So where did I go wrong and how can I fix it?

Wiz
Otsikko: Re: Database advice
Kirjoitti: margarett - helmikuu 17, 2014, 07:35:18 IP
Are you sure $_POST['id'] exists?

You will have something like $POST['price_99'] for item with ID 99, for sure. 'id', on its own, not so sure... So you need to extract it with something like:

$array_ids = array();
foreach ($_POST as $key => $value)
if (stristr($key, 'price_'))
{
$array_ids[] = array(
'id' => substr($key,6),
'price' => (int)$value,
);
}

You will have a full array with the actual submitted data from your form. Try to print_r it to check ;) Then you can treat it how it best serves you ;)

PS: I've written that directly in the browser. Don't take it too serious :P
Otsikko: Re: Database advice
Kirjoitti: The Wizard - helmikuu 18, 2014, 07:35:03 AP
The following is a recap:

Used this code in the form:

<br /><font color="green"><label for="price">', $txt['toy_shop_price'], ' : </label></font>
<input type="text" size="5" name="price_', $item['id'], '" id="price_', $item['id'], '" value="', $item['price'], '" />

<br /><font color="orange"><label for="stock">', $txt['toy_shop_stock'], ': </label></font>
<input type="text" size="5" name="stock_', $item['id'], '" id="stock_', $item['id'], '" value="', $item['stock'], '" />


Used this code in the Sub:

$array_ids = array();

foreach ($_POST as $key => $value)
if (stristr($key, 'stock_'))
{
$array_ids[] = array(
'id' => substr($key,6),
'price' => (int)$value,
'stock' => (int)$value,
);
}

$context['id'] = $array_ids;


Received the following results:

ID, Price and Stock Amount :

Array ( [0] => Array ( [id] => 1 [price] => 5 [stock] => 5 ) [1] => Array ( [id] => 2 [price] => 5 [stock] => 5 ) [2] => Array ( [id] => 3 [price] => 5 [stock] => 5 ) [3] => Array ( [id] => 4 [price] => 5 [stock] => 5 ) [4] => Array ( [id] => 5 [price] => 5 [stock] => 5 ) [5] => Array ( [id] => 6 [price] => 5 [stock] => 5 ) [6] => Array ( [id] => 7 [price] => 5 [stock] => 5 ) [7] => Array ( [id] => 8 [price] => 5 [stock] => 5 ) [8] => Array ( [id] => 9 [price] => 5 [stock] => 5 ) [9] => Array ( [id] => 10 [price] => 5 [stock] => 5 ) [10] => Array ( [id] => 11 [price] => 5 [stock] => 5 ) [11] => Array ( [id] => 12 [price] => 5 [stock] => 5 ) )

Yes the Data is all correct.

Now the next step: Working on it now will let you all know.



Otsikko: Re: Database advice
Kirjoitti: margarett - helmikuu 18, 2014, 08:02:03 AP
Please note that all your price/stock is 5, so you can not be sure if you are getting the same data or not :P

You are explicitly putting the same (int)$value in both fields stock/price, so they will get the same value and not the value sent from the form...
Otsikko: Re: Database advice
Kirjoitti: The Wizard - helmikuu 18, 2014, 08:11:56 AP
LainaaPlease note that all your price/stock is 5, so you can not be sure if you are getting the same data or not :P
Yep caught that too after I posted and did another test changing the value and it worked.


The following works!
If you can suggest a way to slim down the two foreach's It would be nice. If not I'm happy!



foreach ($_POST as $key => $value)
if (stristr($key, 'price_'))
{
$smcFunc['db_query']('', "
UPDATE {db_prefix}shop_items
SET price = {int:price}
WHERE id = {int:id}",array(
'id' => substr($key,6),
'price' => (int)$value
));
}


foreach ($_POST as $key => $value)
if (stristr($key, 'stock_'))
{
$smcFunc['db_query']('', "
UPDATE {db_prefix}shop_items
SET stock = {int:stock}
WHERE id = {int:id}",array(
'id' => substr($key,6),
'stock' => (int)$value
));
}
Otsikko: Re: Database advice
Kirjoitti: margarett - helmikuu 18, 2014, 10:33:56 AP
That's just terribly ineficient :P You are performing 2 update queries per item. If you show 20 items in a page, you'll run 40 queries :P

You should just build a complete array of stuff and perform a db_insert/replace with the complete array. Not sure exactly how, out of my head...
Otsikko: Re: Database advice
Kirjoitti: The Wizard - helmikuu 18, 2014, 01:30:13 IP
LainaaThat's just terribly ineficient :P You are performing 2 update queries per item. If you show 20 items in a page, you'll run 40 queries :P

For the record I have limited my design to only display 12 Toys at a time anywhere. While this does not solve the overall large number of queries running at one time it does limit the issue.

I would like to point out that I started off with the original smf shop mod that was created before smf 2.0 even existed, or was thought of. Then you add the fact that I am trying to create a graphic stye interface mod to smf which is a text style system, and I am amazed that I have gotten as far as I have. Plus I'm not even in most basic programers league. True I understand some stuff - I still have a lot to learn.

Please don't take any of this the wrong way I am indebted to you for all the help you, and others have given me. I do truly believe that once this mod is completed that many smf admins and users will enjoy and benefit from it - that's my hope anyway :).

Wiz