Return empty strings in woocommerce checkout form - forms

I'd like to return empty strings on all checkout form field but one (the billing_country one).
I already know how to do it with all fields :
add_filter('woocommerce_checkout_get_value','__return_empty_string', 1, 1);
And how to do it with only one field:
add_filter('woocommerce_checkout_get_value','custom_checkout_get_value_ship_ville', 10, 2);
function custom_checkout_get_value_ship_ville( $value, $imput ){
if($imput == 'shipping_city')
$value = '';
return $value;
}
But for all but one ... I'm a little stucked.
I succeed by duplicating and adapting the previous function, but it's a lot of code for just returning empty strings.
I tried with else, elsif, switch and with logical operators, but no result.
So if someone have some clue ...
Thanks

If you want to return empty strings on every value of $imput except for one specific value you need to reverse the comparison of your second code snippet. So instead of comparing wether the $imput is equal to a value you compare wether the $imput is NOT equal to a value.
You can read up on this comparison here: http://php.net/manual/en/language.operators.comparison.php
You can also just return an empty string directly without assigning it to a variable:
add_filter('woocommerce_checkout_get_value','custom_checkout_get_value_ship_ville', 10, 2);
function custom_checkout_get_value_ship_ville( $value, $imput ){
if($imput != 'billing_country') {
return '';
}
}

Related

Update scalar variable globally inside if statement in Perl?

I'm trying to update a variable declared and used outside of a series of if / elsif / else statements, and updating it within the series. Is there a functional way to make this sorting/updating variable work?
my $daterange = 'initial';
if ($in{from_date} & $in{to_date}) {
my $daterange=~"AND (date BETWEEN '$fromdate' and '$todate')";
}
elsif ($in{from_date}) {
my $daterange=~"AND (date > '$fromdate')";
}
elsif ($in{to_date}) {
my $daterange=~"AND (date < '$todate')";
}
else {
my $daterange=~"blank";
}
print $daterange;
my creates a new variable. That means that inside your "then` clauses, you create a new variable, then assign a string to it. You never use that variable again!
You want to assign to the existing variable, so stop creating new ones with the same name.
There are numerous other problems with your code:
Your code suffer from SQL injection bugs.
You used =~ to assign to a variable when the assignment operator is =.
You used & to check if two value are true when the logical-AND operator is &&.
You used "blank" to create an empty string when it doesn't.
You sometimes use $in{from_date} and sometimes $fromdate.
You sometimes use $in{to_date} and sometimes $todate.
You assign an initial value (initial) to $daterange that you never end up using.
You have some useless parentheses in your SQL.
Fixed:
my $daterange;
if ($in{from_date} && $in{to_date}) {
$daterange = " AND (date BETWEEN ".$dbh->quote($in{from_date})." AND ".$dbh->quote($in{to_date}).")";
} elsif ($in{from_date}) {
$daterange = " AND date > ".$dbh->quote($in{from_date});
} elsif ($in{to_date}) {
$daterange = " AND date < ".$dbh->quote($in{to_date});
} else {
$daterange = "";
}
Delete all my except the first one.
This prevents one local variable being introduced for each {}, which is then unknown outside.
That way, the accesses inside the {} will affect your global variable.
As c3st7n noted (thanks), you will also have to doublecheck what you actually do to your variable, it is likely that it is not what you intended. I.e. you probably want to use = instead of =~.

What's wrong with my Meteor publication?

I have a publication, essentially what's below:
Meteor.publish('entity-filings', function publishFunction(cik, queryArray, limit) {
if (!cik || !filingsArray)
console.error('PUBLICATION PROBLEM');
var limit = 40;
var entityFilingsSelector = {};
if (filingsArray.indexOf('all-entity-filings') > -1)
entityFilingsSelector = {ct: 'filing',cik: cik};
else
entityFilingsSelector = {ct:'filing', cik: cik, formNumber: { $in: filingsArray} };
return SB.Content.find(entityFilingsSelector, {
limit: limit
});
});
I'm having trouble with the filingsArray part. filingsArray is an array of regexes for the Mongo $in query. I can hardcode filingsArray in the publication as [/8-K/], and that returns the correct results. But I can't get the query to work properly when I pass the array from the router. See the debugged contents of the array in the image below. The second and third images are the client/server debug contents indicating same content on both client and server, and also identical to when I hardcode the array in the query.
My question is: what am I missing? Why won't my query work, or what are some likely reasons it isn't working?
In that first screenshot, that's a string that looks like a regex literal, not an actual RegExp object. So {$in: ["/8-K/"]} will only match literally "/8-K/", which is not the same as {$in: [/8-K/]}.
Regexes are not EJSON-able objects, so you won't be able to send them over the wire as publish function arguments or method arguments or method return values. I'd recommend sending a string, then inside the publish function, use new RegExp(...) to construct a regex object.
If you're comfortable adding new methods on the RegExp prototype, you could try making RegExp an EJSON-able type, by putting this in your server and client code:
RegExp.prototype.toJSONValue = function () {
return this.source;
};
RegExp.prototype.typeName = function () {
return "regex";
}
EJSON.addType("regex", function (str) {
return new RegExp(str);
});
After doing this, you should be able to use regexes as publish function arguments, method arguments and method return values. See this meteorpad.
/8-K/.. that's a weird regex. Try /8\-K/.
A minus (-) sign is a range indicator and usually used inside square brackets. The reason why it's weird because how could you even calculate a range between 8 and K? If you do not escape that, it probably wouldn't be used to match anything (thus your query would not work). Sometimes, it does work though. Better safe than never.
/8\-K/ matches the string "8-K" anywhere once.. which I assume you are trying to do.
Also it would help if you would ensure your publication would always return something.. here's a good area where you could fail:
if (!cik || !filingsArray)
console.error('PUBLICATION PROBLEM');
If those parameters aren't filled, console.log is probably not the best way to handle it. A better way:
if (!cik || !filingsArray) {
throw "entity-filings: Publication problem.";
return false;
} else {
// .. the rest of your publication
}
This makes sure that the client does not wait unnecessarily long for publications statuses as you have successfully ensured that in any (input) case you returned either false or a Cursor and nothing in between (like surprise undefineds, unfilled Cursors, other garbage data.

How to get the value of an html element using HTML::TreeBuilder

I have a perl array:
Print Dumper(\#jsession);
$VAR1 = [
'<html><body><form name = \'form\' id=\'form\' method = \'POST\' action = \'/Site.jsp\'><input type = hidden name = \'phpSessionID\' value = \'RBOpXs47l6AOw**\'><input type = hidden name = \'LoggedUserName\' value = \'User\'><!--input type = submit name = \'button\' value = \'goAhead\'--></form> <script language = \'JavaScript\'> document.getElementById(\'frmWelcome\').submit();</script></body'</html>
];
I want to get the value of the phpSessionID element into a perl variable.
Here is the HTML::TreeBuilder code that i tried:
$tree=HTML::TreeBuilder->new_from_content(#jsession);
$tree->dump();
It actually prints the HTML part from the array,But how do i use it to get the value of the element that i need?
Here is the code that actually worked for me,in case anyone else where to search for this:
$tree=HTML::TreeBuilder->new_from_content(#jsession);
$first_match = $tree->find_by_attribute('name' => 'phpSessionID');
$first_match->dump();
$value = $first_match->attr('value');
chomp($value);
print "$value";
You use look_down (https://metacpan.org/pod/HTML::Element#look_down) from the root element to describe and find the element you want -
#elements = $h->look_down( ...criteria... );
$first_match = $h->look_down( ...criteria... );
This starts at $h and looks thru its
element descendants (in pre-order), looking for elements matching the
criteria you specify. In list context, returns all elements that match
all the given criteria; in scalar context, returns the first such
element (or undef, if nothing matched).
Then use attr (https://metacpan.org/pod/HTML::Element#attr) on the found element to get the attribute value.
$value = $h->attr('attr');
$old_value = $h->attr('attr', $new_value);
Returns (optionally sets) the value of the given attribute of $h. The
attribute name (but not the value, if provided) is forced to
lowercase. If trying to read the value of an attribute not present for
this element, the return value is undef. If setting a new value, the
old value of that attribute is returned.

How to keep the first parameter value only?

In my Perl Catalyst application, I get the value of a URL parameter like this, typically:
my $val = $c->request->params->{arg} || '';
But the URL could contain multiple arg=$Val. I only want to keep the first value of arg=. I could add this throughout my code:
my $val = $c->request->params->{arg} || '';
$val = $val->[0] if (ref($val) eq 'ARRAY');
That is rather ugly. Is there a way to pick up the first value or a url parameter in a better way?
Does your app actually expect multiple values for parameter arg? If not, all you need is
my $val = $c->request->params->{arg} || '';
Sure, it will be garbage if the user provides you with a garbage url, but there's nothing you can do to prevent the user from giving you garbage.
If it's actually valid to have more than one value for parameter arg, why would you want just the first value? You'd actually want all the values.
sub param_vals {
my ($params, $name) = #_;
return () if !exists($params->{name});
return $params->{$name} if !ref($params->{name});
return #{ $params->{$name} };
}
my #args = param_vals($c->request->{params}, 'arg');
I just read the code to Catalyst::Request but I don't see anything to always pull out a single value. Too bad Cat doesn't use something like Hash::MultiValue!

Perl - Is it good practice to use the empty string as false?

Is it safe/good practice in Perl to use an empty string as false in boolean comparisons?
ex:
my $s = '';
if($s) {
print 'true';
} else {
print 'false';
}
or would the length function be a better way to go:
my $s = '';
if(length($s) > 0) {
print 'true';
} else {
print 'false';
}
When testing for true/false in an expression, you should think carefully about what you actually want to test.
If you have a string and you need to check if it has any value at all, then test for that:
if (defined $string) { ... }
If you are passing back a "boolean" value from a function, or testing the result of some internal operation, then perform a boolean check:
if ($value) { ... }
In Perl, "truth" depends on the manner in which it is evaluated. If you simply say if ($value), then the only string values that evaluate to false are the empty string '', and a literal zero '0'. (Also, any undefined value is false, so if $value has never been assigned, that would be false too.)
There are other values which may evaluate to false in a numerical context, for example 0E0, 0.0000, and the string '0 but true'. So the question "what is truth" really depends on the context, which you the programmer need to be aware of.
Internally, Perl uses '' for false and 1 for truth (for example as the result of any boolean expression such as !$value). A common technique for "canonicalizing" any value into one of these two values is !!$value -- it inverts a value twice, giving you either '' or 1.
A string can have length but still be false -- specifically, the string '0' (details: Perl Truth and Falsehood). At least in the general case, length does not provide a robust test for truth.
my $s = '0';
print "'0' is false.\n" unless $s;
print "But it has length.\n" if length $s;
Typically, you should use the test the characteristic that expresses what you really care about. For example, if you ask a user to enter his favorite age, '0' is a false but valid response: "My first year of life was great, and then everything went to hell."