Menubar

martes, 29 de agosto de 2017

Corrección para la función "Como leer un archivo PO desde PHP para traducir nuestra web"

Por J. Manuel Mar H. Editar
Compartir en Facebook
Compartir en Twitter
Compartir en MeWe
Enviar a Reddit
Guardar en Internet archive
Guardar en  archive.today
Enviar por email
Parche  Concluyo esta sección de acceder a datos o hacer uso de otras funciones de Wordpress, pero usando PHP, esperando les halla sido de utilidad. También quiero agradecer a Javier Gutierrez Chamorro (Guti) por estar siempre al pendiente de lo que publico en este blog y hacerme observaciones, muchísimas gracias, si es para mejorar adelante, son bienvenidas las sugerencias. Pues bien, en esta última entrega de Wordpress voy a hacer una corrección a la función para leer un archivo PO desde php que se publicó algunas semanas atrás basada en las observaciones recibidas por Guti.


  En el formato original esta función abre un archivo PO, lo lee línea por línea hasta que encuentra la llave a buscar, si la encuentra devuelve su valor, sinó habrá que esperar hasta que termine de leer todo el archivo y se retornará un valor vacío. Esto funciona sin problemas, el único detalle es ¿que pasa si varias veces se tiene que llamar esa función en el mismo archivo PHP?, pues que todas las veces que se requiera tendrá que abrir y cerrar el archivo, y buscar una y otra vez, lo cual es un procedimiento lento y además existe el riesgo de colapsar al servidor.

Publicidad


  La corrección sugerida es vaciar el contenido de ese archivo a memoria, y luego ya buscar ahí lo que necesitemos, si tenemos la necesidad de buscar varias llaves traducidas, no habrá necesidad de abrir y cerrar el archivo una y otra vez, solo una; ahora solo hay que buscar en memoria las llaves traducidas.

Este es el nuevo código:

<?php

$translatedarray = array();

//thanks to http://www.desarrolloweb.com/articulos/893.php
//thanks to Javier Gutierrez Chamorro (Guti) http://www.javiergutierrezchamorro.com/
function getTranslatedStringFromPOFile($pofile, $msgid)
{

  global $translatedarray;
       
  if(trim($pofile) == "")
    return $msgid; 
  else
  {
     
     if(!file_exists(trim($pofile)))
     return $msgid;
     else
   {
  
     if(trim($msgid) == "")
           return "";
         else
       {
      
         if(empty($translatedarray) == false)
           return gettranslatedstring(trim($msgid));
         else
         {
      
                 $line = "";
                 $fp = fopen(trim($pofile), "r");
        
                 while(!feof($fp))
                 {
                
                     $line = trim(fgets($fp, 1024));
                    
                     if(trim($line) != "")
                     {
                    
                       if(startWith(strtolower(trim($line)), "msgid", false) == true)
                         {
                        
                           $start = strpos(strtolower($line), "msgid");
                           $msgidvalue = substr($line, $start, strlen($line));
                           $start = strpos(strtolower($msgidvalue), " ");
                           $msgidvalue = substr($msgidvalue, $start + 1, strlen($line));
                     
                           if(startWith(strtolower(trim($msgidvalue)), chr(34), false) == true)
                             $msgkeyname = substr($msgidvalue, 1, strlen($msgidvalue) - 1);
                     
                           if(endWith(strtolower(trim($msgkeyname)), chr(34), false) == true)
                             $msgkeyname = substr($msgkeyname, 0, strlen($msgkeyname) - 1);
                     
                           $line = trim(fgets($fp, 1024));
                          
                            if(trim($line) != "")
                            {
                           
                              $start = strpos(strtolower($line), "msgstr");
                                 $msgstrvalue = substr($line, $start, strlen($line));
                                 $start = strpos(strtolower($msgstrvalue), " ");
                                 $msgstrvalue = substr($msgstrvalue, $start + 1, strlen($line));
                            
                                 if(startWith(strtolower(trim($msgstrvalue)), chr(34), false) == true)
                                   $msgstrvalue = substr($msgstrvalue, 1, strlen($msgstrvalue) - 1);
                              
                                 if(endWith(strtolower(trim($msgstrvalue)), chr(34), false) == true)
                                   $msgstrvalue = substr($msgstrvalue, 0, strlen($msgstrvalue) - 1);
                                 
                              array_push($translatedarray, array("ID" => trim($msgkeyname), "VALUE" => $msgstrvalue));
       
                           }
   
                         }

                     }
                       
                 }
               
                 fclose($fp);
                 return getTranslatedString(trim($msgid));
                 
             }

         }
       
      }
   
    }       
           
}

//thanks to http://www.anerbarrena.com/php-foreach-4298/
function getTranslatedString($msgid)
{

  global $translatedarray;
 
  $GLOBALS["msgid"] = trim($msgid);
  $filterarray = array_filter($translatedarray, "getrst");
 
  foreach($filterarray as $key=>$value)
    $thearray = $value;

  if(empty($thearray) == true)
    return "";
  else
    return $thearray["VALUE"];
   
}

function getrst($var)
{

  if(empty($var) == false)
    if(strtolower(trim($var["ID"])) == strtolower(trim($GLOBALS["msgid"])))
        return $var;
       
}

//thanks to https://stackoverflow.com/questions/834303/startswith-and-endswith-functions-in-php
function startWith($str, $c, $sensitivity)
{

  if(trim($str) == "")
    return false;
  elseif(strlen(trim($str)) <= 0)
    return false;
  else
  {
 
    if($sensitivity == true)
   {
 
      if(strlen(trim($str)) == strlen(trim($c)))
     {
   
         if(trim($str) == trim($c))
             return true;
          else
            return false;

      }
 else
 {
   
     if(substr(trim($str), 0, strlen(trim($c))) == trim($c))
       return true;
     else
       return false;
 
 }
  
}
else
{

       if(strlen(trim($str)) == strlen(trim($c)))
      {
   
           if(trim(strtolower($str)) == trim(strtolower($c)))
             return true;
          else
            return false;

      }
      else
     {

         if(substr(trim(strtolower($str)), 0, strlen(trim($c))) == trim(strtolower($c)))
            return true;
        else
           return false;
 
     }
  
    }

  }
 
}

function endWith($str, $c, $sensitivity)
{

    if(trim($str) == "")
       return false;
    elseif(strlen(trim($str)) <= 0)
       return false;
    else
    {
 
        if($sensitivity == true)
       {
 
          if(strlen(trim($str)) == strlen(trim($c)))
         {
   
            if(trim($str) == trim($c))
              return true;
           else
             return false;

        }
        else
       {

          if(substr(trim($str), (strlen(trim($str)) - strlen(trim($c))), strlen(trim($c))) == trim($c))
             return true;
         else
             return false;
 
     }
  
  }
  else
  {
 
      if(strlen(trim($str)) == strlen(trim($c)))
      {
   
         if(trim(strtolower($str)) == trim(strtolower($c)))
            return true;
         else
          return false;

      }
      else
      {

   if(substr(trim(strtolower($str)), (strlen(trim($str)) - strlen(trim($c))), strlen(trim($c))) == trim(strtolower($c)))
          return true;
       else
          return false;
 
      }
  
  }
  
}

}

$originalstr = "Shipping zones";
$translatedstr = getTranslatedStringFromPOFile("woocommerce-es_ES.po", trim($originalstr));
echo "valor original=".$originalstr.", valor traducido=".$translatedstr."<br><br>";

$originalstr = "Error: non-existing attribute ID.";
$translatedstr = getTranslatedStringFromPOFile("woocommerce-es_ES.po", trim($originalstr));
echo "valor original=".$originalstr.", valor traducido=".$translatedstr."<br><br>";

$originalstr = "Bouvet Island";
$translatedstr = getTranslatedStringFromPOFile("woocommerce-es_ES.po", trim($originalstr));
echo "valor original=".$originalstr.", valor traducido=".$translatedstr."<br><br>";

?>


  El código sigue siendo básicamente el mismo, la única diferencia es que ahora, si el arreglo $translatedarray se encuentra vacio, se lee el archivo normalmente y se carga todo su contenido a esa variable, luego se manda a llamar a la función getTranslatedString que busca la llave y retorna el valor traducido.

  En caso de que ya halla datos en $translatedarray entonces se llama directo a getTranslatedString pasandole como parámetro la llave a buscar, si todo sale bien esta función nos retornará el valor de la llave, que es la cadena traducida.
En el ejemplo hay tres traducciones a realizar, y hasta el momento de la prueba (archivo woocommerce-es_ES.po que contiene 21935 línea de texto) apenas si consume tiempo. Espero les sea de mucha utilidad.

Procedencia de las imágenes:
File: Logo base de datos 
URL: http://images.all-free-download.com/images/graphiclarge/two_patch_icon_clip_art_9626.jpg
Licencia: Creative Commons

¿Te gustó este post?, entonces si lo deseas puedes apoyarnos para continuar con nuestra labor, gracias.



Licencia de Creative Commons Esta obra está bajo una licencia de Creative Commons Reconocimiento 4.0 Internacional, haga clic aquí para conocer más detalles.


Compartir:



Directorio de blogs, ¡agrega el tuyo!
Programas para el mantenimiento de Windows
Blog de seguridad informatica