Extracts the messages and translations from the MO file

@throws \Aimeos\MW\Translation\Exception If file content is invalid
@return array Associative list of original singular as keys and one or more translations as values
2493
protected function extract()
	{
		$magic = $this->readInt( 'V' );

		if( ( $magic === self::MAGIC1 ) || ( $magic === self::MAGIC3 ) ) { //to make sure it works for 64-bit platforms
			$byteOrder = 'V'; //low endian
		} elseif( $magic === ( self::MAGIC2 & 0xFFFFFFFF ) ) {
			$byteOrder = 'N'; //big endian
		} else {
			throw new \Aimeos\MW\Translation\Exception( 'Invalid MO file' );
		}

		$this->readInt( $byteOrder );
		$total = $this->readInt( $byteOrder ); //total string count
		$originals = $this->readInt( $byteOrder ); //offset of original table
		$trans = $this->readInt( $byteOrder ); //offset of translation table

		$this->seekto( $originals );
		$originalTable = $this->readIntArray( $byteOrder, $total * 2 );
		$this->seekto( $trans );
		$translationTable = $this->readIntArray( $byteOrder, $total * 2 );

		return $this->extractTable( $originalTable, $translationTable, $total );
	}
325139
protected function getContents()
    {
        // Cancel if the file doesn't exist
        if (!$this->getFilesystem()->has($this->getFilepath())) {
            return [];
        }

        // Get and parse file
        if ($this->contents === null) {
            $this->contents = $this->getFilesystem()->read($this->getFilepath());
            $this->contents = json_decode($this->contents, true);
        }

        return (array) $this->contents;
    }
92632
private function getPostedLocales()
    {
        $localeIDs = [];
        $list = $this->post('translatedLocales');
        if (is_array($list)) {
            $localeIDs = array_merge($localeIDs, $list);
        }
        $list = $this->post('untranslatedLocales');
        if (is_array($list)) {
            $localeIDs = array_merge($localeIDs, $list);
        }
        $repo = $this->app->make(LocaleRepository::class);
        $locales = $repo->getApprovedLocales();
        $result = [];
        foreach ($locales as $locale) {
            if (in_array($locale->getID(), $localeIDs, true)) {
                $result[] = $locale;
            }
        }

        $count = count($result);
        if ($count === 0) {
            throw new UserMessageException(t('Please specify the languages of the .po/.mo files to generate'));
        }
        if ($this->maxLocalesCount && $count > (int) $this->maxLocalesCount) {
            throw new UserMessageException(t('Please specify up to %s languages (you requested %2$s languages)', $this->maxLocalesCount, $count));
        }

        return $result;
    }
1212150
public function getFieldsTranslations()
    {
        $fieldList = parent::getFieldsTranslations();

        // Add the key values (so organization id is present)
        $keys = array_combine(array_values($this->_targetModel->getKeys()), array_values($this->_targetModel->getKeys()));
        $fieldList = $fieldList + $keys;

        $fieldList['grs_email'] = 'gr2o_email';

        return $fieldList;
    }
940530
private function extractGettextStrings()
    {
        $translation = null;
        $translationObjects = array();
        $lookupDirectories = array(
            Strata::getVendorPath() . 'strata-mvc' . DIRECTORY_SEPARATOR . 'strata' . DIRECTORY_SEPARATOR . 'src',
            Strata::getSrcPath(),
            Strata::getThemesPath(),
        );

        foreach ($lookupDirectories as $directory) {
            $translationObjects = $this->recurseThroughDirectory($directory);

            // Merge all translation objects into a bigger one
            foreach ($translationObjects as $t) {
                if (is_null($translation)) {
                    $translation = $t;
                } else {
                    $translation->mergeWith($t);
                }
            }
        }

        return $translation;
    }
629079
public function getTranslations()
    {
        return $this->owner->hasMany($this->translationClassName, [$this->languageForeignKey => $this->_ownerPrimaryKey]);
    }
148922
public function extract()
    {
        
        foreach ($this->getPaths() as $path){
        	// In the RDFExtractor, we expect the paths to points directly to the file.
        	if (!file_exists($path)){
        		throw new tao_helpers_translation_TranslationException("No RDF file to parse at '${path}'.");	
        	}
        	else if (!is_readable($path)){
        		throw new tao_helpers_translation_TranslationException("'${path}' is not readable. Please check file system rights.");	
        	}
        	else{
	        	try{
	        		$tus = array();
	        		$rdfNS = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
	        		$rdfsNS = 'http://www.w3.org/2000/01/rdf-schema#';
	        		$xmlNS = 'http://www.w3.org/XML/1998/namespace'; // http://www.w3.org/TR/REC-xml-names/#NT-NCName
	        		
	        		$translatableProperties = $this->translatableProperties;
	        		
	        		// Try to parse the file as a DOMDocument.
	        		$doc = new DOMDocument('1.0', 'UTF-8');
	        		$doc->load(realpath($path));
	        		if ($doc->documentElement->hasAttributeNS($xmlNS, 'base')) {
	        			$this->xmlBase[$path] = $doc->documentElement->getAttributeNodeNS($xmlNS, 'base')->value; 
	        		}
	        		
	        		$descriptions = $doc->getElementsByTagNameNS($rdfNS, 'Description');
	        		foreach ($descriptions as $description){
	        			if ($description->hasAttributeNS($rdfNS, 'about')){
	        				$about = $description->getAttributeNodeNS($rdfNS, 'about')->value;
	        				
	        				// At the moment only get rdfs:label and rdfs:comment
	        				// c.f. array $translatableProperties
	        				// In the future, this should be configured in the constructor
	        				// or by methods.
	        				$children = array();
	        				foreach ($translatableProperties as $prop){
	        					$uri = explode('#', $prop);
	        					if (count($uri) == 2){
	        						$uri[0] .= '#';
	        						$nodeList = $description->getElementsByTagNameNS($uri[0], $uri[1]);
	        						
	        						for ($i = 0; $i < $nodeList->length; $i++) {
	        							$children[] = $nodeList->item($i);
	        						}
	        					}
	        				}
	        				
	        				foreach ($children as $child) {
	        					// Only process if it has a language attribute.
								$tus = $this->processUnit($child, $xmlNS, $about, $tus);
							}
	        			}
	        			else{
	        				// Description about nothing.
	        				continue;	
	        			}
	        		}
	        		
	        		$this->setTranslationUnits($tus);

	        	} catch (DOMException $e){
	        		throw new tao_helpers_translation_TranslationException("Unable to parse RDF file at '${path}'. DOM returns '" . $e->getMessage() . "'.");
	        	}	
        	}
        }
        
    }
4540
public function getDirectives()
    {
        return [
            'lang' => [$this, 'translate'],
            'translate' => [$this, 'translate'],
            'sprintf' => [$this, 'sprintf'],
            'plural' => [$this, 'plural'],
            'choice' => [$this, 'plural'],
            'messages' => [$this, 'messages'],
            'widget' => [$this, 'widget'],
            'route' => [$this, 'route'],
            'formToken' => [$this, 'formToken'],

            // Authorisation
            'auth' => [$this, 'auth'],
            'can' => [$this, 'auth'],
            'cannot' => [$this, 'cannot'],
            'endcan' => [$this, 'endauth'],
            'endcannot' => [$this, 'endauth'],
            'endauth' => [$this, 'endauth'],

            // Asset
            'css' => [$this, 'css'],
            'js' => [$this, 'js'],
            'assetTemplate' => [$this, 'assetTemplate'],
            'endTemplate' => [$this, 'endTemplate'],
            'attr' => [$this, 'attr'],

            // Debug
            'shown' => [$this, 'shown'],
            'dd' => [$this, 'dd'],
            'ds' => [$this, 'ds'],
            'die' => [$this, 'dead'],
            'debug' => [$this, 'debug'],
            'enddebug' => [$this, 'endauth'],
        ];
    }
295511
public function extractTranslationsFromFolders($folders, $trans_methods, $php_file_extension = 'php')
    {
        $lemmas = [];

        foreach ($folders as $path) {
            foreach ($this->getFilesWithExtension($path, $php_file_extension) as $php_file_path => $dumb) {
                $lemma = [];

                foreach ($this->extractTranslationFromPhpFile($php_file_path, $trans_methods) as $k => $v) {
                    $a = $this->evalString($k);
                    if (is_string($a)) {
                        $real_value         = $a;
                        $lemma[$real_value] = $php_file_path;
                    } else {
                        $this->messageBag->writeError("Unable to understand string $k");
                    }
                }

                $lemmas = array_merge($lemmas, $lemma);
            }
        }

        return $lemmas;
    }
946371
public function extract() {
        foreach ($this->log as $line) {
            foreach ($this->messageGroupsJoined as $header => $keywords) {
                $pattern = $this->getPattern($keywords);

                if (preg_match($pattern, $line)) {
                    $this->appendToGroup($header, $line, $pattern);
                }
            }
        }

        // Remove empty groups
        foreach (array_keys($this->messageGroups) as $groupKey) {
            if (true === empty($this->groups[$groupKey])) {
                unset($this->messageGroups[$groupKey]);
            }
        }

        // The array_merge sorts $messageGroups basing on $groups
        return array_merge($this->messageGroups, $this->groups);
    }
429492
protected function getTranslations( $domain )
	{
		if( !isset( $this->files[$domain] ) )
		{
			if ( !isset( $this->sources[$domain] ) )
			{
				$msg = sprintf( 'No translation directory for domain "%1$s" available', $domain );
				throw new \Aimeos\MW\Translation\Exception( $msg );
			}

			// Reverse locations so the former gets not overwritten by the later
			$locations = array_reverse( $this->getTranslationFileLocations( $this->sources[$domain], $this->getLocale() ) );

			foreach( $locations as $location ) {
				$this->files[$domain][$location] = new \Aimeos\MW\Translation\File\Mo( $location );
			}
		}

		return ( isset( $this->files[$domain] ) ? $this->files[$domain] : [] );
	}
955451
public function collectFromFiles()
    {
        $translationKeys = [];

        foreach ($this->getAllViewFilesWithTranslations() as $file => $matches) {
            foreach ($matches as $key) {
                try {
                    list($fileName, $keyName) = explode('.', $key, 2);
                } catch (\ErrorException $e) {
                    continue;
                }

                if (isset($translationKeys[$fileName]) && in_array($keyName, $translationKeys[$fileName])) {
                    continue;
                }

                $translationKeys[$fileName][] = $keyName;
            }
        }

        return $translationKeys;
    }
406778
public static function ListAll()
    {
        $data = [];
        //
        $folders = glob(Application::$root.'resources/translator/*');
        //
        foreach ($folders as $key => $value) {
            $folder = \Strings::splite($value, 'resources/translator/');
            $folder = $folder[1];
            //
            $data[] = '>'.$folder;
            //
            foreach (glob(Application::$root.'resources/translator/'.$folder.'/*.php') as $key2 => $value2) {
                $file = \Strings::splite($value2, "app/lang/$folder/");
                $file = $file[1];
                //
                $data[] = '   '.$file;
            }
        }
        //
        return $data;
    }
54233
private function getTranslatedMessage(Exception $exception)
    {
        $message = $exception->getMessage();
        if ($exception instanceof Translatable) {
            $message = $this->translator->trans($exception->getMessageTemplate(), $exception->getParameters(), 'repository_exceptions');
        }

        return $message;
    }
417329
public static function getAllStrings()
    {
        if (is_null(self::$dir) || is_null(self::$locale)) {
            throw new \Exception('Locales directory and locale must be set');
        }

        $strings = [];
        foreach (scandir(self::$dir . '/' . self::$locale) as $text_domain) {
            if ($text_domain == '.' || $text_domain == '..') {
                continue;
            }

            /** @noinspection PhpIncludeInspection */
            foreach ((array)require self::$dir . '/' . self::$locale . '/' . $text_domain as $string => $value) {
                $strings[$string] = $value;
            }
        }

        return $strings;
    }
732594
protected function load_messages(){
        if($this->messages == NULL || $this->locale != $this->messagesLocale){
            if($this->locale != NULL){
                if(file_exists($this->dir_content . "_$this->locale" . '.txt')){
                    $this->messages= file($this->dir_content . "_$this->locale" . '.txt');
                    $this->messages= $this->parse_properties($this->messages);
                    $this->messagesLocale= $this->locale;
                }
            }
            if($this->messages == NULL){
                $this->messages= file($this->dir_content . '.txt');
                $this->messages= $this->parse_properties($this->messages);
                $this->messagesLocale= NULL;
            }
        }
    }
155725
public function getLanguageList() {
		$files = glob($this->getPath().'messages_*.php');
		
		$startAt = strlen('messages_');
		$languages = array();
		foreach ($files as $file) {
			$base = basename($file);
			$languages[] = substr($base, $startAt, strrpos($base, '.php') - $startAt);
		}
		return $languages;
	}