dynamic calculation of simple math expression - php

We are taking simple math expression as inputs from user and want to evaluate it. Total number of fields are also dynamic. Each field contains the specific css class as per their index. For example, 1st field has css field "col1", 2nd field has "col2" and so on.
Users gives us input in the form of
"col5 = col4 * col3"
We are converting it to
jQuery(".col5").val(jQuery(".col4").val() * jQuery(".col3").val())
using str_replace function. To do so, we need to do loop for total no of fields. (below is php code example)
for($colLoop = 0; $colLoop < $total_cols; $colLoop++){
$formula = str_replace("col$colLoop","parseFloat(jQuery('.col$colLoop input').val())", $formula);
}
This works but we are looking for some proper solution as it's loops unnecessary for all fields. Is it possible using some other methods? Let us know

Related

Order by properly on SNMP oids

I've searched and tried lots of things but I can't find a solution.
I am storing some SNMP OIDs in a database, and displaying them in a table with datatables.
I want the OIDs to be displayed in the correct order so for example:
1.3.6.1.2.1.1
1.3.6.1.2.1.10
1.3.6.1.2.1.2
In correct order would be:
1.3.6.1.2.1.1
1.3.6.1.2.1.2
1.3.6.1.2.1.10
A SQL query with order by on the column storing the OID string would order them:
1.3.6.1.2.1.1
1.3.6.1.2.1.10
1.3.6.1.2.1.2
I'm using serverside processing with either PHP or preferably python flask. Currently I am building the table myself in flask and have written a function that orders them by converting the OIDs to tuples and sorting. This works but I would like to use datatables to get the pagination and responsiveness.
One thing to note is there isn't a limit on the length of the OID.
Any ideas would be much appreciated.
This is kind of a hack, but it might work. If each element in the OID has a max value < 100, then create a second column in the database, where each element is converted to a 2-digit 0-filled value:
real_oid sorting_oid
1.3.6.1.2.1.1 01.03.06.01.02.01.01
1.3.6.1.2.1.10 01.03.06.01.02.01.10
1.3.6.1.2.1.2 01.03.06.01.02.01.02
You could even eliminate the periods to save space, once you tested that is is all working.
First split the string on the period and typecast to int. Then use sorted and operator.itemgetter to sort by multiple attributes. Then re-join using a period. Something like the following:
original_oids = [...]
split_and_typecast_oids = [map(int, oid.split(".")) for oid in original_oids]
sorted_oids = sorted(split_and_typecast_oids, operator.itemgetter(1,2,3,4,5,6,7))
rejoined_oids = [".".join(map(str, oid)) for oid in sorted_oids]

elastica scoring based on regular expression using mvel

I am new to elastic search and here is my scenario I am trying to solve.
I have a search input box that supports autosuggestion logic.
The results are fetched from an elastic index which uses ngram filter.
What I want to improve is to introduce a scoring capability so as to order the results from the most important to the less important one (depending on the score).
The score must be based on the following cases:
If there is a match that starts with the given string, set score 100
If there is a match that contains the given string and does not start with it, set score to 10
For this purpose an elastica script was implemented with mvel statements in order to support regular expression match. In other words, it checks to see if the value on the left matches the regular expression on the right (only then a variable is incremented accordingly). But unfortunately it goes wrong when search string is language specific despite the fact that the value on the left is of the specified language too. Another problem to deal with is the second case I mention above (cannot make it to work).
The script when a value ('one example' (belongs to the name field)) starting with the given word ('one') works just fine.
$testParam = mb_strtolower('one', 'utf-8');
$regexStart = '^' . $testParam . '.*$';
$ElasticaScript = new Elastica_Script(" total = 1; if(doc['name'].value ~= '{$regexStart}'){ total += 100; } return total; ");
The script when a value ('one example' (belongs to the name field)) contain the given word ('example') does not work and as a result total score remains 1 and does not increment to 11 as it should be.
$testParam = mb_strtolower('example', 'utf-8');
$regexStart = '^.*' . $testParam . '.*$';
$ElasticaScript = new Elastica_Script(" total = 1; if(doc['name'].value ~= '{$regexStart}'){ total += 10; } return total; ");
And at last, with the same logic, when I try to match a greek word against a value (containing greek letters) of the name field, the increment of the total score is ignored as well.
All the work has been done using the elastica, let alone php.
Could you please help to solve my problem ?
If there is another approach/solution, feel free to share it with me.
Thank you in advance
doc['name'].value loads the analyzed version of the field. Unless your field is set to not analyzed, this will likely be very different than the original content of the field, and not useful for doing regex matches. The Elasticsearch docs on script fields say this only makes sense for non-analyzed or single term fields. For example, if your content is indexed as ngrams, this value will consist of ngrams.
You can access the original text of the field using _source.field_name, and then compute your score based on that. You can still do your search as usual against the ngrams, and use the _source just for scoring.
Here's a sample function_score query that defaults the score to _score, adds 100 if the name field starts with one, else adds 10 if the name field contains one anywhere else. It uses _source.name to access the contents of the name field, so it's doing the regex against the original text of the name field, not the ngrams calculated from the name field.
{
"query": {
"function_score": {
"boost_mode": "replace",
"script_score": {
"script": "total = _score; if (_source.name ~= '^one.*') { total += 100 } else if (_source.name ~= '.*?one.*?') { total += 10 } return total"
}
}
}
}

LIKE Condition in PHP Not Work correctly

i have a row in my database with name "active_sizes" and i want filter my website items by size, for this, i use LIKE Condition in php :
AND active_sizes LIKE '%" . $_GET['size'] . "%'
but by using this code i have problem
for example when $_GET['size']=7.0 this code shows items that active_sizes=17.0
my active_sizes value looks like 17.0,5.0,6.5,7.5,,
thanks
Using comma-separated values in a single field in a database is indicative of bad design. You should normalize things, and have a seperate "item_sizes" table. As it stands now, you need a VERY ugly where clause to handle such sub-string mismatches:
$s = (intval)$_GET['size'];
... WHERE (active_sizes = $s) // the only value in the field
OR (active_sizes LIKE '$s%,') // at the beginning of the field
OR (active_sizes LIKE '%,$s,%') // in the middle of the field
OR (active_sizes LIKE '%,$s') // at the end of the field
Or, if you normalized things properly and had these individual values in their own child table:
WHERE (active_sizes_child.size = $s)
I know which one I'd choose to go with...
You don't state which DB you're using, but if you're in MySQL, you can temporarily accomplish the same thing with
WHERE find_in_set($s, active_sizes)
at the cost of losing portability. Relevant docs here: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_find-in-set
You Have % signs around your $_GET value. Combined with LIKE, this means that any string that simply contains your get value will be retuned. If you want an exact match, use the = operator instead, without the percentage signs.
This will solve your immediate issue:
AND active_sizes LIKE '" . mysql_real_escape_string($_GET['size']) . "%'
If you are using the database other than MySQL, use corresponding escape function. Never trust input data.
Besides, I'd suggest using numeric field (DECIMAL or NUMERIC) for active_sizes field. This will accelerate your queries, will let you consume less memory, create queries like active_sizes BETWEEN 16.5 AND 17.5, and generally this is more correct data type for a shoe size.

PHP Form Posting Values To Database

Basically, i have a working form where the user inputs details about their laptop to sell to my shop.
I give them a quote once they have submitted the Specs of the laptop.
At the moment i have got option boxes and checkboxes which each have a value-- for example these. ---
<label for="state">State</label><br>
<select name="state">
<option value="10">Excellent</option>
<option value="5">Good</option>
<option value="0">Poor</option>
</select><br>
The Values of the options they have selected get added up at the end and that gives them the quote - in the above example - "10" means £10 extra for a excellent condition laptop etc.
I use $_POST[state] to get the value of it to add onto the other options for the quote.
But my problem lies when i POST them to a database (so we can check when they come in).
When they get added to the database, obviously it just comes out as the values not the actually name of it like "excellent" or "good". just says "10" or "5".
Is there anyway to put the name of the option into the database instead of the value?
sure... just make sure that's what you want to do. It's usually not considered a good database practice to create denormalized tables like that, but you could do it. When you collect your post data, simply create another variable and assign a value to it based off the state value like so:
$stateText = '';
switch ($state){
case 10:
$stateText = 'Excellent';
break;
case 5:
$stateText = 'Good';
break;
case 0:
$stateText = 'Poor';
break;
default:
// bad value
$stateText = '';
}
...then store this to the database in a new column.
This is just one of many ways to do this.
You can only do it if you have a lookup, be it an array or in another table that stores the keys and values.
You should be carefuly not to store the post data directly into your database without sanitizing it, otherwise you might become subject to sql injection.
Is there anyway to put the name of the option into the database instead of the value?
There is, but it involves doing it explicitly (converting "10" into "Excellent" before inserting the value) rather than just basically tossing $_POST into the database as-is. You can make this very simple if you are building the <option>s with an array in the first place by reading the the array again and swapping the values with the keys.
$values = array(
10 => 'Excellent',
5 => 'Good',
0 => 'Poor',
);
$post_value = $_POST['state'];
$db_value = $values[$post_value];
// further validation: make sure the array key exists or use a default value
// further usage: build your HTML <options> with this array
However:
If you're going to do that, you're much better off storing the values as numbers and converting them to words when you display them (assuming the numbers do have some meaning). This also allows you to localize by providing translations.
Response to comments:
I would recommend a rating system, like 1 through 5, and calculate your price modifications internally - not directly from the user input or from a hardcoded value (in the database). This allows you to tweak the price changes from within your app, rather than from database values that were created at an earlier time, like if you decide an "Excellent" condition warrants an increase of 11 rather than 10 - unless you specifically want the prices "locked in" permanently at the time the product was posted.
Whatever you do, make sure to validate the input - I can't think of any good reason to use direct user input to calculate prices - it should be done internally based on product ids, and any other conditions. HTML source can be modified on-the-fly to post values you didn't expect from the dropdown.
You can't get it via the HTML form. But you can still do a server side that would map the values to the appropriate condition.
You can use a switch statement or an if statement to map them.
if(value == 10){
$condition = 'Excellent';
} else {//....}

WordPress: PHP: How to perform a nested sort within a category for the desired results

There is a plugin that I am trying to adapt for my meta_tags for use with WordPress.
It is called Categories by Title by http://www.mikesmullin.com.
What I am trying to achieve is a nested sort. I have three meta_keys. A selection-no, release-month, and release-year. I would like to sort posts within their category by release-year (asc), release-month (asc), then selection-no (asc). For example: 1955 10 selection-no-1, 1956 10 selection-no-2, 1956 10 selection-no-5, and so on.
I have modified the code, however, it only sorts by the last meta_key listed, by release-year.
Here is the code.
add_action('pre_get_posts','sort_categories_by_title');
function sort_categories_by_title($x) {
if(is_category()) {
$x->query_vars['orderby'] = 'meta_value';
$x->query_vars['meta_key'] = 'selection-no';
$x->query_vars['meta_key'] = 'release-month';
$x->query_vars['meta_key'] = 'release-year';
$x->query_vars['order'] = 'asc';
}
}
Any help would be greatly appreciated. Thank you.
Have a look at usort. You supply a comparison function which can look inside each item and choose what to order by.
In your example, every time you do $x->query_vars['meta_key'] you overwrite the previous value, so you're only adding the last meta_key as a selection option.
On top of that WordPress only supports pulling by a single meta_key/meta_value comparison. To get the more complex comparison that you're after you should be filtering on posts_where_paged to add in more comparisons and posts_orderby to construct the order by clause that you need. You'll need a basic knowledge of raw SQL query writing to accomplish this.
You might consider restructuring your data as well and putting the release-date in to a real date format and using typecasting to take the string format of the meta_value and cast it as a date field to then do proper date based sorting operations on it.

Categories