Invalid charset on $_POST - character-encoding

I'm with a problem about the charset of the $_POST. When I submited a form, case the string inserted on the InputText haved a special character or a accent, the value of this input on the $_POST array is corrupted with invalid characters.
Exemple:
I inserted on the input: "pão"
The $_POST show me: Array ( [input] => pão)
I'm using the CodeIgniter Framework with ISO-8859-1 charset. To improve my test, I used a mb_detect_encoding() and this function returned utf-8. :\
Below the code of important parts:
/*
|--------------------------------------------------------------------------
| Default Character Set
|--------------------------------------------------------------------------
|
| This determines which character set is used by default in various methods
| that require a character set to be provided.
|
*/
$config['charset'] = "iso-8859-1";
/*
|--------------------------------------------------------------------------
| Default Language
|--------------------------------------------------------------------------
|
| This determines which set of language files should be used. Make sure
| there is an available translation if you intend to use something other
| than english.
|
*/
$config['language'] = "portugues";
$db['default']['char_set'] = "latin1";
$db['default']['dbcollat'] = "latin1_swedish_ci";
Form that was submited:
<form action="HTTP://localhost/portalsibe/index.php/grupos/cadastro" id="form" accept-charset="utf8" method="POST" name="frmPadrao" target="" enctype="multipart/form-data">

Try this solution, insert this jquery function in your script:
Font
Credits:
Javier Poo, WeLinux S.A.
Oficina: 02-372.97.70, Celular:84039925
Bombero Ossa # 1010, Santiago
www.welinux.cl
jQuery.fn.extend({
param: function( a ) {
var s = [];
// If an array was passed in, assume that it is an array
// of form elements
if ( a.constructor == Array || a.jquery ){
// Serialize the form elements
jQuery.each( a, function(){
s.push(unescape(encodeURIComponent(escape(this.name))) + "=" + unescape(encodeURIComponent(escape(this.value))));
});
}
// Otherwise, assume that it's an object of key/value pairs
else{
// Serialize the key/values
for ( var j in a )
// If the value is an array then the key names need to be repeated
if ( a[j] && a[j].constructor == Array )
jQuery.each( a[j], function(){
s.push(unescape(encodeURIComponent(escape(j)) + "=" + encodeURIComponent(escape(this))));
});
else
s.push(unescape(encodeURIComponent(escape(j)) + "=" + encodeURIComponent(escape(a[j]))));
}
// Return the resulting serialization
return s.join("&").replace(/ /g, "+");
},
serialize: function() {
return this.param(this.serializeArray());
}
});

Can you change everything to utf8? Including database?
If yes, change all files, and set MySQL database (and tables) to utf8_general_ci. If you are using notepad++ to develop, go to Encoding > Encode in UTF-8 (em português Formatar > Codificação em UTF-8).
Try not to use ISO-8859-1 as character encoding.

Then you need to "transform" all your files and database do ISO-8859-1. Don't forget to add in your PHP/HTML files, the encoding.
For example, in HTML4: <meta http-equiv="Content-type" content="text/html;charset=ISO-8859-1"> and HTML5: <meta charset="ISO-8859-1">
Also, try to change teh enctype in your <form> tag to application/x-www-form-urlencoded and see if it works.

Related

Svelte: How to bind a formatted input field to a property

First of all: Svelte is still new to me. I hope the question is not too trivial.
Within a simple component I want to use the content of a formatted input field for a calculation.
For example:
In the input field a Euro amount should be displayed formatted (1.000).
Next to it a text with the amount plus VAT should be displayed (1.190).
How I do this without formatting is clear to me. The example looks like this:
export let net;
export let vat;
$: gross = net + (net * vat / 100);
$: grossPretty = gross.toLocaleString('de-DE',{ minimumFractionDigits: 0, maximumFractionDigits: 0 });
with a simple markup like this:
<form>
<label>Net amount</label>
<input type="text" step="any" bind:value={net} placeholder="Net amount">
</form>
<div>
Gros = {grossPretty} €
</div>
In vue i used a computed property. Its getter delivers the formatted string and its setter takes the formatted string and saves the raw value.
(In data() I define net, in the computed properties i define netInput. The input field uses netInput as v-model).
It looks like this:
netInput: {
get(){
return this.net.toLocaleString('de-DE',{ minimumFractionDigits: 0, maximumFractionDigits: 0 });
},
set(s){
s = s.replace(/[\D\s._-]+/g, "");
this.net = Number(s);
}
}
How can I handle it in svelte?
You can do something somewhat similar, you create another computed variable that stores the deformatted string from the input field and is used in the calculation instead of the direct input
export let net;
export let vat;
$: net_plain = Number(net.replace(/[\D\s._-]+/g, ""));
$: gross = net_plain + (net_plain * vat / 100);
$: grossPretty = gross.toLocaleString('de-DE',{ minimumFractionDigits: 0, maximumFractionDigits: 0 });
But maybe find a better name for the variable :)
Thanks to Stephane Vanraes I found a solution.
It has not the charm of the vue approach but it's ok. First I inserted 'net_plain'. To have the input field formatted during input, I added an event listener for the keyup event.
<input type="text" step="any" bind:value={net} on:keyup={handleKeyUp} placeholder="Net amount">
The event is handled from the function handleKeyUp as follows:
function handleKeyUp(event){
if ( window.getSelection().toString() !== '' ) {
return;
}
// ignore arrow keys
let arrows = [38,40,37,39];
if ( arrows.includes( event.keyCode)) {
return;
}
let input = event.target.value.replace(/[\D\s._-]+/g, "");
input = input ? parseInt( input, 10 ) : 0;
event.target.value = ( input === 0 ) ? "" : input.toLocaleString( "de-DE" );
}
BUT: If anyone has a solution using getter and setter I would appreciate the anwer!

Weird antlr grammar rule

I have found an old file that define antlr grammar rules like that:
rule_name[ ParamType *param ] > [ReturnType *retval]:
<<
$retval = NULL;
OtherType1 *new_var1 = NULL;
OtherType2 *new_var2 = NULL;
>>
subrule1[ param ] > [ $retval ]
| subrule2 > [new_var2]
<<
if( new_var2 == SOMETHING ){
$retval = something_related_to_new_var2;
}
else{
$retval = new_var2;
}
>>
{
somethingelse > [new_var_1]
<<
/* Do something with new_var_1 */
$retval = new_var_1;
>>
}
;
I'm not an Antlr expert and It's the first time that i see this kind of semantic for a rule definition.
Does anybody know where I can find documentation/informations about this?
Even a keyword for a google search is welcome.
Edit:
It should be ANTLR Version 1.33MR33.
Ok, I found! Here is the guide:
http://www.antlr2.org/book/pcctsbk.pdf
I quote the interesting part of the pdf that answer to my question.
1) Page 47:
poly > [float r]
: <<float f;>>
term>[$r] ( "\+" term>[f] <<$r += f;>> )*
;
Rule poly is defined to have a return value called $r via the "> [float r]" notation; this is similar to the output redirection character of UNIX shells. Setting the value of $r sets the return value of poly. he first action after the ":" is an init-action (because it is the first action of a rule or subrule). The init-action defines a local variable called f that will be used in the (...)* loop to hold the return value of the term.
2) Page 85:
A rule looks like:
rule : alternative1
| alternative2
...
| alternativen
;
where each alternative production is composed of a list of elements that can be references to rules, references to tokens, actions, predicates, and subrules. Argument and return value definitions looks like the following where there are n arguments and m return values:
rule[arg1,...,argn] > [retval1,...,retvalm] : ... ;
The syntax for using a rule mirrors its definition:
a : ... rule[arg1,...,argn] > [v1,...,vm] ...
;
Here, the various vi receive the return values from the rule rule, each vi must be an l-value.
3) Page 87:
Actions are of the form <<...>> and contain user-supplied C or C++ code that must be executed during the parse.

TableSorter : csv export and accented characters

With TableSorter, when I export my table in a CSV file, the accented characters doesn't appear correctly.
How to solve that ?
In version 2.16.4, the output_encoding option was added to the output widget.
The demo now has a select dropdown in which you can choose "utf8 BOM" required to make the csv file work properly in Excel.
You can set this option to include a BOM by default as follows:
output_encoding : 'data:text/csv;charset=utf8,%EF%BB%BF'
With version 2.30.6, the solution proposed above didn't work for me.
I read an article saying the unicode character \uFEFF should be specified at the beginning of the CSV data.
So, my code below insert this character only once and I reset the boolean immediately to do it only once.
Dont pay attention about scroller_* widget options if you don't use the widget 'scroller' (same for 'columnSelector' and 'filter' widgets).
Here to show UTF8 data in Excel, use the callback function output_formatContent and see my code below.
var insertBOM = true;
var $tablesorterScroll = $(".tablesorter-scroll");
$tablesorterScroll.tablesorter({
sortInitialOrder: 'desc',
widthFixed : false,
showProcessing: true,
widgets: ['filter', 'columnSelector', 'scroller', 'output'],
widgetOptions: {
// Set the max-height property of the table for the scroller widget.
scroller_height : 412, // sized with table CompanyBoard statistics (fits like that without scrollbar and finishes at the end of the row)
// Delay in milliseconds before the filter widget starts searching; This option prevents searching for
// every character while typing and should make searching large tables faster.
filter_searchDelay : 200,
// target the column selector markup
columnSelector_container : $('#columnSelector'),
// column status, true = display, false = hide
// disable = do not display on list
columnSelector_columns : {
//0: 'disable' /* set to disabled; not allowed to unselect it */
},
// remember selected columns (requires $.tablesorter.storage)
columnSelector_saveColumns: true,
// container layout
columnSelector_layout : '<label><input type="checkbox">{name}</label>',
// data attribute containing column name to use in the selector container
columnSelector_name : 'data-selector-name',
/* Responsive Media Query settings */
// enable/disable mediaquery breakpoints
columnSelector_mediaquery: false,
// toggle checkbox name
columnSelector_mediaqueryName: 'Auto: ',
// breakpoints checkbox initial setting
columnSelector_mediaqueryState: false,
// hide columnSelector false columns while in auto mode
columnSelector_mediaqueryHidden: false,
// set the maximum and/or minimum number of visible columns; use null to disable
columnSelector_maxVisible: null,
columnSelector_minVisible: null,
// responsive table hides columns with priority 1-6 at these breakpoints
// see http://view.jquerymobile.com/1.3.2/dist/demos/widgets/table-column-toggle/#Applyingapresetbreakpoint
// *** set to false to disable ***
columnSelector_breakpoints : [ '20em', '30em', '40em', '50em', '60em', '70em' ],
// data attribute containing column priority
// duplicates how jQuery mobile uses priorities:
// http://view.jquerymobile.com/1.3.2/dist/demos/widgets/table-column-toggle/
columnSelector_priority : 'data-priority',
// class name added to checked checkboxes - this fixes an issue with Chrome not updating FontAwesome
// applied icons; use this class name (input.checked) instead of input:checked
columnSelector_cssChecked : 'checked',
output_saveFileName : 'TableExport.csv',
output_separator: ';', // Excel recognize it and shows data in separated column without doing "Text to columns" Excel option.
output_replaceQuote: '\'',
output_delivery: 'd', // (p)opup, (d)ownload
output_saveRows: 'v', // (a)ll, (v)isible, (f)iltered, jQuery filter selector (string only) or filter function
output_encoding: "data:text/csv;charset=utf-8",
output_formatContent: function (config, widgetOptions, data) {
// data.isHeader (boolean) = true if processing a header cell
// data.$cell = jQuery object of the cell currently being processed
// data.content = processed cell content
// (spaces trimmed, quotes added/replaced, etc)
// **********
// use data.$cell.html() to get the original cell content
var BOM = "";
// Add BOM at file starting
if (insertBOM) {
BOM = "\uFEFF"; // set Excel enconding UTF-8
insertBOM = false;
}
return BOM + data.content.replace(/&/g, '&'); // data.content is HTML text converted so '&' has been converted to & which is the HTML reprensetation of the '&' character. Convert it back to show '&' in the CSV.
}
}
});
EDIT (15.10.2020)
My initial solution proposed above doesn't work when output_headerRows: true AND if the first header row has a rowspan. A colspan is ok.
To handle that situation, I found a way :
Before: The BOM was inserted by the function output_formatContentwhich is raised row after row (and a condition to apply the BOM only once)
Now: Use the output_callback function that is raised only once at the end of the data processed, so can insert the BOM.
IMPORTANT: You need tablesorter v2.25.1+ to be able to return data instead of true as before.
output_callback : function(config, data, url) {
BOM = "\uFEFF"; // The BOM character to force Excel opens CSV as UTF-8
return BOM + data;
}

Using money-rails with AngularJS

I'm converting some forms within my Rails 3.2 app to use AngularJS so that I can do live calculations and such. In my rails app I use money-rails to handle the currency. This treats all currency fields as integers made of of cents.
This becomes a problem when I send all the information through JSON over to my AngularJS template. Now my form is all in cents when I want them in dollars and cents.
I've put the conversion in my AngularJS controller so when I get the data from the server I convert it from cents to dollars & cents and vice vesa just before updating. Here is the code:
# Edit Investor
window.InvestorEditCtrl = ($scope, $routeParams, $location, Investor, Common) ->
console.log 'InvestorEditCtrl'
# Setup variable for common services(factory)
$scope.common = Common
$scope.master = {} # Initialise our main object hash
investor_id = $routeParams.investor_id # Get the ID of the investor we are editing from the URL
# Get the investor information & assign it to the scope master object
console.log 'Get JSON'
$scope.investor = new Investor.show({investor_id: investor_id}, (resource) ->
# copy the response from server response (JSON format) to the scopes master
$scope.master = angular.copy(resource)
# Convert price_cents to dollars
$scope.investor.price_cents /= 100
)
# Update the investor passing the JSON back to the server.
$scope.update = (investor) ->
# Convert price_cents to cents
investor.price_cents *= 100
$scope.master = angular.copy(investor)
investor.$update({investor_id: investor_id}, (t) ->
$location.path('/investors/' + t.id)
)
Is there a better way to do this?
You could write either a filter or a directive that converts it to the form you want in your HTML. The filter would look something like this:
app.filter('centsToDollars', function() {
return function(input) {
var out = input / 100;
return out;
}
});
Then, in your html, wherever you want the cents displayed dollars and cents, call it like this:
<p>{{investor.price_cents | centsToDollars}}</p>
The filter would only impact the display of the data and wouldn't modify the underlying data from being cents.
If you needed to modify the display of an input field, the better route would probably be a directive. You could do something like what's referenced here
app.directive('myCentsToDollars', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elem, attrs, ngModel) {
var toDollars = function(text) {
var text = (text || "0");
return (parseFloat(text) / 100);
}
var toCents = function(text) {
var text = (text || "0");
return (parseFloat(text) * 100);
}
ngModel.$parsers.push(toDollars);
ngModel.$formatters.push(toCents);
}
}
});
Then, in your html, do:
<input type="text" my-cents-to-dollars ng-model="investor.price_cents" />

Open Source Projects for i18n à la Facebook

Facebook has this unique and clever approach to localization of their site: translators (in their case users that help to translate the site voluntarily) can simply click on the not-yet-translated strings – which are marked with a green bottom border – in their natural context on the site. See http://www.facebook.com/translations/.
Now, if you ever had to deal with the translation of a website, you'll be well aware of how odd and funny some of these translations can be when using tools like poedit where the translator isn't fully aware of the spot the translated string will lated appear in on the website.
Example: Please translate "Home". In German, for instance, the start page of a website would be "Home" while the house you live in is "Heim". Now, you as the translator basically have to guess which context this term is likely to appear in on the website and translate accordingly. Chances are, you're new website on home furniture now translates as "Home-Einrichtung" which sounds ridiculous to any German.
So, my question boils down to:
Do you know any open source PHP projects that work on something like this? I'm basically looking for a framework that allows you to put your internationalized website in "translation mode" and make strings clickable and translatable e.g. through a Javascript modal.
I'm not so much looking for a full-fledged and ready-made solution, but would love to know about similar projects that I can contribute code to.
Thanks in advance!
If you want to roll your own with jquery & jquery browserLanguage, this might get you going.
Tag all translatable text's contain elements with class="i18n", and include jquery, jquery browserLanguage, and your i18n script.
1. the internationalization javascript
— this needs to accept translations via ajax from your server, like:
var i18n = {};
i18n.bank = new Array();
i18n.t = function ( text, tl=$.browserLanguage ) {
var r = false;
$.ajax({
url: "/i18n_t.php?type=request&from="+ escape(text) +"&tl="+ tl,
success: function(){ i18n.bank[text] = this; r = true; }
});
return r;
};
2. php i18n translation service
— now we need to serve up translations, and accept them
the database will look like a bunch of tables, one for each language.
// SCHEMA for each language:
CREATE TABLE `en`
(
`id` INT PRIMARY KEY AUTO INCREMENT NOT NULL,
`from` VARCHAR(500) NOT NULL,
`to` VARCHAR(500) NOT NULL
)
the php will need some connection and db manipulation.. for now this may do:
//Connect to the database
$connection = mysql_connect('host (usually localhost)', 'mysql_username' , 'mysql_password');
$selection = mysql_select_db('mysql_database', $connection);
function table_exists($tablename, $database = false) {
if(!$database) {
$res = mysql_query("SELECT DATABASE()");
$database = mysql_result($res, 0);
}
$res = mysql_query("SELECT COUNT(*) AS count FROM information_schema.tables WHERE table_schema = '$database' AND table_name = '$tablename'
");
return mysql_result($res, 0) == 1;
}
the code is simply:
<?php
// .. database stuff from above goes here ..
$type=$_GET["type"];
$from=$_GET["from"];
$to=$_GET["to"];
$tl=$_GET["tl"];
if (! table_exists($tl)) {
...
}
if ($type == "request") { // might want to set $tl="en" when ! table_exists($tl)
$find = mysql_query("SELECT to FROM `'$tl'` WHERE from='$from'");
$row = mysql_fetch_array($find);
echo $row['to'];
} elsif ($type == "suggest") {
$find = mysql_query("SELECT COUNT(*) AS count FROM `'$tl'` WHERE from='$from'");
if ( !(mysql_result($res, 0)) == 0 ) {
$ins = mysql_query("INSERT INTO `'$tl'` (from, to) VALUES ('$from','$to')");
}
}
?>
3. page translation mechanics
— finally we can tie them together in your webpages with some further jquery:
i18n.suggest = function (from) { // post user translation to our php
$.ajax({
url: "/i18n_t.php?type=suggest&from='+from+'&to="+ escape( $('#i18n_s').contents() ) +"&tl="+ $.browserLanguage,
success: function(){ $('#i18n_t_div').html('<em>Thanks!</em>').delay(334).fadeOut().remove(); }
});
};
$(document).ready(function() {
i18n.t("submit");
i18n.t("Thanks!");
$('.i18n').click( function(event) { //add an onClick event for all i18n spans
$('#i18n_t_div').remove;
$(this).parent().append(
'<div id="i18n_t_div"><form class="i18n_t_form">
<input type="text" id="i18n_s" name="suggestion" value="+$(this).contents()+" />
<input type="button" value="'+ i18n.bank[ "submit" ] +'" onclick="i18n.suggest( '+$(this).contents()+' )" />
</form></div>'
);
}).each(function(){
var c = $(this).contents(); //now load initial translations for browser language for all the internationalized content on the page
if ( i18n.t(c) ){
$(this).html(i18n.bank[c]);
}
});
});
Mind you I don't have a server to test this on... and I don't actually code php. :D It will take some debugging but the scaffolding should be correct.

Resources