Continued:
[core.git] / framework / main / classes / language / class_LanguageSystem.php
1 <?php
2 // Own namespace
3 namespace Org\Mxchange\CoreFramework\Localization;
4
5 // Import framework stuff
6 use Org\Mxchange\CoreFramework\Bootstrap\FrameworkBootstrap;
7 use Org\Mxchange\CoreFramework\Localization\ManageableLanguage;
8 use Org\Mxchange\CoreFramework\Object\BaseFrameworkSystem;
9 use Org\Mxchange\CoreFramework\ObjectArray\FrameworkArrayObject;
10 use Org\Mxchange\CoreFramework\Registry\Registerable;
11 use Org\Mxchange\CoreFramework\Registry\GenericRegistry;
12
13 // Import SPL stuff
14 use \InvalidArgumentException;
15
16 /**
17  * The language sub-system for handling language strings being used in the
18  * application and whole framework
19  *
20  * @author              Roland Haeder <webmaster@shipsimu.org>
21  * @version             0.0.0
22  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2019 Core Developer Team
23  * @license             GNU GPL 3.0 or any newer version
24  * @link                http://www.shipsimu.org
25  *
26  * This program is free software: you can redistribute it and/or modify
27  * it under the terms of the GNU General Public License as published by
28  * the Free Software Foundation, either version 3 of the License, or
29  * (at your option) any later version.
30  *
31  * This program is distributed in the hope that it will be useful,
32  * but WITHOUT ANY WARRANTY; without even the implied warranty of
33  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
34  * GNU General Public License for more details.
35  *
36  * You should have received a copy of the GNU General Public License
37  * along with this program. If not, see <http://www.gnu.org/licenses/>.
38  */
39 class LanguageSystem extends BaseFrameworkSystem implements ManageableLanguage, Registerable {
40         /**
41          * The full-qualified base path for the language include files
42          */
43         private $languageBasePath = '';
44
45         /**
46          * The 2-char language code
47          */
48         private $langCode = 'xx'; // This will later be overwritten!
49
50         /**
51          * The array-object for all language strings
52          */
53         private $langStrings = NULL;
54
55         /**
56          * An instance of this class
57          */
58         private static $selfInstance = NULL;
59
60         /**
61          * Protected constructor
62          *
63          * @return      void
64          */
65         protected function __construct () {
66                 // Call parent constructor
67                 parent::__construct(__CLASS__);
68         }
69
70         /**
71          * Creates an instance of the class LanguageSystem and prepares it for usage
72          *
73          * @param       $languageBasePath       The local base path for all language strings or emty for auto-detection
74          * @return      $langInstance   An instance of LanguageSystem
75          * @throws      InvalidArgumentException        If languageBasePath remains empty (@TODO Get rid of that old-lost code)
76          * @throws      InvalidLanguagePathStringException      If $languageBasePath is no string
77          * @throws      LanguagePathIsNoDirectoryException      If $languageBasePath is no
78          *                                                                              directory or not found
79          * @throws      LanguagePathReadProtectedException      If $languageBasePath is
80          *                                                                              read-protected
81          */
82         public static final function createLanguageSystem ($languageBasePath = '') {
83                 // Get a new instance
84                 $langInstance = new LanguageSystem();
85
86                 // Is the base path set?
87                 if (empty($languageBasePath)) {
88                         // No, then attempt "auto-dection":
89                         // 1) Get application
90                         $applicationInstance = GenericRegistry::getRegistry()->getInstance('application');
91
92                         // 2) Try to build it
93                         $languageBasePath = sprintf('%s%s/language/',
94                                 $langInstance->getConfigInstance()->getConfigEntry('application_base_path'),
95                                 $applicationInstance->getAppShortName()
96                         );
97                 } // END - if
98
99                 // Is the base path valid?
100                 if (empty($languageBasePath)) {
101                         // Language path is empty
102                         throw new InvalidArgumentException('languageBasePath is still empty');
103                 } elseif (!is_string($languageBasePath)) {
104                         // Is not a string
105                         throw new InvalidLanguagePathStringException(array($langInstance, $languageBasePath), self::EXCEPTION_INVALID_STRING);
106                 } elseif (!is_dir($languageBasePath)) {
107                         // Is not a path
108                         throw new LanguagePathIsNoDirectoryException(array($langInstance, $languageBasePath), self::EXCEPTION_INVALID_PATH_NAME);
109                 } elseif (!is_readable($languageBasePath)) {
110                         // Is not readable
111                         throw new LanguagePathReadProtectedException(array($langInstance, $languageBasePath), self::EXCEPTION_READ_PROTECED_PATH);
112                 }
113
114                 // Set the base path
115                 $langInstance->setLanguageBasePath($languageBasePath);
116
117                 // Initialize the variable stack
118                 $langInstance->initLanguageStrings();
119
120                 // Set language code from default config
121                 $langInstance->setLanguageCode(FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('default_lang'));
122
123                 // Remember this instance
124                 self::$selfInstance = $langInstance;
125
126                 // Return the prepared instance
127                 return $langInstance;
128         }
129
130         /**
131          * Singleton getter for this instance
132          *
133          * @return      $selfInstance   An instance of this class
134          */
135         public static final function getSelfInstance () {
136                 return self::$selfInstance;
137         }
138
139         /**
140          * Setter for base path
141          *
142          * @param       $languageBasePath       The relative base path for all language files
143          * @return      void
144          */
145         protected final function setLanguageBasePath ($languageBasePath) {
146                 // And set it
147                 $this->languageBasePath = (string) $languageBasePath;
148         }
149
150         /**
151          * Setter for language code
152          *
153          * @param       $langCode       The language code for the current application
154          * @return      void
155          */
156         protected final function setLanguageCode ($langCode) {
157                 // Cast it
158                 $langCode = (string) $langCode;
159
160                 // And set it (only 2 chars)
161                 $this->langCode = substr($langCode, 0, 2);
162         }
163
164         /**
165          * Initialize the array-object for all later language strings
166          *
167          * @return      void
168          */
169         public function initLanguageStrings () {
170                 /*
171                  * Locale category constants are usually predefined, but may not be
172                  * on some systems such as Win32.
173                  *
174                  * Origin: StatusNet's lib/language.php
175                  */
176                 $localeCategories = array(
177                         'LC_CTYPE',
178                         'LC_NUMERIC',
179                         'LC_TIME',
180                         'LC_COLLATE',
181                         'LC_MONETARY',
182                         'LC_MESSAGES',
183                         'LC_ALL'
184                 );
185
186                 // Set all, if not defined
187                 foreach ($localeCategories as $key => $name) {
188                         // Is it set?
189                         if (!defined($name)) {
190                                 // No, then set it
191                                 define($name, $key);
192                         } // END - if
193                 } // END - foreach
194
195                 // Init language strings array
196                 $this->langStrings = new FrameworkArrayObject('FakedLanguageStrings');
197         }
198
199         /**
200          * Getter for language code
201          *
202          * @return      $langCode       The language code for the current application
203          */
204         public final function getLanguageCode () {
205                 return $this->langCode;
206         }
207
208         /**
209          * Get the plain message from the cache variable for the given message id
210          *
211          * @param       $messageId              The message id we shall find in the cache variable
212          * @return      $messageText    The plain message text
213          */
214         public function getMessage ($messageId) {
215                 // Default is missing message text
216                 $messageText = sprintf('!%s!',
217                         $messageId
218                 );
219
220                 // Try to look it up in the cache variable
221                 if ($this->langStrings->offsetExists($messageId)) {
222                         // Return the message string
223                         $messageText = $this->langStrings->offsetGet($messageId);
224                 } // END - if
225
226                 // Return the text
227                 return $messageText;
228         }
229
230 }