diff --git a/common/oatbox/user/UserLanguageService.php b/common/oatbox/user/UserLanguageService.php
index 72d67e22a..aaf7d225d 100644
--- a/common/oatbox/user/UserLanguageService.php
+++ b/common/oatbox/user/UserLanguageService.php
@@ -29,6 +29,9 @@ class UserLanguageService extends ConfigurableService implements UserLanguageSer
public const OPTION_LOCK_DATA_LANGUAGE = 'lock_data_language';
public const OPTION_AUTHORING_LANGUAGE = 'authoring_language';
+ /** @var ?string */
+ private $customInterfaceLanguage;
+
/**
* {@inheritDoc}
* @see \oat\oatbox\user\UserLanguageServiceInterface::getDefaultLanguage()
@@ -56,6 +59,10 @@ public function getDataLanguage(User $user)
*/
public function getInterfaceLanguage(User $user)
{
+ if (!empty($this->customInterfaceLanguage)) {
+ return $this->customInterfaceLanguage;
+ }
+
$lang = $user->getPropertyValues(GenerisRdf::PROPERTY_USER_UILG);
return empty($lang) ? $this->getDefaultLanguage() : (string)current($lang);
}
@@ -72,4 +79,12 @@ public function getAuthoringLanguage(): string
{
return $this->getOption(self::OPTION_AUTHORING_LANGUAGE, $this->getDefaultLanguage());
}
+
+ /**
+ * @inheritdoc
+ */
+ public function setCustomInterfaceLanguage(?string $customInterfaceLanguage): void
+ {
+ $this->customInterfaceLanguage = $customInterfaceLanguage;
+ }
}
diff --git a/common/oatbox/user/UserLanguageServiceInterface.php b/common/oatbox/user/UserLanguageServiceInterface.php
index 8e3949eab..81c948dd0 100644
--- a/common/oatbox/user/UserLanguageServiceInterface.php
+++ b/common/oatbox/user/UserLanguageServiceInterface.php
@@ -52,4 +52,12 @@ public function getInterfaceLanguage(User $user);
* @return boolean
*/
public function isDataLanguageEnabled();
+
+ /**
+ * When a custom interface language is set, it overrides the interface language retrieved in the getInterfaceLanguage
+ * method.
+ *
+ * @param ?string $customInterfaceLanguage
+ */
+ public function setCustomInterfaceLanguage(?string $customInterfaceLanguage): void;
}
diff --git a/common/session/class.BasicSession.php b/common/session/class.BasicSession.php
index 4396b3af4..f1df3a6eb 100644
--- a/common/session/class.BasicSession.php
+++ b/common/session/class.BasicSession.php
@@ -15,7 +15,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Copyright (c) 2017 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
+ * Copyright (c) 2017-2021 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
*
*/
@@ -142,7 +142,20 @@ public function getDataLanguage()
*/
public function getInterfaceLanguage()
{
- return $this->getServiceLocator()->get(UserLanguageServiceInterface::class)->getInterfaceLanguage($this->getUser());
+ /** @var PHPSession $session */
+ $session = PHPSession::singleton();
+
+ /** @var UserLanguageServiceInterface $userLanguageService */
+ $userLanguageService = $this->getServiceLocator()->get(UserLanguageServiceInterface::class);
+
+ if ($session->hasAttribute('overrideInterfaceLanguage')) {
+ $userLanguageService->setCustomInterfaceLanguage($session->getAttribute('overrideInterfaceLanguage'));
+ } else {
+ // Just to be sure the custom interface language is removed when the session attribute is gone
+ $userLanguageService->setCustomInterfaceLanguage(null);
+ }
+
+ return $userLanguageService->getInterfaceLanguage($this->getUser());
}
/**
diff --git a/core/GenerisRdf.php b/core/GenerisRdf.php
index b58f16e4f..422412e48 100644
--- a/core/GenerisRdf.php
+++ b/core/GenerisRdf.php
@@ -60,6 +60,7 @@ interface GenerisRdf
public const PROPERTY_MASK_SUBJECT = 'http://www.tao.lu/Ontologies/generis.rdf#MaskSubject';
public const PROPERTY_MASK_PREDICATE = 'http://www.tao.lu/Ontologies/generis.rdf#MaskPredicate';
public const PROPERTY_MASK_OBJECT = 'http://www.tao.lu/Ontologies/generis.rdf#MaskObject';
+ public const PROPERTY_DEPENDS_ON_PROPERTY = 'http://www.tao.lu/Ontologies/generis.rdf#DependsOnProperty';
//@deprecated use UserRdf::CLASS_URI
public const CLASS_GENERIS_USER = 'http://www.tao.lu/Ontologies/generis.rdf#User';
//@deprecated use UserRdf::PROPERTY_LOGIN
diff --git a/core/kernel/classes/class.Property.php b/core/kernel/classes/class.Property.php
index 71638898d..f6c5e6c16 100644
--- a/core/kernel/classes/class.Property.php
+++ b/core/kernel/classes/class.Property.php
@@ -21,10 +21,12 @@
*
*/
-use oat\generis\model\data\ModelManager;
+declare(strict_types=1);
+
+use oat\generis\model\WidgetRdf;
use oat\generis\model\GenerisRdf;
use oat\generis\model\OntologyRdfs;
-use oat\generis\model\WidgetRdf;
+use oat\generis\model\resource\DependsOnPropertyCollection;
/**
* uriProperty must be a valid property otherwis return false, add this as a
@@ -88,6 +90,9 @@ class core_kernel_classes_Property extends core_kernel_classes_Resource
*/
public $multiple = false;
+ /** @var DependsOnPropertyCollection */
+ private $dependsOnPropertyCollection;
+
// --- OPERATIONS ---
/**
* @return core_kernel_persistence_PropertyInterface
@@ -96,7 +101,7 @@ private function getImplementation()
{
return $this->getModel()->getRdfsInterface()->getPropertyImplementation();
}
-
+
/**
* constructor
@@ -109,10 +114,11 @@ private function getImplementation()
*/
public function __construct($uri, $debug = '')
{
-
parent::__construct($uri, $debug);
+
$this->lgDependent = null;
$this->multiple = null;
+ $this->dependsOnPropertyCollection = new DependsOnPropertyCollection();
}
/**
@@ -145,7 +151,7 @@ public function getDomain()
}
}
$returnValue = $this->domain;
-
+
return $returnValue;
}
@@ -161,7 +167,7 @@ public function getDomain()
public function setDomain(core_kernel_classes_Class $class)
{
$returnValue = (bool) false;
-
+
if (!is_null($class)) {
foreach ($this->getDomain()->getIterator() as $domainClass) {
if ($class->equals($domainClass)) {
@@ -190,7 +196,7 @@ public function setDomain(core_kernel_classes_Class $class)
public function getRange()
{
$returnValue = null;
-
+
if (is_null($this->range)) {
$rangeProperty = $this->getProperty(OntologyRdfs::RDFS_RANGE);
$rangeValues = $this->getPropertyValues($rangeProperty);
@@ -222,6 +228,37 @@ public function setRange(core_kernel_classes_Class $class)
return (bool) $returnValue;
}
+ /**
+ * @TODO Improve getter
+ */
+ public function getDependsOnPropertyCollection(): DependsOnPropertyCollection
+ {
+ $dependsOnProperty = $this->getProperty(GenerisRdf::PROPERTY_DEPENDS_ON_PROPERTY);
+ $dependsOnPropertyValues = $this->getPropertyValues($dependsOnProperty);
+
+ foreach ($dependsOnPropertyValues as $dependsOnPropertyValue) {
+ if ($dependsOnPropertyValue !== GenerisRdf::PROPERTY_DEPENDS_ON_PROPERTY) {
+ $this->dependsOnPropertyCollection->append(
+ $this->getProperty($dependsOnPropertyValue)
+ );
+ }
+ }
+
+ return $this->dependsOnPropertyCollection;
+ }
+
+ /**
+ * @TODO Improve setter
+ */
+ public function setDependsOnPropertyCollection(DependsOnPropertyCollection $dependsOnPropertyCollection): void
+ {
+ foreach ($dependsOnPropertyCollection as $dependsOnProperty) {
+ $this->getImplementation()->setDependsOnProperty($this, $dependsOnProperty);
+ }
+
+ $this->dependsOnPropertyCollection = $dependsOnPropertyCollection;
+ }
+
/**
* Get the Property object corresponding to the widget of this Property.
*
@@ -235,7 +272,7 @@ public function getWidget()
if ($this->widget === false) {
$this->widget = $this->getOnePropertyValue($this->getProperty(WidgetRdf::PROPERTY_WIDGET));
}
-
+
return $this->widget;
}
@@ -282,7 +319,7 @@ public function isMultiple()
if (is_null($this->multiple)) {
$multipleProperty = $this->getProperty(GenerisRdf::PROPERTY_MULTIPLE);
$multiple = $this->getOnePropertyValue($multipleProperty);
-
+
if (is_null($multiple)) {
$returnValue = false;
} else {
@@ -290,7 +327,7 @@ public function isMultiple()
}
$this->multiple = $returnValue;
}
-
+
$returnValue = $this->multiple;
return (bool) $returnValue;
}
@@ -306,7 +343,7 @@ public function isMultiple()
*/
public function setMultiple($isMultiple)
{
-
+
$this->getImplementation()->setMultiple($this, $isMultiple);
$this->multiple = $isMultiple;
}
diff --git a/core/kernel/persistence/interface.PropertyInterface.php b/core/kernel/persistence/interface.PropertyInterface.php
index a5f3261c1..4c5e8d079 100644
--- a/core/kernel/persistence/interface.PropertyInterface.php
+++ b/core/kernel/persistence/interface.PropertyInterface.php
@@ -30,8 +30,8 @@
interface core_kernel_persistence_PropertyInterface
{
-
-
+
+
/**
* Short description of method isLgDependent
*
@@ -41,7 +41,7 @@ interface core_kernel_persistence_PropertyInterface
* @return boolean
*/
public function isLgDependent(core_kernel_classes_Resource $resource);
-
+
/**
* Short description of method isMultiple
*
@@ -51,7 +51,7 @@ public function isLgDependent(core_kernel_classes_Resource $resource);
* @return boolean
*/
public function isMultiple(core_kernel_classes_Resource $resource);
-
+
/**
* Short description of method getRange
*
@@ -61,7 +61,7 @@ public function isMultiple(core_kernel_classes_Resource $resource);
* @return core_kernel_classes_Class
*/
public function getRange(core_kernel_classes_Resource $resource);
-
+
/**
* Short description of method delete
*
@@ -72,7 +72,7 @@ public function getRange(core_kernel_classes_Resource $resource);
* @return boolean
*/
public function delete(core_kernel_classes_Resource $resource, $deleteReference = false);
-
+
/**
* Short description of method setRange
*
@@ -83,7 +83,12 @@ public function delete(core_kernel_classes_Resource $resource, $deleteReference
* @return core_kernel_classes_Class
*/
public function setRange(core_kernel_classes_Resource $resource, core_kernel_classes_Class $class);
-
+
+ public function setDependsOnProperty(
+ core_kernel_classes_Resource $resource,
+ core_kernel_classes_Property $property
+ ): void;
+
/**
* Short description of method setMultiple
*
@@ -94,7 +99,7 @@ public function setRange(core_kernel_classes_Resource $resource, core_kernel_cla
* @return void
*/
public function setMultiple(core_kernel_classes_Resource $resource, $isMultiple);
-
+
/**
* Short description of method setLgDependent
*
diff --git a/core/kernel/persistence/smoothsql/class.Property.php b/core/kernel/persistence/smoothsql/class.Property.php
index e4b67f4e4..34f80e54c 100644
--- a/core/kernel/persistence/smoothsql/class.Property.php
+++ b/core/kernel/persistence/smoothsql/class.Property.php
@@ -20,10 +20,12 @@
* 2009-2012 (update and modification) Public Research Centre Henri Tudor (under the project TAO-SUSTAIN & TAO-DEV);
* 2017 (update and modification) Open Assessment Technologies SA (under the project TAO-PRODUCT);
*/
-
+
+declare(strict_types=1);
+
use oat\generis\model\GenerisRdf;
use oat\generis\model\OntologyRdfs;
-
+
/**
* Short description of class core_kernel_persistence_smoothsql_Property
*
@@ -139,6 +141,18 @@ public function setRange(core_kernel_classes_Resource $resource, core_kernel_cla
return $returnValue;
}
+ public function setDependsOnProperty(
+ core_kernel_classes_Resource $resource,
+ core_kernel_classes_Property $property
+ ): void {
+ $dependsOnProperty = new core_kernel_classes_Property(
+ GenerisRdf::PROPERTY_DEPENDS_ON_PROPERTY,
+ __METHOD__
+ );
+
+ $this->setPropertyValue($resource, $dependsOnProperty, $property->getUri());
+ }
+
/**
* Short description of method setMultiple
*
@@ -150,7 +164,7 @@ public function setRange(core_kernel_classes_Resource $resource, core_kernel_cla
*/
public function setMultiple(core_kernel_classes_Resource $resource, $isMultiple)
{
-
+
$multipleProperty = new core_kernel_classes_Property(GenerisRdf::PROPERTY_MULTIPLE);
$value = ((bool)$isMultiple) ? GenerisRdf::GENERIS_TRUE : GenerisRdf::GENERIS_FALSE ;
$this->removePropertyValues($resource, $multipleProperty);
@@ -168,7 +182,7 @@ public function setMultiple(core_kernel_classes_Resource $resource, $isMultiple)
*/
public function setLgDependent(core_kernel_classes_Resource $resource, $isLgDependent)
{
-
+
$lgDependentProperty = new core_kernel_classes_Property(GenerisRdf::PROPERTY_IS_LG_DEPENDENT, __METHOD__);
$value = ((bool)$isLgDependent) ? GenerisRdf::GENERIS_TRUE : GenerisRdf::GENERIS_FALSE ;
$this->removePropertyValues($resource, $lgDependentProperty);
diff --git a/core/ontology/generis.rdf b/core/ontology/generis.rdf
index 492a6c6f3..1ef62de21 100644
--- a/core/ontology/generis.rdf
+++ b/core/ontology/generis.rdf
@@ -366,4 +366,11 @@
+
+
+
+
+
+
+
diff --git a/core/resource/DependsOnPropertyCollection.php b/core/resource/DependsOnPropertyCollection.php
new file mode 100644
index 000000000..66a9ca5e0
--- /dev/null
+++ b/core/resource/DependsOnPropertyCollection.php
@@ -0,0 +1,33 @@
+addReport(Report::createSuccess('Models were successfully synchronized'));
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->throwIrreversibleMigrationException();
+ }
+}
diff --git a/test/unit/common/oatbox/user/UserLanguageServiceTest.php b/test/unit/common/oatbox/user/UserLanguageServiceTest.php
index 70446254b..3d3b1f9e1 100644
--- a/test/unit/common/oatbox/user/UserLanguageServiceTest.php
+++ b/test/unit/common/oatbox/user/UserLanguageServiceTest.php
@@ -22,8 +22,12 @@
namespace oat\generis\test\unit\common\oatbox\user;
+use oat\generis\model\GenerisRdf;
use oat\generis\test\TestCase;
+use oat\oatbox\user\User;
use oat\oatbox\user\UserLanguageService;
+use Prophecy\Argument;
+use Prophecy\Prophecy\ObjectProphecy;
class UserLanguageServiceTest extends TestCase
{
@@ -50,4 +54,40 @@ public function testGetDefaultLanguageForAuthoringLanguage(): void
$this->assertSame($this->subject->getDefaultLanguage(), $this->subject->getAuthoringLanguage());
}
+
+ public function testGetInterfaceLanguageReturnsDefaultLanguageWhenUserDoesNotHaveItSet(): void
+ {
+ $user = $this->createUser();
+
+ $this->assertSame($this->subject->getDefaultLanguage(), $this->subject->getInterfaceLanguage($user));
+ }
+
+ public function testGetInterfaceLanguageReturnsLanguageFromUser(): void
+ {
+ $user = $this->createUser('en-US');
+
+ $this->assertSame('en-US', $this->subject->getInterfaceLanguage($user));
+ }
+
+ public function testGetInterfaceLanguageReturnsCustomInterfaceLanguage(): void
+ {
+ $this->subject->setCustomInterfaceLanguage('es-ES');
+
+ $user = $this->createUser();
+
+ $this->assertSame('es-ES', $this->subject->getInterfaceLanguage($user));
+ }
+
+ private function createUser(?string $withLanguage = null): User
+ {
+ /** @var User|ObjectProphecy $user */
+ $user = $this->prophesize(User::class);
+
+ if ($withLanguage !== null) {
+ $user->getPropertyValues(Argument::is(GenerisRdf::PROPERTY_USER_UILG))
+ ->willReturn([$withLanguage]);
+ }
+
+ return $user->reveal();
+ }
}