is invalid", ezcTranslationException::NOT_CONFIGURED ); } $this->setOptions( array( 'location' => $location ) ); $this->setOptions( $options ); $this->tsFilenameFormat = '[LOCALE].xml'; } /** * Sets configuration data * * This backend accepts two settings which can be set through this * function. The two options are 'location' that specifies the directory to * the translation files and 'format' that specifies the of the * translation's filename. In this format, the special placeholder [LOCALE] * will be replaced with the requested locale's name. The options will be * stored in the private properties $tsLocationPath and $tsFilenameFormat. * * Example: * * setOptions( * array( 'location' => 'usr/share/translations', * 'format' => 'translation-[LOCALE].xml' ) * ); * ?> * * * @param array $configurationData */ public function setOptions( $configurationData ) { foreach ( $configurationData as $name => $value ) { switch ( $name ) { case 'location': if ( $value[strlen( $value ) - 1] != '/' ) { $value .= '/'; } $this->tsLocationPath = $value; break; case 'format': $this->tsFilenameFormat = $value; break; default: throw new ezcBaseConfigException( $name, ezcBaseConfigException::UNKNOWN_CONFIG_SETTING ); } } } /** * Builds a filename for the translation file * * This function uses the tsLocationPath and tsFilenameFormat properties, * combined with the $locale parameter to form a filename that contains the * translation belonging to the specified locale. * * @param string $locale The string containing the locale. * @returns string The built filename. */ public function buildTranslationFileName( $locale ) { $filename = $this->tsLocationPath . $this->tsFilenameFormat; $filename = str_replace( '[LOCALE]', $locale, $filename ); return $filename; } /** * Creates an SimpleXML parser object for the specified locale * * This function checks if the tsLocationPath setting is made, if the file * with the filename as returned by buildTranslationFileName() exists and * creates a SimpleXML parser object for this file. If either the setting * is not made, or the file doesn't exists it throws an exception. * * @param string $locale The string containing the locale. * @param string $returnClass The class of the returned XML Parser Object. * @returns object The created parser. The parameter $returnClass * determines what type of class gets returned. The * classname that you specify should be inherited from * SimpleXMLElement. */ public function openTranslationFile( $locale, $returnClass = 'SimpleXMLElement' ) { $filename = $this->buildTranslationFileName( $locale ); if ( !file_exists( $filename ) ) { throw new ezcTranslationException( "The translation file <{$filename}> does not exist", ezcTranslationException::MISSING_TRANSLATION_FILE ); } return simplexml_load_file( $filename, $returnClass ); } /** * */ private function parseSimpleXMLMessage( $message ) { $status = ezcTranslationData::TRANSLATED; if ( $message->translation['type'] == 'unfinished' ) { $status = ezcTranslationData::UNFINISHED; } else if ( $message->translation['type'] == 'obsolete' ) { return null; } $source = trim( (string) $message->source ); $translation = trim( (string) $message->translation ); $comment = trim( (string) $message->comment ); $source = strlen( $source ) ? $source : false; $translation = strlen( $translation ) ? $translation : false; $comment = strlen( $comment ) ? $comment : false; return new ezcTranslationData( $source, $translation, $comment, $status ); } /** * Returns a array containing a translation map. * * This method returns an array containing the translation map for the * specified $locale and $context. It uses the $tsLocationPath and * $tsFilenameFormat properties to locate the file, unless caching is * enabled. * * @param $locale string The locale to retrieve translations for * @param $context string The translation context to retrieve translations for * @returns array[ezcTranslationData] * @throws ezcTranslationException when a context is not available * @throws ezcTranslationException when the translation file does not exist. * @throws ezcTranslationException when the $tsLocationPath and * $tsFilenameFormat are not set before this * method is called. */ public function getContext( $locale, $context ) { $ts = $this->openTranslationFile( $locale ); $contextElements = array(); foreach ( $ts as $trContext ) { if ( (string) $trContext->name == $context ) { foreach ( $trContext as $message ) { if ( $message->source != '' ) { $element = $this->parseSimpleXMLMessage( $message ); if ( is_null( $element ) ) { continue; } $contextElements[] = $element; } } return $contextElements; } } throw new ezcTranslationException( "The context <{$context}> does not exist.", ezcTranslationException::CONTEXT_NOT_AVAILABLE ); } /** * Initializes the reader * * Opens the translation file. * * @param string $locale The locale to read from. * @throws ezcTranslationException when the $tsLocationPath and * $tsFilenameFormat are not set before this * method is called. */ public function initReader( $locale ) { $this->xmlParser = $this->openTranslationFile( $locale, 'SimpleXMLIterator' ); $this->xmlParser->rewind(); } /** * Deinitializes the reader * * This method should be called after the haveMore() method returns false * to cleanup resources. * * @throws ezcTranslationException when the reader is not initialized with * initReader(). */ public function deinitReader() { $this->xmlParser = null; } /** * Returns whether there are more contexts available. * * This method parses a little bit more of the XML file to be able to * return the next context. If no more contexts are available it returns * false, if it read a context from the file the method returns true. * * @throws ezcTranslationException when the reader is not initialized with * initReader(). * @return boolean */ public function haveMore() { if ( is_null( $this->xmlParser ) ) { throw new ezcTranslationException( 'The reader is not initialized with the initReader() method.', ezcTranslationException::READER_NOT_INITIALIZED ); } $valid = $this->xmlParser->valid(); if ( $valid ) { $newContext = array( trim( $this->xmlParser->getChildren()->name), array() ); foreach ( $this->xmlParser->getChildren()->message as $data ) { $translationItem = $this->parseSimpleXMLMessage( $data ); if ( !is_null( $translationItem ) ) { $newContext[1][] = $translationItem; } } $this->currentContext = $newContext; $this->xmlParser->next(); } return $valid; } /** * Returns the current context * * This method returns the latest read context, that the haveMore() method * put into the $currentContext property. * * @return array The current context's translation map * @throws ezcTranslationException when the reader is not initialized with * initReader(). */ public function readContext() { if ( is_null( $this->xmlParser ) ) { throw new ezcTranslationException( 'The reader is not initialized with the initReader() method.', ezcTranslationException::READER_NOT_INITIALIZED ); } return $this->currentContext; } } ?>