1: <?php
2: /**
3: * This code is licensed under AGPLv3 license or Afterlogic Software License
4: * if commercial version of the product was purchased.
5: * For full statements of the licenses see LICENSE-AFTERLOGIC and LICENSE-AGPL3 files.
6: */
7:
8: namespace Aurora\System\Module;
9:
10: use Aurora\Api;
11: use Illuminate\Support\Str;
12:
13: /**
14: * @license https://www.gnu.org/licenses/agpl-3.0.html AGPL-3.0
15: * @license https://afterlogic.com/products/common-licensing Afterlogic Software License
16: * @copyright Copyright (c) 2019, Afterlogic Corp.
17: *
18: * @package Api
19: */
20: abstract class AbstractModule
21: {
22: /**
23: * @var string
24: */
25: protected $sPath;
26:
27: /**
28: * @var string
29: */
30: protected $sVersion;
31:
32: /**
33: * @var array
34: */
35: protected $aManagersCache = [];
36:
37: /**
38: * @var array
39: */
40: protected $aParameters;
41:
42: /**
43: * @var array
44: */
45: protected $aObjects = [];
46:
47: /**
48: * @var \MailSo\Base\Http
49: */
50: public $oHttp;
51:
52: /**
53: * @var array
54: */
55: protected $aConfig;
56:
57: /**
58: *
59: * @var \Aurora\System\Module\Settings
60: */
61: public $oModuleSettings = null;
62:
63: /**
64: *
65: * @var array
66: */
67: protected $aSettingsMap = [];
68:
69: /**
70: *
71: * @var string
72: */
73: public static $Delimiter = '::';
74:
75: /**
76: *
77: * @var bool
78: */
79: protected $bInitialized = false;
80:
81: /**
82: *
83: * @var array
84: */
85: protected $aRequireModules = [];
86:
87: /**
88: *
89: * @var array
90: */
91: protected $aSkipedEvents = [];
92:
93: /**
94: *
95: * @var array
96: */
97: public $aErrors = [];
98:
99: /**
100: *
101: * @var array
102: */
103: public $aAdditionalEntityFieldsToEdit = [];
104:
105: /**
106: *
107: * @var Manager
108: */
109: protected $oModuleManager = null;
110:
111: /**
112: *
113: * @var boolean
114: */
115: protected $bIsPermanent = false;
116:
117: protected $aDeniedMethodsByWebApi = [
118: '__construct',
119: 'init',
120: 'initialize',
121: 'createInstance',
122: 'getInstance',
123: 'Decorator',
124: 'RequireModule',
125: 'GetRequireModules',
126: 'isPermanent',
127: 'isValid',
128: 'getNamespace',
129: 'getModuleSettings',
130: 'loadModuleSettings',
131: 'saveModuleConfig',
132: 'getConfig',
133: 'setConfig',
134: 'denyMethodsCallByWebApi',
135: 'denyMethodCallByWebApi',
136: 'subscribeEvent',
137: 'broadcastEvent',
138: 'skipEvent',
139: 'removeEventFromSkiped',
140: 'includeTemplate',
141: 'extendObject',
142: 'getExtendedObject',
143: 'issetObject',
144: 'SetPath',
145: 'GetHash',
146: 'GetName',
147: 'GetPath',
148: 'GetVersion',
149: 'GetFullName',
150: 'AddEntry',
151: 'AddEntries',
152: 'HasEntry',
153: 'RemoveEntry',
154: 'RemoveEntries',
155: 'GetEntryCallback',
156: 'DefaultResponse',
157: 'TrueResponse',
158: 'FalseResponse',
159: 'ExceptionResponse',
160: 'CallMethod',
161: 'i18N',
162: 'GetErrors',
163: 'GetErrorMessageByCode',
164: 'GetAdditionalEntityFieldsToEdit',
165: ];
166:
167: /**
168: *
169: * @var array
170: */
171: protected $aLang;
172:
173: /**
174: * @param string $sVersion
175: */
176: public function __construct($sPath, $sVersion = '1.0')
177: {
178: $this->sVersion = (string) $sVersion;
179:
180: $this->sPath = $sPath . self::GetName();
181: $this->aParameters = [];
182: $this->oHttp = \MailSo\Base\Http::SingletonInstance();
183: $this->oModuleManager = \Aurora\System\Api::GetModuleManager();
184: }
185:
186: /**
187: *
188: * @return void
189: */
190: abstract public function init();
191:
192: /**
193: *
194: * @param string $sPath
195: * @param string $sVersion
196: * @return \Aurora\System\Module\AbstractModule
197: */
198: public static function createInstance($sPath, $sVersion = '1.0')
199: {
200: /* @phpstan-ignore-next-line */
201: return new static($sPath, $sVersion);
202: }
203:
204: /**
205: *
206: * @return \Aurora\System\Module\AbstractModule
207: */
208: public static function getInstance()
209: {
210: return \Aurora\System\Api::GetModule(self::GetName());
211: }
212:
213: /**
214: *
215: * @return \Aurora\System\Module\Decorator
216: */
217: public static function Decorator()
218: {
219: return \Aurora\System\Api::GetModuleDecorator(self::GetName());
220: }
221:
222: /**
223: *
224: * @param \Aurora\System\Module\Manager $oModuleManager
225: * @return \Aurora\System\Module\Manager
226: */
227: protected function SetModuleManager(Manager $oModuleManager)
228: {
229: return $this->oModuleManager = $oModuleManager;
230: }
231:
232: /**
233: *
234: * @return \Aurora\System\Module\Manager
235: */
236: protected function GetModuleManager()
237: {
238: return $this->oModuleManager;
239: }
240:
241: /**
242: *
243: * @param string $sModule
244: */
245: public function RequireModule($sModule)
246: {
247: if (!in_array($sModule, $this->aRequireModules)) {
248: $this->aRequireModules[] = $sModule;
249: }
250: }
251:
252: /**
253: *
254: * @return array
255: */
256: public function GetRequireModules()
257: {
258: return $this->aRequireModules;
259: }
260:
261: /**
262: *
263: * @return boolean
264: */
265: public function isPermanent()
266: {
267: return $this->bIsPermanent;
268: }
269:
270: /**
271: *
272: * @return boolean
273: */
274: public function isValid()
275: {
276: return true;
277: }
278:
279: /**
280: *
281: * @return boolean
282: */
283: protected function isAllowedModule()
284: {
285: return $this->isPermanent() || $this->oModuleManager->IsAllowedModule(self::GetName());
286: }
287:
288: /**
289: *
290: * @return boolean
291: */
292: protected function isInitialized()
293: {
294: return (bool) $this->bInitialized;
295: }
296:
297: protected function initSubscriptions()
298: {
299: $class = new \ReflectionClass($this);
300: $subscriptionsClassName = $class->getNamespaceName() . "\\Subscriptions";
301: if (class_exists($subscriptionsClassName)) {
302: $subscriptions = new $subscriptionsClassName($this);
303: $subscriptions->init();
304: }
305: }
306:
307: protected function initEntries()
308: {
309: $class = new \ReflectionClass($this);
310: $entitiesClassName = $class->getNamespaceName() . "\\Entries";
311: if (class_exists($entitiesClassName)) {
312: $entities = new $entitiesClassName($this);
313: $entities->init();
314: }
315: }
316:
317: /**
318: *
319: * @return boolean
320: */
321: public function initialize()
322: {
323: $mResult = true;
324: if (!$this->isInitialized()) {
325: $this->bInitialized = true;
326: $this->loadModuleSettings();
327: $this->init();
328: $this->initSubscriptions();
329: $this->initEntries();
330: }
331:
332: return $mResult;
333: }
334:
335: /**
336: *
337: * @return string
338: */
339: final public static function getNamespace()
340: {
341: return \substr_replace(static::class, '', -7);
342: }
343:
344: /**
345: *
346: * @return \Aurora\System\Module\Settings
347: */
348: public function getModuleSettings()
349: {
350: return $this->oModuleSettings;
351: }
352:
353: /**
354: *
355: * @return \Aurora\System\Module\Settings
356: */
357: public function loadModuleSettings()
358: {
359: if (!isset($this->oModuleSettings)) {
360: $this->oModuleSettings = & $this->GetModuleManager()->getModuleSettings(self::GetName());
361: $this->oModuleSettings->Load();
362: }
363: return $this->oModuleSettings;
364: }
365:
366: /**
367: * Saves module settings to config.json file.
368: *
369: * returns bool
370: */
371: public function saveModuleConfig()
372: {
373: $bResult = false;
374:
375: if (isset($this->oModuleSettings)) {
376: $bResult = $this->oModuleSettings->Save();
377: }
378:
379: return $bResult;
380: }
381:
382: /**
383: *
384: * @param string $sName
385: * @param mixed $mDefaultValue
386: * @return mixed
387: */
388: public function getConfig($sName, $mDefaultValue = null)
389: {
390: $mResult = $mDefaultValue;
391: if (isset($this->oModuleSettings)) {
392: $mResult = $this->oModuleSettings->GetValue($sName, $mDefaultValue);
393: }
394:
395: return $mResult;
396: }
397:
398: /**
399: * Sets new value of module setting.
400: *
401: * @param string $sName Name of module setting.
402: * @param string $sValue New value of module setting.
403: *
404: * @return boolean
405: */
406: public function setConfig($sName, $sValue = null)
407: {
408: $bResult = false;
409:
410: if (isset($this->oModuleSettings)) {
411: $bResult = $this->oModuleSettings->SetValue($sName, $sValue);
412: }
413:
414: return $bResult;
415: }
416:
417: /**
418: *
419: * @param array $aMethods
420: *
421: */
422: public function denyMethodsCallByWebApi($aMethods)
423: {
424: foreach ($aMethods as $sMethodName) {
425: $this->denyMethodCallByWebApi($sMethodName);
426: }
427: }
428:
429: /**
430: *
431: * @param string $sMethodName
432: *
433: */
434: public function denyMethodCallByWebApi($sMethodName)
435: {
436: if (!in_array($sMethodName, $this->aDeniedMethodsByWebApi)) {
437: $this->aDeniedMethodsByWebApi[] = $sMethodName;
438: }
439: }
440:
441: /**
442: *
443: * @param string $sMethodName
444: * @return boolean
445: */
446: protected function isDeniedMethodByWebApi($sMethodName)
447: {
448: return in_array($sMethodName, array_values($this->aDeniedMethodsByWebApi));
449: }
450:
451: /**
452: *
453: * @param string $sMethod
454: * @return boolean
455: */
456: protected function isEventCallback($sMethod)
457: {
458: return in_array($sMethod, $this->getEventsCallbacks());
459: }
460:
461: /**
462: *
463: * @return array
464: */
465: protected function getEventsCallbacks()
466: {
467: $aEventsValues = array();
468: $aEvents = $this->GetModuleManager()->getEvents();
469: foreach (array_values($aEvents) as $aEvent) {
470: foreach ($aEvent as $aEv) {
471: if ($aEv[0]::GetName() === self::GetName()) {
472: $aEventsValues[] = $aEv[1];
473: }
474: }
475: }
476:
477: return $aEventsValues;
478: }
479:
480: /**
481: *
482: * @param string $sEvent
483: * @param callable $fCallback
484: * @param int $iPriority
485: */
486: public function subscribeEvent($sEvent, $fCallback, $iPriority = 100)
487: {
488: $this->GetModuleManager()->subscribeEvent($sEvent, $fCallback, $iPriority);
489: }
490:
491: /**
492: *
493: * @param string $sEvent
494: * @param array $aArguments
495: */
496: public function broadcastEvent($sEvent, &$aArguments = [], &$mResult = null)
497: {
498: if (!in_array($sEvent, $this->aSkipedEvents)) {
499: return $this->GetModuleManager()->broadcastEvent(
500: self::GetName(),
501: $sEvent,
502: $aArguments,
503: $mResult
504: );
505: } else {
506: $this->removeEventFromSkiped($sEvent);
507: }
508: }
509:
510: /**
511: *
512: * @param string $sEvent
513: */
514: public function skipEvent($sEvent)
515: {
516: if (!in_array($sEvent, $this->aSkipedEvents)) {
517: $this->aSkipedEvents[] = $sEvent;
518: }
519: }
520:
521: /**
522: *
523: * @param string $sEvent
524: */
525: public function removeEventFromSkiped($sEvent)
526: {
527: $this->aSkipedEvents = array_diff(
528: $this->aSkipedEvents,
529: array($sEvent)
530: );
531: }
532:
533: /**
534: * @param string $sParsedTemplateID
535: * @param string $sParsedPlace
536: * @param string $sTemplateFileName
537: * @param string $sModuleName
538: */
539: public function includeTemplate($sParsedTemplateID, $sParsedPlace, $sTemplateFileName, $sModuleName = '')
540: {
541: if (0 < strlen($sParsedTemplateID) && 0 < strlen($sParsedPlace) && file_exists($this->GetPath() . '/' . $sTemplateFileName)) {
542: $this->GetModuleManager()->includeTemplate(
543: $sParsedTemplateID,
544: $sParsedPlace,
545: $this->GetPath() . '/' . $sTemplateFileName,
546: $sModuleName
547: );
548: }
549: }
550:
551: /**
552: *
553: * @param string $sType
554: * @param array $aMap
555: */
556: public function extendObject($sType, $aMap)
557: {
558: $this->GetModuleManager()->extendObject(self::GetName(), $sType, $aMap);
559: }
560:
561: /**
562: *
563: * @param string $sType
564: * @return array
565: */
566: public function getExtendedObject($sType)
567: {
568: return $this->GetModuleManager()->getExtendedObject($sType);
569: }
570:
571: /**
572: *
573: * @param string $sType
574: * @return boolean
575: */
576: public function issetObject($sType)
577: {
578: return $this->GetModuleManager()->issetObject($sType);
579: }
580:
581: /**
582: * @param string $sPath
583: */
584: final public function SetPath($sPath)
585: {
586: $this->sPath = $sPath;
587: }
588:
589: /**
590: * @return string
591: */
592: final public function GetHash()
593: {
594: return '';
595: }
596:
597: /**
598: * @return string
599: */
600: final public static function GetName()
601: {
602: return substr(strrchr(static::getNamespace(), "\\"), 1);
603: }
604:
605: public function getModuleName()
606: {
607: return static::GetName();
608: }
609:
610: /**
611: * @return string
612: */
613: final public function GetPath()
614: {
615: return $this->sPath;
616: }
617:
618: /**
619: * @return string
620: */
621: public function GetVersion()
622: {
623: return $this->sVersion;
624: }
625:
626: /**
627: * @return string
628: */
629: final public function GetFullName()
630: {
631: return self::GetName() . '-' . $this->sVersion;
632: }
633:
634: /**
635: *
636: * @param string $sName
637: * @param callable $mCallbak
638: */
639: final public function AddEntry($sName, $mCallbak)
640: {
641: \Aurora\System\Router::getInstance()->register(
642: self::GetName(),
643: $sName,
644: [$this, $mCallbak]
645: );
646: }
647:
648: /**
649: *
650: * @param array $aEntries
651: */
652: final public function AddEntries($aEntries)
653: {
654: foreach ($aEntries as $sName => $mCallbak) {
655: $this->AddEntry($sName, $mCallbak);
656: }
657: }
658:
659: /**
660: *
661: * @param string $sName
662: * @return boolean
663: */
664: final public function HasEntry($sName)
665: {
666: return \Aurora\System\Router::getInstance()->hasRoute($sName);
667: }
668:
669: /**
670: *
671: * @param string $sName
672: */
673: final public function RemoveEntry($sName)
674: {
675: return \Aurora\System\Router::getInstance()->removeRoute($sName);
676: }
677:
678: /**
679: *
680: * @param array $aEntries
681: */
682: final public function RemoveEntries($aEntries)
683: {
684: foreach ($aEntries as $sName) {
685: $this->RemoveEntry($sName);
686: }
687: }
688:
689: /**
690: *
691: * @param callable $mCallbak
692: * @return boolean
693: */
694: protected function isEntryCallback($mCallbak)
695: {
696: return \Aurora\System\Router::getInstance()->hasCallback($mCallbak);
697: }
698:
699: /**
700: *
701: * @param string $sName
702: * @return mixed
703: */
704: final public function GetEntryCallback($sName)
705: {
706: return \Aurora\System\Router::getInstance()->getCallback($sName);
707: }
708:
709: /**
710: * @param string $sMethod
711: * @param mixed $mResult = false
712: *
713: * @return array
714: */
715: final public function DefaultResponse($sMethod, $mResult = false)
716: {
717: return \Aurora\System\Managers\Response::DefaultResponse(self::GetName(), $sMethod, $mResult);
718: }
719:
720: /**
721: * @param string $sMethod
722: *
723: * @return array
724: */
725: final public function TrueResponse($sMethod)
726: {
727: return $this->DefaultResponse($sMethod, true);
728: }
729:
730: /**
731: * @param string $sMethod
732: * @param int $iErrorCode
733: * @param string $sErrorMessage
734: * @param array $aAdditionalParams = null
735: *
736: * @return array
737: */
738: final public function FalseResponse($sMethod, $iErrorCode = null, $sErrorMessage = null, $aAdditionalParams = null, $sModule = null)
739: {
740: return \Aurora\System\Managers\Response::FalseResponse($sMethod, $iErrorCode, $sErrorMessage, $aAdditionalParams, $sModule);
741: }
742:
743: /**
744: * @param string $sActionName
745: * @param \Exception $oException
746: * @param array $aAdditionalParams = null
747: *
748: * @return array
749: */
750: final public function ExceptionResponse($sActionName, $oException, $aAdditionalParams = null)
751: {
752: return \Aurora\System\Managers\Response::ExceptionResponse($sActionName, $oException, $aAdditionalParams);
753: }
754:
755: /**
756: *
757: * @param string $sMethodName
758: * @param array $aArguments
759: * @param boolean $bWebApi
760: * @return array
761: */
762: protected function prepareMethodArguments($sMethodName, &$aArguments, $bWebApi)
763: {
764: $aMethodArgs = array();
765: $oReflector = new \ReflectionMethod($this, $sMethodName);
766: $aReflectionParameters = $oReflector->getParameters();
767: if ($bWebApi) {
768: foreach ($aReflectionParameters as $oParam) {
769: $sParamName = $oParam->getName();
770: $iParamPosition = $oParam->getPosition();
771: $bIsArgumentGiven = array_key_exists($sParamName, $aArguments);
772: if (!$bIsArgumentGiven && !$oParam->isDefaultValueAvailable()) {
773: $aMethodArgs[$iParamPosition] = null;
774: } else {
775: $aMethodArgs[$iParamPosition] = $bIsArgumentGiven ?
776: $aArguments[$sParamName] : $oParam->getDefaultValue();
777: }
778: }
779: } else {
780: $aTempArguments = array();
781: $aMethodArgs = $aArguments;
782: foreach ($aReflectionParameters as $oParam) {
783: $sParamName = $oParam->getName();
784: $iParamPosition = $oParam->getPosition();
785: $mArgumentValue = null;
786: if (isset($aArguments[$iParamPosition])) {
787: $mArgumentValue = $aArguments[$iParamPosition];
788: } elseif ($oParam->isDefaultValueAvailable()) {
789: $mArgumentValue = $oParam->getDefaultValue();
790: }
791: $aTempArguments[$sParamName] = $mArgumentValue;
792: }
793: $aArguments = $aTempArguments;
794: }
795:
796: return $aMethodArgs;
797: }
798:
799: /**
800: *
801: * @param string $sMethod
802: * @return boolean
803: */
804: protected function isCallbackMethod($sMethod)
805: {
806: return ($this->isEntryCallback($sMethod) || $this->isEventCallback($sMethod));
807: }
808:
809: protected function canCallMethod($sMethod, $bWebApi)
810: {
811: return !($bWebApi && ($this->isCallbackMethod($sMethod) || $this->isDeniedMethodByWebApi($sMethod))) && $this->isAllowedModule();
812: }
813:
814: /**
815: *
816: * @param string $sMethod
817: * @param array $aArguments
818: * @param boolean $bWebApi
819: * @return mixed
820: */
821: final public function CallMethod($sMethod, $aArguments = array(), $bWebApi = false)
822: {
823: $mResult = false;
824: try {
825: if (!method_exists($this, $sMethod)) {
826: throw new \Aurora\System\Exceptions\ApiException(
827: \Aurora\System\Notifications::MethodNotFound
828: );
829: } elseif (!$this->canCallMethod($sMethod, $bWebApi)) {
830: throw new \Aurora\System\Exceptions\ApiException(
831: \Aurora\System\Notifications::MethodAccessDenied
832: );
833: } else {
834: if ($bWebApi && !isset($aArguments['UserId'])) {
835: $aArguments['UserId'] = \Aurora\System\Api::getAuthenticatedUserId();
836: }
837:
838: // prepare arguments for before event
839: $aMethodArgs = $this->prepareMethodArguments($sMethod, $aArguments, $bWebApi);
840:
841: $bEventResult = $this->broadcastEvent(
842: $sMethod . AbstractModule::$Delimiter . 'before',
843: $aArguments,
844: $mResult
845: );
846:
847: // prepare arguments for main action after event
848: $aMethodArgs = $this->prepareMethodArguments($sMethod, $aArguments, true);
849:
850: if (!$bEventResult) {
851: try {
852: $oReflector = new \ReflectionMethod($this, $sMethod);
853: if (!$oReflector->isPublic()) {
854: throw new \Aurora\System\Exceptions\ApiException(
855: \Aurora\System\Notifications::MethodNotFound
856: );
857: }
858: $mMethodResult = call_user_func_array(
859: array($this, $sMethod),
860: $aMethodArgs
861: );
862: if (is_array($mMethodResult) && is_array($mResult)) {
863: $mResult = array_merge($mMethodResult, $mResult);
864: } elseif ($mMethodResult !== null) {
865: $mResult = $mMethodResult;
866: }
867: } catch (\Exception $oException) {
868: if ($oException instanceof \Illuminate\Database\QueryException) {
869: // throw new \Aurora\System\Exceptions\ApiException(
870: // $oException->getCode(),
871: // $oException,
872: // 'Database is not configured'
873: // );
874: Api::LogException($oException);
875: $mResult = false;
876: } elseif (!($oException instanceof \Aurora\System\Exceptions\ApiException)) {
877: throw new \Aurora\System\Exceptions\ApiException(
878: $oException->getCode(),
879: $oException,
880: $oException->getMessage()
881: );
882: } else {
883: throw $oException;
884: }
885:
886: $this->GetModuleManager()->AddResult(
887: self::GetName(),
888: $sMethod,
889: $aArguments,
890: $mResult,
891: $oException->getCode()
892: );
893: }
894: }
895:
896: $this->broadcastEvent(
897: $sMethod . AbstractModule::$Delimiter . 'after',
898: $aArguments,
899: $mResult
900: );
901:
902: $this->GetModuleManager()->AddResult(
903: self::GetName(),
904: $sMethod,
905: $aArguments,
906: $mResult
907: );
908: }
909: } catch (\Exception $oException) {
910: throw new \Aurora\System\Exceptions\ApiException(
911: $oException->getCode(),
912: $oException,
913: $oException->getMessage(),
914: [],
915: $this
916: );
917: }
918:
919: return $mResult;
920: }
921:
922: /**
923: * Obtains list of module settings for authenticated user.
924: *
925: * @return array|null
926: */
927: public function GetSettings()
928: {
929: return null;
930: }
931:
932: protected function getLangsData($sLang)
933: {
934: $mResult = false;
935: $sLangFile = $this->GetPath() . '/i18n/' . $sLang . '.ini';
936: $sLangFile = @\file_exists($sLangFile) ? $sLangFile : '';
937:
938: if (0 < \strlen($sLangFile)) {
939: $aLang = \Aurora\System\Api::convertIniToLang($sLangFile);
940: if (\is_array($aLang)) {
941: $mResult = $aLang;
942: }
943: }
944: return $mResult;
945: }
946:
947: /**
948: * @param string $sData
949: * @param array $aParams = null
950: * @param int $iPluralCount = null
951: * @param string $sUUID = null
952: *
953: * @return string
954: */
955: public function i18N($sData, $aParams = null, $iPluralCount = null, $sUUID = null)
956: {
957: static $sLanguage = null;
958: if (is_null($sLanguage)) {
959: if ($sUUID) {
960: $oCoreDecorator = \Aurora\Modules\Core\Module::Decorator();
961: $oUser = $oCoreDecorator ? $oCoreDecorator->GetUserByUUID($sUUID) : null;
962: if ($oUser instanceof \Aurora\Modules\Core\Models\User) {
963: $sLanguage = $oUser->Language;
964: }
965: }
966: if (empty($sLanguage)) {
967: $sLanguage = \Aurora\System\Api::GetLanguage();
968: }
969: }
970:
971: if (is_null($this->aLang)) {
972: if (isset(\Aurora\System\Api::$aClientI18N[self::GetName()][$sLanguage])) {
973: $aLang = \Aurora\System\Api::$aClientI18N[self::GetName()][$sLanguage];
974: } else {
975: \Aurora\System\Api::$aClientI18N[self::GetName()][$sLanguage] = false;
976:
977: $this->aLang = $this->getLangsData($sLanguage);
978: if (!$this->aLang) {
979: $this->aLang = $this->getLangsData('English');
980: }
981:
982: if (\is_array($this->aLang)) {
983: \Aurora\System\Api::$aClientI18N[self::GetName()][$sLanguage] = $this->aLang;
984: }
985: }
986: if (!isset($this->aLang[$sData])) {
987: $this->aLang = $this->getLangsData('English');
988: }
989: }
990:
991: return isset($iPluralCount) ? \Aurora\System\Api::processTranslateParams($this->aLang, $sData, $aParams, \Aurora\System\Api::getPlural($sLanguage, $iPluralCount)) :
992: \Aurora\System\Api::processTranslateParams($this->aLang, $sData, $aParams);
993: }
994:
995: /**
996: *
997: * @param \Aurora\System\Classes\Model $oEntity
998: */
999: protected function updateEnabledForEntity(&$oEntity, $bEnabled = true)
1000: {
1001: if ($bEnabled) {
1002: $oEntity->enableModule(self::GetName());
1003: } else {
1004: $oEntity->disableModule(self::GetName());
1005: }
1006: }
1007:
1008: /**
1009: *
1010: * @param \Aurora\System\Classes\Model $oEntity
1011: * @return bool
1012: */
1013: protected function isEnabledForEntity(&$oEntity)
1014: {
1015: return !$oEntity->isModuleDisabled(self::GetName());
1016: }
1017:
1018: /**
1019: *
1020: * @return array
1021: */
1022: public function GetErrors()
1023: {
1024: return is_array($this->aErrors) ? (object) $this->aErrors : [];
1025: }
1026:
1027: /**
1028: * @param int $iErrorCode
1029: * @return string
1030: */
1031: public function GetErrorMessageByCode($iErrorCode)
1032: {
1033: return is_array($this->aErrors) && isset($this->aErrors[(int) $iErrorCode]) ? $this->aErrors[(int) $iErrorCode] : '';
1034: }
1035:
1036: /**
1037: *
1038: * @return array
1039: */
1040: public function GetAdditionalEntityFieldsToEdit()
1041: {
1042: return is_array($this->aAdditionalEntityFieldsToEdit) ? $this->aAdditionalEntityFieldsToEdit : [];
1043: }
1044: }
1045: