Cakephp Form Labels Encoding Utf8 - forms

In my php application since the beginning that i set everything with utf8 to avoid future problems. I set my database:
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'root',
'password' => '',
'database' => 'aquitex',
'prefix' => '',
'encoding' => 'utf8',
);
public $test = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'root',
'password' => '',
'database' => 'aquitex',
'prefix' => '',
'encoding' => 'utf8',
);
}
The file core.php:
Configure::write('App.encoding', 'UTF-8');
And the default layout of the views:
<?php echo $this->Html->charset(); ?>
However, i'm still having problems in some elements like labels of forms.
In my index.ctp file, this line:
echo $this->Html->link("Segurança", array('controller' => 'Posts','action'=> 'add'), array( 'class' => 'button'));
works perfectly and there's no problem with the 'ç' character.
But in forms, like this:
echo $this->Form->create('Post');
echo $this->Form->input('Nome Produto');
echo $this->Form->input(utf8_encode("Código Produto"));
echo $this->Form->input("Versão");
echo $this->Form->input('Data');
//echo $this->Form->input('body', array('rows' => '3'));
echo $this->Form->end('Criar Ficha');
there's no way i can get the words on the labels of the form with 'ó" or 'ç' characters showing properly. As you can see i even tried the utf8encode() in one of them.
Any hints? Thank you!

there is no need to use utf8_encode() in your views.
you simply forgot to save the view file properly.
save it as "utf8 without bom" and you will be fine.
files that do not contain any special utf8 char can still stay as ansi (since there is no difference between them then).
but every file that does contain such a character you need to save as utf8 (even controllers and models if you plan on using utf8 characters there for error messages etc).
PS: in general it is wiser to use english and to translate it via PO file into your language.
this way you can leave the files as they are and you are more flexible (you can add new languages on the fly just by creating a new PO file then).
EDIT
After figuring out together that your inputs() use utf8 chars, I will need to update:
It is wise to use "underscore_field_names" for your db fields (and therefore your input fields) - and in English:
echo $this->Form->input("version"));
you can easily translate them via PO file afterwards or specifying the label:
echo $this->Form->input("version", array('label' => 'Versão'));
but the first way is recommended to keep it dry.

App.encoding just tells Cake to send data in UTF8. If you're using MySQL, make sure the database itself is set to utf8_general_ci collation.

Related

Display boolean as radio button in CakePHP form

Does anyone know how to display two radio buttons in a form in CakePHP and have them save to a boolean field in the DB?
I can get my boolean value to display as a checkbox (default behaviour) but I need to display two radio buttons, however when I do this the changes don't get saved to the DB.
I feel like it's something very simple. Here's my code:
<h1>Edit Content</h1>
<?php
$thisVal = $this->data['LessonContent']['is_exercise'] ? "1" : "0";
$options = array(
'0' => 'Learning Material',
'1' => 'Exercise'
);
echo $this->Form->create('LessonContent', array('action'=>'edit'));
echo $this->Form->input('name', array('label' => 'Name'));
echo $this->Form->input('description', array('label' => 'Description'));
echo $this->Form->input('is_exercise', array(
'type' => 'radio',
'class' => 'radio',
'legend' => false,
'name' => 'Type',
'options' => $options,
'value' => $thisVal
));
echo $this->Form->input('id', array('type'=>'hidden'));
echo $this->Form->input('lesson_id', array('type'=>'hidden'));
echo $this->Form->end('Save Content');
echo $this->Html->link('Cancel', array('controller'=>'Lessons', 'action'=>'view', $this->data['Lesson']['id']));
?>
Thanks
You're overriding the name of the input, therefore the value for is_excercise will be sent as Type.
Remove the name option;
echo $this->Form->input('is_exercise', array(
'type' => 'radio',
'class' => 'radio',
'legend' => false,
'options' => $options,
'value' => $thisVal
));
note after making this change, you probably don't even have to manually set the value of the radio-button.
debugging
In situations like this, always check/debug the posted form-data, either via FireBug or by debugging it in CakePHP, by putting this in your controller;
debug($this->request);
Even better, install the CakePHP DebugKit Plugin this plugin shows all the information (request data, queries, session variables etc.) without having to add debug-lines

CakePHP - input select not taking select options from a variable

I am developing an application with CakePHP 2.3.2 and I am having some trouble with an input select on a form. I am creating an array, in my Controller, which contains a list of states. In my View I find that when I use this variable in the 'options' field of the input I do not get any select options. If I do a print_r on the variable, in the view, I see exactly what I think I should be seeing for the 'options' field. I have even tried copying this print_r output and putting it in the 'options' field and then the input select works fine.
Here is what I have
In Controller
$options = 'array(1 => \'NSW\',2 => \'ACT\',3 => \'NT\');
$this->set('all_states, $options);
In View
<?php
$options = $all_states;
echo $this->Form->create('Refine', array('url => '/ServiceDirectoryResults/view/refine'));
echo $this->Form->input('field' ,array(
'type' => 'select',
'label' => false,
'options' => $options
));
echo $this->Form->end('Refine Search');
?>
When I run this I see a select with no select options
If I add print_r($options) after the echo $this->Form->end('Refine Search'); I see
array(1 => 'NSW',2 => 'ACT,3 => 'NT')
Which is what I would expect as it is the content of the $options variable which was the $all_states variable passed from the controller. If I take this output from the print_r and replace the $option with it in the input select the select drop down works fine and I see the three options. For some reason I can't work out the select is working fine if I hard code the select options but it will not work if I pass a variable containing the array to the input select.
I would really appreciate if if someone could give me a clue what I am doing wrong here.
Kind Regards
Richard
you might try it like below:
echo $this->Form->input('field', array('type'=>'select','label' => false,
'options' => $options,'default'=>'2'));
to the following HTML being generated:
<option value="2" selected="selected">ACT</option>
option two is shown instead any other one.
Likely issue:
Arrays should not be made as strings like you have:
$options = 'array(1 => \'NSW\',2 => \'ACT\',3 => \'NT\');
Instead, just make an array:
$options = array(1 => 'NSW', 2 => 'ACT', 3 => 'NT');
Other notes:
Why are you setting $options to $all_states only to set it back?
Missing quotes all over - make sure if you start quotes, that you also end them
not good practice to hard-code your URLs (like in your Form->create)

How to properly use UTF-8-encoded data from Schema inside Catalyst app?

Data defined inside Catalyst app or in templates has correct encoding and is diplayed well, but from database everything non-Latin1 is converted to ?. I suppose problem should be in model class, which is such:
use strict;
use base 'Catalyst::Model::DBIC::Schema';
__PACKAGE__->config(
schema_class => 'vhinnad::Schema::DB',
connect_info => {
dsn => 'dbi:mysql:test',
user => 'user',
password => 'password',
{
AutoCommit => 1,
RaiseError => 1,
mysql_enable_utf8 => 1,
},
'on_connect_do' => [
'SET NAMES utf8',
],
}
);
1;
I see no flaws here, but something must be wrong. I used my schema also with test scripts and data was well encoded and output was correct, but inside Catalyst app i did not get encoding right. Where may be the problem?
EDIT
For future reference i put solution here: i mixed in connect info old and new style.
Old style is like (dsn, username, passw, hashref_options, hashref_other options)
New style is (dsn => dsn, username => username, etc), so right is to use:
connect_info => {
dsn => 'dbi:mysql:test',
user => 'user',
password => 'password',
AutoCommit => 1,
RaiseError => 1,
mysql_enable_utf8 => 1,
on_connect_do => [
'SET NAMES utf8',
],
}
In a typical Catalyst setup with Catalyst::View::TT and Catalyst::Model::DBIC::Schema you'll need several things for UTF-8 to work:
add Catalyst::Plugin::Unicode::Encoding to your Catalyst app
add encoding => 'UTF-8' to your app config
add ENCODING => 'utf-8' to your TT view config
add <meta http-equiv="Content-type" content="text/html; charset=UTF-8"/> to the <head> section of your html to satisfy old IEs which don't care about the Content-Type:text/html; charset=utf-8 http header set by Catalyst::Plugin::Unicode::Encoding
make sure your text editor saves your templates in UTF-8 if they include non ASCII characters
configure your DBIC model according to DBIx::Class::Manual::Cookbook#Using Unicode
if you use Catalyst::Authentication::Store::LDAP configure your LDAP stores to return UTF-8 by adding ldap_server_options => { raw => 'dn' }
According to Catalyst::Model::DBIC::Schema#connect_info:
The old arrayref style with hashrefs for DBI then DBIx::Class options is also supported.
But you are already using the 'new' style so you shouldn't nest the dbi attributes:
connect_info => {
dsn => 'dbi:mysql:test',
user => 'user',
password => 'password',
AutoCommit => 1,
RaiseError => 1,
mysql_enable_utf8 => 1,
on_connect_do => [
'SET NAMES utf8',
],
}
This advice assumes you have fairly up to date versions of DBIC and Catalyst.
This is not necessary: on_connect_do => [ 'SET NAMES utf8' ]
Ensure the table|column charsets are UTF-8 in your DB. You can achieve things that sometimes look right even when parts are broken. The DB must be saving the character data as UTF-8 if you expect the entire chain to work.
Ensure you're using and configuring Catalyst::Plugin::Unicode::Encoding in your Catalyst app. It did have serious-ish bugs in the not too distant past so get the newest.

Cakephp form creation gives me missing database table

According to the manual, I should be able to do this which is to leave Model as null
<?php
echo $this->Form->create(null, array('url' => '/recipes/add'));
// or
echo $this->Form->create(null, array(
'url' => array('controller' => 'recipes', 'action' => 'add')
));
But in reality, I got error saying missing database table? Why?
I have my Model which is not directly mapping to any table. Why can't I leave it as null? Something like this:
<?php echo $this->Form->create(null,array('url' => array('my_account','action' => 'change_avatar'),'type' => 'file'));?>
Try passing false for the model instead of null:
<?php
echo $this->Form->create(false, array('url' => '/recipes/add'));
// or
echo $this->Form->create(false, array(
'url' => array('controller' => 'recipes', 'action' => 'add')
));
From the manual:
You can also pass false for $model. This will place your form data into the array: $this->request->data (instead of in the sub-array: $this->request->data['Model']). This can be handy for short forms that may not represent anything in your database.
make a table with name recipes in your database. The submitted date from the form will be saved at recipes table.

No translation for the language - Works on development server but not in production

While translation works fine on the development server we get the following notice on the production server: No translation for the language 'fr' available.
Here is the translation configuration in the bootstrap (forcing the locale for the test) :
$locale = "fr_CA.utf8";
$translate = new Zend_Translate(
array(
'adapter'=>'gettext',
'content' => APPLICATION_PATH . '/lang',
'locale' => $locale,
'scan' => Zend_Translate::LOCALE_DIRECTORY,
'disableNotices' => false,
'clear' =>true,
'reload'=>true,
)
);
The .mo file is in APPLICATION_PATH/lang/fr_CA.utf8/LC_MESSAGES/messages.mo
There are translated strings in the .mo file and the locale exists on both servers, according to "locale -a".
Any clue as to why such a setup could work on one server and not the other?
EDIT :
I got it to work with the following configuration :
$translate = new Zend_Translate(
array(
'adapter'=>'gettext',
'content' => APPLICATION_PATH.'/lang/'.$locale.'/LC_MESSAGES/messages.mo',
'locale' => $locale,
'disableNotices' => true,
'clear' =>true,
'reload'=>true,
)
);
It seems like the scanning was not working.
I had a similar problem (using the array adapter)
Reason: production site webroot path contains hidden directory /home/.sites/path/to/my/webroot/
// Settings:
$locale = new Zend_Locale('browser');
$language = $locale->getLanguage();
// Solution: added option 'ignore' => '===' to override
// default $_options settings in Zend_Translate_Adapter
$translate = new Zend_Translate(array(
'adapter' => 'array',
'content' => APPLICATION_PATH . '/languages/' . $language,
'scan' => Zend_Translate::LOCALE_DIRECTORY,
'locale' => $locale,
'ignore' => '===', // override default '.'
));
I had a similar problem but using application.ini to configure translation.
These were the Zend_Translate related lines:
resources.translate.adapter = "gettext"
resources.translate.content = APPLICATION_PATH "/languages"
resources.translate.options.scan = 'directory'
This worked fine on our development server but not on our staging server. We had to remove the quotes from the scan option:
resources.translate.options.scan = directory
Without quotes it worked. But I have no idea why this particular config line can't handle quotes on our staging server.