Update a database field with Joomla UpdateObject method with a calculated field from same table - model-view-controller

Right to the point.
I need to update a field in the database using the field to calculate the new value first.
E.g of fields: https://i.stack.imgur.com/FADH6.jpg
Now I am using the Joomla updateObject function. my goal is to take the "spent" value from the DB table without using a select statement.
Then I need to calculate a new value with it like (spent + 10.00) and update the field with the new value. Check out the code below:
// Create an object for the record we are going to update.
$object = new stdClass();
// Must be a valid primary key value.
$object->catid = $item['category'];
$object->spent = ($object->spent - $item['total']);
// Update their details in the users table using id as the primary key.
$result = JFactory::getDbo()->updateObject('#__mytable', $object, 'catid');
The bit which i need to make the calculation on is
$object->spent = ($object->spent - $item['total']);
I realise I can use a seperate insert statement but I am wondering if there is a better way. Any help is much appreciated.
It needs to work like this, WITHOUT THE SELECT (working example)
$query = $db->getQuery(true);
$query->select($db->quoteName('spent'));
$query->from($db->quoteName('#__mytable'));
$query->where($db->quoteName('catid')." = ". $item['category']);
// Reset the query using our newly populated query object.
$db->setQuery($query);
$oldspent = $db->loadResult();
// Create an object for the record we are going to update.
$object = new stdClass();
// Must be a valid primary key value.
$object->catid = $item['category'];
$object->spent = ($oldspent - $item['total']);
// Update their details in the users table using id as the primary key.
$result = JFactory::getDbo()->updateObject('#__mytable', $object, 'catid');

The sticking point with trying to use updateObject('#__mytable', $object, 'catid'); is that your query logic needs to reference the column name in the calculation to assign the "difference" as the new value. The raw mysql query syntax to update a column value with the value minus another value is like:
"`spent` = `spent` - {$item['total']}"
updateObject() will convert spent - {$item['total']} to a literal string, the database will expect a numeric value, so UPDATE results in a 0 value recorded. In other words, $db->getAffectedRows() will give you a positive count and there will be no errors generated, but you don't get the desired mathematical action.
The workaround is to discard updateObject() as a tool and build an UPDATE query without objects -- don't worry it's not too convoluted. I'll build in some diagnostics and failure checking, but you can remove whatever parts that you wish.
I have tested the following code to be successful on my localhost:
$db = JFactory::getDBO();
try {
$query = $db->getQuery(true)
->update($db->quoteName('#__mytable'))
->set($db->quoteName("price") . " = " . $db->qn("price") . " - " . (int)$item['total'])
->where($db->quoteName("catid") . " = " . (int)$item['category']);
echo $query->dump(); // see the generated query (but don't show to public)
$db->setQuery($query);
$db->execute();
if ($affrows = $db->getAffectedRows()) {
JFactory::getApplication()->enqueueMessage("Updated. Affected Rows: $affrows", 'success');
} else {
JFactory::getApplication()->enqueueMessage("Logic Error", 'error');
}
} catch (Exception $e) {
JFactory::getApplication()->enqueueMessage("Query Syntax Error: " . $e->getMessage(), 'error'); // never show getMessage() to public
}
Here is a StackOverflow page discussing the mysql subtraction logic: update a column by subtracting a value

Related

Writing 100 rows form oracle database using powershell

I have an problem using powershell .
first i would like to explain what the sitiation is :
I have an Oracle database running with an table NAMES . In the table i got about 10000 rows with data . I would like to to count them til 100 rows and and then "echo " them on my powershell prompt here is where the problem comes in because i can count the rows using the following script:
$query = “SELECT * FROM NAMES"
$command = $con.CreateCommand()
$command.CommandText = $query
$result = $command.ExecuteReader()
$test= $result|Measure-Object
$i=$test.Count
The number that returns is the correct number but then it goes wrong because when i want to use an foreach loop i cant get the names from my table
Here is wat i got maybey it helps
foreach ($Row in $query.Tables[0].Rows)
{
write-host "value is : $($Row[0])"
}
hope someone finds an answer
You are missing the strict mode: Set-StrictMode -Version latest. By setting it, you'd get much more informative an error message:
$query = "SELECT * FROM NAMES"
foreach ($Row in $query.Tables[0].Rows) { ... }
Property 'Tables' cannot be found on this object. Make sure that it exists.
+ foreach ($Row in $query.Tables[0].Rows) { ... }
The $query variable doesn't contain member Tables, so attempting to read it is futile. It would seem likely that the $result variable contains the Tables member. That depends on the data provider you are using and what's missing on the code sample.

jqGrid How to use EditUrl

I'm using jqGrid to maintain a database in MySQL using jSON data. I'm able to display the data in the grid but when I try to add or edit a data row through the modal form I get a message saying "Url is not set". But what is the editurl suppose to contain? mysql insert statements? I'm using the grid's predefined add and edit functions.
Also, if you take a look at the trirand demo page under Manipulating then under Grid Data. They specify their url as url:'server.php?q=2' and their editurl:"someurl.php" They never say what the someurl.php contains. This is where I get lost and I can't find a resource to give me any hints as to what is suppose to be in the editurl php file.
Thanks for any advice.
UPDATE:
Code in my editurl php file: I put the POST values from the col model in variables. I only need insert and update statements in the switch statement. Take a look at my insert statement to see which one I should be using. I also have to make you aware that I'm not listing all the columns in the database but I'm listing all the columns that the user sees in the grid. The first insert statement is commented and it states the columns that the values are suppose to be inserted based on their order. The second insert statement is following the order that is in the database. Where you see ' ' are the columns that I didn't want to display to the data grid for the user to see because that information wasn't relevant.
<?php
$dbhost = "localhost";
$dbuser = "root";
$dbpass = "**********";
$dbname = "codes";
// connect to the database
$mysql_connect($dbhost, $dbuser, $dbpass) or die("Connection Error: " . mysql_error());
mysql_select_db($dbname) or die("Error conecting to db.");
$div = $_POST['div_id'];
$l2 = $_POST['l2_id'];
$l1l2 = $_POST['l1l2_id'];
$l1l3 = $_POST['l1l3_id'];
$l2l3 = $_POST['l2l3_id'];
$beg = $_POST['exec_beg'];
$end = $_POST['exec_end'];
$csa = $_POST['csa_id'];
$area = $_POST['area_id'];
$areadesc = $_POST['area_desc'];
$shortdesc = $_POST['short_desc'];
$longdesc = $_POST['long_desc'];
$enabled = $_POST['avail_ind'];
switch($_POST['oper'])
{
case "add":
$query = "INSERT INTO divcodes values ($div,'',$l1l2,$l2,$l1l3,$l2l3,$beg,$end,'',''$csa,$area,$areadesc,$shortdesc,$longdesc,$enabled,'','','','','',''";
$run = mysql_query($query);
break;
case "edit":
//do mysql update statement here
break;
}
When I set the editurl to my php file and I try to add new row of data to the grid it gives me internal server error 500. I don't know how to debug it any further and the error 500 is such a general error.
I thought that since I was using the predefined operations of the grid (add/edit) that the grid would just know to perform an insert or update statement into my database but it looks like that's not the case?
UPDATE TAKE 2: I changed the syntax to use the mysqli extension. Once I restructured my insert statements I stopped getting the 'Internal Server Error Code 500'. When I click add new record then fill in test data then click on submit the modal window disappears like the data has been added to the grid. But no where in the grid can I find the data (maybe the grid is not reloading with the new data). I checked phpmyadmin and the new row is no where to be found. When I edit an existing row and click submit the dialog box stays open but I'm not getting the error 500 which is a relief.
<?php
$dbhost = "localhost";
$dbuser = "root";
$dbpass = "**********";
$dbname = "codes";
// connect to the database
$conn = mysqli_connect($dbhost, $dbuser, $dbpass) or die("Connection Error: " . mysql_error());
mysqli_select_db($conn,$dbname) or die("Error conecting to db.");
$div = $_POST['div_id'];
$l2 = $_POST['l2_id'];
$l1l2 = $_POST['l1l2_id'];
$l1l3 = $_POST['l1l3_id'];
$l2l3 = $_POST['l2l3_id'];
$beg = $_POST['exec_beg'];
$end = $_POST['exec_end'];
$csa = $_POST['csa_id'];
$area = $_POST['area_id'];
$areadesc = $_POST['area_desc'];
$shortdesc = $_POST['short_desc'];
$longdesc = $_POST['long_desc'];
$enabled = $_POST['avail_ind'];
switch($_POST['oper'])
{
case "add":
$query = "INSERT INTO divcodes (div_id,l1l2_id,l2_id,l1l3_id,l2l3_id,exec_beg,exec_end,csa_id,area_id,area_desc,short_desc,long_desc,avail_ind) values ($div,$l1l2,$l2,$l1l3,$l2l3,$beg,$end,$csa,$area,$areadesc,$shortdesc,$longdesc,$enabled)";
mysqli_query($conn,$query);
break;
case "edit":
$query = "UPDATE divcodes SET div_id=$div,l1l2_id=$l2,l2_id=$l1l2,l1l3_id=$l2l3,l2l3_id=$l2l3,exec_beg=$beg,exec_end=$end,csa_id=$csa,area_id=$area,area_desc=$areadesc,short_desc=$shortdesc,long_desc=$longdesc,avail_ind=$enabled";
mysqli_query($conn,$query);
break;
}
?>
The editurl is the PHP file that will do your INSERTS, UPDATES and DELETES.
There are several parameters passed to this file including the parameter: oper which will be either add, edit or del depending on which operation you did.
In your PHP file (the editurl file) I would just do a switch:
switch ($_POST["oper"]) {
case "add":
// do mysql insert statement here
break;
case "edit":
// do mysql update statement here
break;
case "del":
// do mysql delete statement here
break;
}
Also passed to that file will be all of your data from that row in name:value pairs, just like the oper parameter. The name will be the index property you defined in your colModel array when you setup your grid.
So if you had a column (from the colModel) that looked like:
{
name: 'name1',
index: 'name1',
width: 95,
align: "center",
hidden: false
}
In your editurl PHP file, you can access that column's value to build your queries above by using:
$_POST["name1"]
Hope this helps and let me know if you have any further questions. I struggled with this part of jQGrid just like you are so I know the pain!! lol
UPDATE
Your MySQL Insert statement is incorrect. You do not need to include every column in that exists in your table, just the ones that are required (the columns that can't be null).
For instance, I have a table (tableName) with three columns:
ID (required, not null)
Name (required, not null)
Phone (not required)
If I want to perform an insert onto this table, but I don't want to insert anything into the Phone column, my Insert statement would look like:
INSERT INTO tableName (ID, Name) VALUES (123, "Frank")
On the left side of VALUES is where you specify which columns you will be inserting into. On the right side of VALUES are the actual values we will be inserting.
Here is a simple, helpful link on MySQL syntax: http://www.w3schools.com/php/php_mysql_insert.asp
As you can see, in that first example on that link, they don't specify which columns, meaning they will be inserting data into ALL columns. In your case, that is not what you want, so I would check out their second example, which does specify the columns you are inserting into.

How do I select a single row in Magento in a custom database for display in a block?

I don't want to use foreach to loop through an array of multiple rows, as I am planning on only displaying only one row and using a variable. I can't find information for this online.
What doesn't work
$param = $this->getRequest()->getParam('manufacturer');
$extrabrand = Mage::getModel('brands/brands')->getCollection();
$extrabrand->addFieldToFilter('attributelabelid', $param);
//$extrabrand->setAttributelabelid($param);
$extrabrand->load();
Fatal error: Call to undefined method
Desbest_Brands_Model_Mysql4_Brands_Collection::getDescription() in
/home/desbest/public_html/clients/magentofull/app/design/frontend/default/default/template/Desbest_Brands/brand_info.phtml
on line 20
Plus there is no EAV.
Without seeing the code in brand_info.phtml it's hard to say what the problem is, but my guess is you're using the collection in $extrabrand as though it were a model. Try this instead
//get the parameter from the request
$param = $this->getRequest()->getParam('manufacturer');
//instantiate the brand/brand model, and use
//its `getCollection` method to return a collection
//object
$collection = Mage::getModel('brands/brands')->getCollection();
//add the paramater as a filter
$collection->addFieldToFilter('attributelabelid', $param);
//get the first item of the collection (load will be called automatically)
$extrabrand = $collection->getFirstItem();
//look at the data in the first item
var_dump($extrabrand->getData());
If you need to get only 1 element (first) from the collection, use current() function:
$param = $this->getRequest()->getParam('manufacturer');
$extrabrandCollection = Mage::getModel('brands/brands')->getCollection()
->addFieldToFilter('attributelabelid', $param);
$extrabrand = current($extrabrandCollection->getItems());

doctrine 2 findby function , get keys and values

can i get the keys and values dynamically.
in php, you would: foreach ($array as $key => $value)
but you can do this for :
$this->_em->getRepository('Members')->findBy(array('id' =>5));
any way to get the keys from this with their values..?
i can do this by turning it into an array and extract it but i wouldnt get any association results inside the array ..
i want to do this as i want to be able to extract all properties and values of this object and extract all other objects within it too..
Ih had the same issue as you now have and after some research i just found a solution which you might be interested.what you need is an associative array of keys/values and not an object.findBy()method only returns entity OBJECT.so you will need to use DQL(doctrine query language).
//create a QueryBuilder instance
$qb = $this->_em->createQueryBuilder();
$qb->add('select', 'a')
//enter the table you want to query
->add('from', 'Members a')
->add('where', 'a.id = :id')
//order by username if you like
//->add('orderBy', 'a.username ASC')
//find a row with id=5
->setParameter('id', '5');
query = $qb->getQuery();
//if you dont put 3 or Query::HYDRATE_ARRAY inside getResult() an object is returned and if you put 3 an array is returned
$accounts = $query->getResult(3);
from doctrine documentation:
13.7.4. Hydration Modes
Each of the Hydration Modes makes assumptions about how the result is
returned to user land. You should know about all the details to make
best use of the different result formats:
The constants for the different hydration modes are:
Query::HYDRATE_OBJECT
Query::HYDRATE_ARRAY
Query::HYDRATE_SCALAR
Query::HYDRATE_SINGLE_SCALAR
To learn more about 'The Query Builder' please refer to doctrine2 documentation
Update:
To fetch associated Entities you will need to define fetch joins.Here is an example provided in doctrine documentation:
$dql = "SELECT b, e, r, p FROM Bug b JOIN b.engineer e ".
"JOIN b.reporter r JOIN b.products p ORDER BY b.created DESC";
$query = $entityManager->createQuery($dql);
$bugs = $query->getArrayResult();
foreach ($bugs AS $bug) {
echo $bug['description'] . " - " . $bug['created']->format('d.m.Y')."\n";
echo " Reported by: ".$bug['reporter']['name']."\n";
echo " Assigned to: ".$bug['engineer']['name']."\n";
foreach($bug['products'] AS $product) {
echo " Platform: ".$product['name']."\n";}
echo "\n";}
The code mentioned above will fetch your entities as array of arrays and you can do whatever you want with $keys and $values.
Hope this helps...

PHP - How to accomplish this if?

I am creating an order cart.
On the page that displays the cart, it checks if a value stored in the session $order corresponds with an id of a row in a mysql table. If this match exists, then the corresponding row is returned.
Within this process, I am trying to retrieve the quantity value stored in the session $quantity that corresponds to the id of the row in the table.
Each value in $order and $quantityis assigned a name, which is the id of the item they were added from.
This is the code that adds the order to the cart:
if (isset($_POST['action']) and $_POST['action'] == 'Order')
{
// Add item to the end of the $_SESSION['order'] array
$_SESSION['order'][$_POST['id']] = $_POST['id'];
$_SESSION['quantity'][$_POST['id']] = $_POST['quantity'];
header('Location: .');
exit();
}
This is the code on the cart page:
foreach ($order as $item)
foreach ($quantity as $amount)
{
mysql_data_seek( $productsSql, 0); //<- this line, to reset the pointer for every EACH.
while($row = mysql_fetch_assoc($productsSql))
{
$itId = $row['id'];
$itDesc = $row['desc'];
$itPrice1 = $row['price1'];
if ($item == $itId)
{
$pageContent .= '
<tr>
<td>'.$itDesc.'</td>
<td>'.if ($item[''.$itId.''] == $amount[''.$itId.'']) {echo $amount}.'</td>
<td>R'.number_format($itPrice1*$amount, 2).'</td>
</tr>
';
}
}
}
This row is producing a syntax error:
<td>'.if ($item[''.$itId.''] == $amount[''.$itId.'']) {echo $amount}.'</td>
What is the problem here for starters?
Secondly, how would I need to do to accomplish the task that I am facing?
Any input on this would be greatly appreciated!
Could you try this?
<td>'.($item[$itId] == $amount[$itId] ? $amount : '').'</td>
This is a ternary operator, look at http://en.wikipedia.org/wiki/Ternary_operation
You can't simply add conditional statements like that while you're building a string.
You can do this, however
<td>' . ($item[$itId] == $amount[$itId]) ? $amount : null . '</td>
but you should use a more legible method.
Another issue you may get is if $amount is an array, you won't be able to print it as a string. If, however, $amount is an object with ArrayAccess interface, you can print it with the __toString() method; but that's another story.
The code for creating the cart page has several issues.
You walk over items and over quantities, which will probably give you duplicate outputs.
$item is a plain string, so I wonder what $item[$itId] is supposed to do?
You walk over your complete result set several times which actually is not necessary. I really hope that "$productSql" isn't a "select * from product", otherwhise this might get REAL slow in production mode.
I suggest creating a good SQL for getting the data and using this as a basis for filling the page:
// note this has SQL-injection issues, so you really need to make sure that $order contains no crap
$productsSql = mysql_query("select * from product where id in (".join($order, ',').")");
// you now have a result set with all products from your order.
while($row = mysql_fetch_assoc($productsSql))
{
$itId = $row['id'];
$itDesc = $row['desc'];
$itPrice1 = $row['price1'];
// session contains the quantity array mapping ID -> Quantity, so grab it from there
$itQuantity = $quantity[$itId];
// finally calculate the price
$itPrice = number_format($itPrice1*$itQuantity, 2);
// now you have all data for your template and can just insert it.
// if you use double quotes you can put the $xyz into the string directly
$pageContent .= "
<tr>
<td>$itDesc</td>
<td>$itQuanty</td>
<td>R $itPrice</td>
</tr>
";
}

Resources