@@ -72,13 +72,25 @@ abstract class CMSPlugin implements DispatcherAwareInterface, PluginInterface, L
7272 protected $ _type = null ;
7373
7474 /**
75- * Affects constructor behavior. If true, language files will be loaded automatically.
75+ * If true, language files of the plugin will be loaded automatically.
76+ *
77+ * NOTE: Enabling this feature have a negative effect on performance,
78+ * therefore it is recommended to load a language manually, in the respective event.
7679 *
7780 * @var boolean
7881 * @since 3.1
7982 */
8083 protected $ autoloadLanguage = false ;
8184
85+ /**
86+ * Internal flag for autoloadLanguage feature.
87+ *
88+ * @var boolean
89+ *
90+ * @since __DEPLOY_VERSION__
91+ */
92+ private $ autoloadLanguageDone = false ;
93+
8294 /**
8395 * Should I try to detect and register legacy event listeners, i.e. methods which accept unwrapped arguments? While
8496 * this maintains a great degree of backwards compatibility to Joomla! 3.x-style plugins it is much slower. You are
@@ -154,11 +166,6 @@ public function __construct($config = [])
154166 $ this ->_type = $ config ['type ' ];
155167 }
156168
157- // Load the language files if needed.
158- if ($ this ->autoloadLanguage ) {
159- $ this ->loadLanguage ();
160- }
161-
162169 if (property_exists ($ this , 'app ' )) {
163170 @trigger_error ('The application should be injected through setApplication() and requested through getApplication(). ' , E_USER_DEPRECATED );
164171 $ reflection = new \ReflectionClass ($ this );
@@ -178,6 +185,12 @@ public function __construct($config = [])
178185 $ this ->db = Factory::getDbo ();
179186 }
180187 }
188+
189+ // Load the language files if needed.
190+ // It is required Application to be set, so we trying it here and in CMSPlugin::setApplication()
191+ if ($ this ->autoloadLanguage && $ this ->getApplication ()) {
192+ $ this ->autoloadLanguage ();
193+ }
181194 }
182195
183196 /**
@@ -193,11 +206,26 @@ public function __construct($config = [])
193206 public function loadLanguage ($ extension = '' , $ basePath = JPATH_ADMINISTRATOR )
194207 {
195208 if (empty ($ extension )) {
196- $ extension = 'Plg_ ' . $ this ->_type . '_ ' . $ this ->_name ;
209+ $ extension = 'plg_ ' . $ this ->_type . '_ ' . $ this ->_name ;
197210 }
198211
199212 $ extension = strtolower ($ extension );
200- $ lang = $ this ->getApplication () ? $ this ->getApplication ()->getLanguage () : Factory::getLanguage ();
213+ $ app = $ this ->getApplication () ?: Factory::getApplication ();
214+ $ lang = $ app ->getLanguage ();
215+
216+ if (!$ lang ) {
217+ // @TODO: Throw an exception in Joomla 7
218+ @trigger_error (
219+ \sprintf (
220+ 'Trying to load language before Application is initialised is discouraged. This will throw an exception in 7.0. Plugin "%s/%s" ' ,
221+ $ this ->_type ,
222+ $ this ->_name
223+ ),
224+ E_USER_DEPRECATED
225+ );
226+
227+ return false ;
228+ }
201229
202230 // If language already loaded, don't load it again.
203231 if ($ lang ->getPaths ($ extension )) {
@@ -208,6 +236,35 @@ public function loadLanguage($extension = '', $basePath = JPATH_ADMINISTRATOR)
208236 || $ lang ->load ($ extension , JPATH_PLUGINS . '/ ' . $ this ->_type . '/ ' . $ this ->_name );
209237 }
210238
239+ /**
240+ * Method to handle language autoload feature in safe way, only when the language is initialised.
241+ *
242+ * @return void
243+ *
244+ * @internal The method does not expect to be called outside the CMSPlugin class.
245+ *
246+ * @since __DEPLOY_VERSION__
247+ */
248+ final protected function autoloadLanguage (): void
249+ {
250+ if ($ this ->autoloadLanguageDone ) {
251+ return ;
252+ }
253+
254+ $ app = $ this ->getApplication ();
255+
256+ // Check whether language already initialised in the Application, otherwise wait for it
257+ if (!$ app ->getLanguage ()) {
258+ $ app ->getDispatcher ()->addListener ('onAfterInitialise ' , function () {
259+ $ this ->loadLanguage ();
260+ });
261+ } else {
262+ $ this ->loadLanguage ();
263+ }
264+
265+ $ this ->autoloadLanguageDone = true ;
266+ }
267+
211268 /**
212269 * Registers legacy Listeners to the Dispatcher, emulating how plugins worked under Joomla! 3.x and below.
213270 *
@@ -426,6 +483,11 @@ public function setApplication(CMSApplicationInterface $application): void
426483 if ($ application ->getLanguage ()) {
427484 $ this ->setLanguage ($ application ->getLanguage ());
428485 }
486+
487+ // Try to load the language files if it were not loaded in the constructor already.
488+ if ($ this ->autoloadLanguage ) {
489+ $ this ->autoloadLanguage ();
490+ }
429491 }
430492
431493 /**
0 commit comments