radig / locale

CakePHP Plugin to work with localized data
www.radig.com.br
MIT License
15 stars 6 forks source link

Falha apenas na primeira execução #2

Closed PabloGarciaComBR closed 10 years ago

PabloGarciaComBR commented 10 years ago

Na primeira execução, o retorno da função Locale->date e Locale->datetime falham. Com o debug configurado para '2', as seguintes mensagens são exibidas:

Me parece ser um problema parecido com o que ocorre em distribuições derivadas do debian. Só que neste caso, ele falha na primeira execução ou quando há um tempo sem executar esta função. Atualizando a página ou voltando a ela rapidamente, os datas são convertidas corretamente. Estou testando em uma maquina com Win7 Pro x64, WampServer 2.4 (Apache 2.4.4, PHP 5.4.16 e MySQL 5.6.12) e CakePHP 2.4.3. Também testei a mesma aplicação no CENTOS 5.10 x86_64 e em uma outra maquina com Win7 Pro x64 só que com Apache, PHP e MySQL configurados "na mão".

Estou a disposição para colaborar com a resolução do problema.

CauanCabral commented 10 years ago

@PabloGarciaComBR , você está usando algum tipo de opcache? Como APC ou Zend_OpCache?

PabloGarciaComBR commented 10 years ago

Não configurei nada. Apenas as opções default do CakePHP 2.4. Segundo a documentação, a partir do 2.3 ele tenta usar o APC, caso esteja disponível. No meu bootstrap.php achei a seguinte entrada:

// Setup a 'default' cache configuration for use in the application.
Cache::config('default', array('engine' => 'File'));

O que indica que o cache está ativo. No core.php há as seguintes linhas de configuração:

/**
 * Configure the cache handlers that CakePHP will use for internal
 * metadata like class maps, and model schema.
 *
 * By default File is used, but for improved performance you should use APC.
 *
 * Note: 'default' and other application caches should be configured in app/Config/bootstrap.php.
 *       Please check the comments in bootstrap.php for more info on the cache engines available
 *       and their settings.
 */
$engine = 'File';

// In development mode, caches should expire quickly.
$duration = '+999 days';
if (Configure::read('debug') > 0) {
    $duration = '+10 seconds';
}

// Prefix each application on the same server with a different string, to avoid Memcache and APC conflicts.
$prefix = 'siscorretora_';

/**
 * Configure the cache used for general framework caching. Path information,
 * object listings, and translation cache files are stored with this configuration.
 */
Cache::config('_cake_core_', array(
    'engine' => $engine,
    'prefix' => $prefix . 'cake_core_',
    'path' => CACHE . 'persistent' . DS,
    'serialize' => ($engine === 'File'),
    'duration' => $duration
));

/**
 * Configure the cache for model and datasource caches. This cache configuration
 * is used to store schema descriptions, and table listings in connections.
 */
Cache::config('_cake_model_', array(
    'engine' => $engine,
    'prefix' => $prefix . 'cake_model_',
    'path' => CACHE . 'models' . DS,
    'serialize' => ($engine === 'File'),
    'duration' => $duration
));

Todas as outras linhas estão comentadas. Caso seja necessário o acesso a qualquer outra informação, estou ao seu dispor. Obrigado.

varantes-cit commented 10 years ago

Estou há um tempo com o mesmo problema, porém o erro que recebo é outro.

Fatal error: Uncaught exception 'LocaleException' with message 'Localização '' não possuí formatação definida. Tente adicionar o formato antes de usa-lo.' in app\plugins\locale\libs\localize.php on line 63

LocaleException: Localização '' não possuí formatação definida. Tente adicionar o formato antes de usa-lo. in app\plugins\locale\libs\localize.php on line 63

Só acontece no primeiro carregamento da página. Quando recarrego, ele some. Utilizando Win7 + WAMPP + PHP 5.3.13 + APACHE 2.2.22

CauanCabral commented 10 years ago

Ontem tirei o dia pra tentar resolver problemas no plugin. Vocês definiram o "setlocale(LC, ...)" como explica no README?

Corrigi dois casos de testes que variam de acordo com o banco de dados usado (MySQL ou Postgresql), e agora todos passam. Rodei localmente numa máquina OpenSUSE + Apache + PHP 5.5, via console na mesma máquina (retira o Apache da equação). Repeti o teste em uma VM do Vagrant com Ubuntu Server. Os testes ainda não passam no Travis-ci, não consigo descobrir o motivo, mas ao menos agora são dois problemas apenas.

PabloGarciaComBR commented 10 years ago

@CauanCabral o setlocale está definido sim. Vou baixar os arquivos atualizados e testar assim que tiver um tempo aqui. Daí te dou um feedback. Obrigado.

CauanCabral commented 10 years ago

Obrigado @PabloGarciaComBR, fico no aguardo.

estevesklein commented 10 years ago

Estava com o mesmo problema. Resolvido com a atualização. Obrigado!

estevesklein commented 10 years ago

Olá Cauan, O problema persistiu quando resetei o server. Fiz alguns testes e resolvi o problema da seguinte forma: No Bootstrap setlocale(LC_ALL, 'pt_BR.utf-8', 'pt_BR', 'pt-br', 'portuguese'); Abs

PabloGarciaComBR commented 10 years ago

@CauanCabral Realmente, com a sua atualização o plugin ficou muito mais estável. Porém ainda persistia um problema na primeira execução depois de reiniciar o servidor. Testei a alteração proposta pelo @estevesklein - adicionar o quinto parâmetro "portuguese" - e realmente funcionou. Agora está tudo perfeito :)

CauanCabral commented 10 years ago

Obrigado @estevesklein e @PabloGarciaComBR , vou incluir essa observação no Readme.

Abraços.

r0drigocarvalho commented 10 years ago

Fala pessoal, fiz as alterações:

boostrap.php - setlocale(LC_ALL, 'pt_BR.utf-8', 'pt_BR', 'pt-br', 'portuguese');

atualizei o plugin baixando o master

mas mesmo assim estou tendo problema com $this->Locale->currency($valor); ele não formata o valor, alguem esta tendo este problema?

CauanCabral commented 10 years ago

Olá @r0drigocarvalho , peço que abra uma issue nova porque seu problema parece ser diferente do desta thread.

Não esqueça de informar qual o valor da váriavel $valor e seu ambiente (qual SO e versão do PHP pelo menos). Abraço.

thiagojeffery commented 9 years ago

Olá, fiz o que aconselharam. boostrap.php - setlocale(LC_ALL, 'pt_BR.utf-8', 'pt_BR', 'pt-br', 'portuguese'); porém continuo com o mesmo problema. estou usando cakephp 2.5.5 no xampp com win7 64. Sempre na primeira execução aparece o erro: Undefined index: [ROOT\plugins\Locale\Lib\Localize.php, line 41] Undefined index: [ROOT\plugins\Locale\Lib\Localize.php, line 91] algumas vezes ele passa a funcionar depois que fico danto refresh direto na página com F5 função usada $this->Locale->date() Existe algo que eu possa fazer pra resolver? abraço

CauanCabral commented 9 years ago

Olá Thiago, qual a versão do seu PHP?

Qual a saída do PHP para a chamada:

var_dump(setlocale(LC_ALL, 'pt_BR.utf-8', 'pt_BR', 'pt-br', 'portuguese'));

Fiz uma busca aqui sobre setlocale no Windows, e parece haver um problema com UTF8 (que não deveria influenciar nisso... mas nunca se sabe): http://stackoverflow.com/questions/10995953/php-setlocale-in-windows-7

Talvez utilizar também 'Portuguese_Brazil.1252', como é indicado na página do Moodle, seja uma boa.

manfe commented 9 years ago

Fala @CauanCabral estou tendo o mesmo problema e executando esse vardump o retorno é esse: string(5) "pt-br"

Porém nessa questão que tu mencionou eles falam que trabalhando com UTF-8 no windows acaba dando algum problema no setar o locale. Uma forma de resolver foi fazer com que a opção 'portuguese' fosse encontrada antes da 'pt-br' assim o Windows consegue se achar e não dar o erro, ou seja, é necessário que o comando fique assim:

setlocale(LC_ALL, 'pt_BR.utf-8', 'pt_BR', 'portuguese', 'pt-br');

Executando o comando: var_dump(setlocale(LC_ALL, 'pt_BR.utf-8', 'pt_BR', 'portuguese', 'pt-br')); O retorno é: string(22) "Portuguese_Brazil.1252"

Ou seja, através do "portuguese" ele pega o "Portuguese_Brazil.1252"

Vale ressaltar que ainda não fiz os testes no servidor linux, no qual ficará em produção.

CauanCabral commented 9 years ago

Opa @manfe , acho que não seria complicado tratar diferente a ordem dos elementos no Linux e Windows, algo como:

$os = strtolower(php_uname('s'));
// Unix/Linux
if (strpos($os, 'windows') === false) {
    setlocale(LC_ALL, 'pt_BR.utf-8', 'pt_BR', 'pt-br', 'portuguese');
// Windows
} else {
    setlocale(LC_ALL, 'pt_BR.utf-8', 'pt_BR', 'portuguese', 'pt-br');
}

Pode testar se funciona bem dessa forma? Se puder fazer um PR para vermos se os testes não quebram com a alteração também ajudaria bastante.

Muito obrigado pelas informações.

thiagojeffery commented 9 years ago

Olá Cauan! Desculpe a demora em responder, ia responder, mas tava ocupado na hora e esqueci, muito trabalho, e estava fazendo outro projeto. A saída que me pediu é: string(5) "pt-br" Acredito que resolvi usando somente isso: setlocale(LC_ALL, 'pt_BR', 'portuguese'); Ao invés do sugerido.

viniciusbig commented 9 years ago

Pode não ser uma issue relacionada, mas como os sintomas são parecidos, vou deixar meu comentário:

Usando o setlocale que vem no plugin setlocale(LC_ALL, 'pt_BR.utf-8', 'pt_BR', 'pt-br', 'pt_BR.iso-8859-1', 'portuguese');

encontro o erro de: Notice (8): Undefined index: [APP\Plugin\Locale\Lib\Unlocalize.php, line 41]

Quando tento adicionar um novo registro. Note que o erro é no "Unlocalize".

@CauanCabral , aplicando o IF que você sugeriu no locale/bootstrap.php e funcionou. Mas, nesse cenário, somente os campos de data do meu registro foram convertidas (de DD/MM/YYY para YYY-MM-DD)

para os campos float os valores não foram convertidos de 123,45 para 123.45.

A saída pro meu vardump (com o IF que vc mandou) fica 'Portuguese_Brazil.1252'

Outra informação que pode ser relevante é que a variável $currentFormat = localeconv(); do arquivo Unlocalize.php (134) tem o seguinte conteúdo:

array( 'decimal_point' => '.', 'thousands_sep' => '', 'int_curr_symbol' => '', 'currency_symbol' => '', 'mon_decimal_point' => '', 'mon_thousands_sep' => '', 'positive_sign' => '', 'negative_sign' => '', 'int_frac_digits' => (int) 127, 'frac_digits' => (int) 127, 'p_cs_precedes' => (int) 127, 'p_sep_by_space' => (int) 127, 'n_cs_precedes' => (int) 127, 'n_sep_by_space' => (int) 127, 'p_sign_posn' => (int) 127, 'n_sign_posn' => (int) 127, 'grouping' => array(), 'mon_grouping' => array() )

Esse 'decimal_point' => '.' não deveria ser uma vírgula? Esse trecho deveria procurar a vírgula e trocar por um ponto mas, ao invés disso, procura por um ponto (que não existe) e não faz mais nada. Assim, o valor 123,45 passa sem alteração.

Para contextualizar, estou usando Cake 2.5.5, Windows 7, WAMP (PHP 5.5.12, Apache 2.4.9)

Você sabe o que pode ser?

viniciusbig commented 9 years ago

Só para deixar registrado, encontrei alguma resposta para o problema.

Este é um bug aberto no php [1] e não se sabe ao certo a razão. O bug está marcado como won't-fix. O bug faz com que o localeconv() tenha valores errados mesmo com a configuração correta de setLocale. Aparantemente é um problema do Windows 7.

[1] [https://bugs.php.net/bug.php?id=65230]

CauanCabral commented 9 years ago

Interessante @viniciusbig , acho que o ideal então seria mudar o plugin para utilizar a extensão intl, assim como fizeram no CakePHP 3.0

Será que compensa fazer essa alteração?

Ando com o tempo bem curto, e essa issue não me afeta diretamente porque não trabalho com Windows, mas entendo a necessidade de vários em relação a isso.

viniciusbig commented 9 years ago

@CauanCabral Acho que seria interessante alterar sim, principalmente pra depois se criar uma versão Cake 3.0 deste plugin (Ou o Cake 3.0 já faz o trabalho que este plugin faz? Ainda não mexi completamente no Cake 3.0).

Meu ambiente de desenvolvimento é windows, mas meu ambiente de produção é linux. Engraçado que esse erro não acontece em todas as versões do Windows 7. A mesma instalação em máquinas diferentes, com o mesmo servidor e versão de PHP, ora funciona, ora não funciona. Então sou impactado um pouco pelo problema.

Ainda não conheço o funcionamento da extensão intl, mas vou dar uma olhada nela!

CauanCabral commented 9 years ago

@viniciusbig Então, no CakePHP 3.0 não vejo necessidade de ter o Locale (escrevi a respeito um tempo atrás http://cauancabral.net/2015/02/15/cakephp-3-0-o-fim-do-locale/ )

No máximo, o plugin poderia automatizar essas configurações que comento no post, de resto o próprio ORM/I18n já resolvem.