Get text message does not parse the PO files

I have the following PO file:




msgid ""

msgstr ""

"Project-Id-Version: fewf\n"

"POT-Creation-Date: \n"

"PO-Revision-Date: \n"

"Last-Translator: \n"

"Language-Team: wefwef <ewf>\n"

"MIME-Version: 1.0\n"

"Content-Type: text/plain; charset=utf-8\n"

"Content-Transfer-Encoding: 8bit\n"


msgid "Hello"

msgstr "REPLACED"



when the function




/**

	 * Loads messages from a PO file.

	 * @param string file path

	 * @param string message context

	 * @return array message translations (source message => translated message)

	 */

	public function load($file,$context)

	{

		$pattern='/msgctxt\s+"(.*?(?<!\\\\))"'

			. '\s+msgid\s+"(.*?(?<!\\\\))"'

			. '\s+msgstr\s+"(.*?(?<!\\\\))"/';

		$content=file_get_contents($file);

        $n=preg_match_all($pattern,$content,$matches);

        $messages=array();

        for($i=0;$i<$n;++$i)

        {

        	if($matches[1][$i]===$context)

        	{

	        	$id=$this->decode($matches[2][$i]);

	        	$message=$this->decode($matches[3][$i]);

	        	$messages[$id]=$message;

	        }

        }

        return $messages;

	}



from the CGettextPoFile class runs it returns nothing, Even the $matches returns nothing, meaning it does not parse the PO file correctly.

Any idea why?

Maybe it’s a dumb question, but have you checked that $content does have the actual PO file loaded?

Yea, I did lots of tests including checking that it loads the correct file, and loads the content into the variable, But i got to the point that the problem is with the regex that does not match anything inside the PO file. Which seems to be as a bug since the regex doesn’t work.

The problem is that the current regex looks for message context (msgctxt) in every "record" like




msgctxt ""

msgid "Hello"

msgstr "REPLACED"


msgctxt ""

msgid "Hello2"

msgstr "REPLACED2"



So the regex should be changed so that the context msgctxt is optional (enclosed in ( … )? in the regex) and the $matches index should be set appropriately…

here is the new load() function that works:




    public function load($file,$context)

    {

                $pattern='/(msgctxt\s+"(.*?(?<!\\\\))")?'

                        . '\s+msgid\s+"(.*?(?<!\\\\))"'

                        . '\s+msgstr\s+"(.*?(?<!\\\\))"/';

        $content=file_get_contents($file);

        $n=preg_match_all($pattern,$content,$matches);

        $messages=array();

        for($i=0;$i<$n;++$i)

        {

            if($matches[2][$i]===$context)

            {

                $id=$this->decode($matches[3][$i]);

                $message=$this->decode($matches[4][$i]);

                $messages[$id]=$message;

            }

        }

        return $messages;

    }



I see, SO in other words it seems to be as this is a bug in the framework unless the msgctxt must exist for every record.

PO file specification say that the msgctxt is optional… in Yii this is used for the context… so if you are using translations for different contexts than you should use the msgctxt on every record in this implementation as it is now…

A little bit off topc, but I’d change form gettext to simple arrays and use APC to keep those translation files in memory. This is a really heavy and time consuming regular expression you’d run many many times for each page request.

Yes, Though on a production environment you will be using the MO files isntead which are complied.