From e71c7786a2ed4e48aa11711ab26c69954620514b Mon Sep 17 00:00:00 2001 From: Samuel Weirich <4281791+SamuelWei@users.noreply.github.com> Date: Wed, 11 Jun 2025 14:55:36 +0200 Subject: [PATCH 1/3] Add support for clientSettingsOverride --- composer.json | 3 +- src/BigBlueButton.php | 2 +- src/Parameters/CreateMeetingParameters.php | 32 +++++++++++++++---- src/Util/SimpleXMLElementExtended.php | 24 ++++++++++++++ tests/fixtures/client_settings.xml | 6 ++++ .../CreateMeetingParametersTest.php | 16 ++++++++-- 6 files changed, 71 insertions(+), 12 deletions(-) create mode 100644 src/Util/SimpleXMLElementExtended.php create mode 100644 tests/fixtures/client_settings.xml diff --git a/composer.json b/composer.json index ceb080c1..a81e1f04 100644 --- a/composer.json +++ b/composer.json @@ -62,7 +62,8 @@ "ext-curl": "*", "ext-simplexml": "*", "ext-mbstring": "*", - "ext-json": "*" + "ext-json": "*", + "ext-dom": "*" }, "suggest": { "psr/http-client-implementation": "To use the PsrHttpClientTransport.", diff --git a/src/BigBlueButton.php b/src/BigBlueButton.php index 5564e460..8e4431d0 100644 --- a/src/BigBlueButton.php +++ b/src/BigBlueButton.php @@ -222,7 +222,7 @@ public function getCreateMeetingUrl(CreateMeetingParameters $createMeetingParams */ public function createMeeting(CreateMeetingParameters $createMeetingParams): CreateMeetingResponse { - $xml = $this->processXmlResponse($this->getCreateMeetingUrl($createMeetingParams), $createMeetingParams->getPresentationsAsXML()); + $xml = $this->processXmlResponse($this->getCreateMeetingUrl($createMeetingParams), $createMeetingParams->getModules()); return new CreateMeetingResponse($xml); } diff --git a/src/Parameters/CreateMeetingParameters.php b/src/Parameters/CreateMeetingParameters.php index e3480d44..131ad623 100644 --- a/src/Parameters/CreateMeetingParameters.php +++ b/src/Parameters/CreateMeetingParameters.php @@ -25,6 +25,7 @@ use BigBlueButton\Enum\Feature; use BigBlueButton\Enum\GuestPolicy; use BigBlueButton\Enum\MeetingLayout; +use BigBlueButton\Util\SimpleXMLElementExtended; /** * @method string getName() @@ -157,6 +158,10 @@ * @method $this setPluginManifestsFetchUrl(string $pluginManifestsFetchUrl) * @method bool|null isPresentationConversionCacheEnabled() * @method $this setPresentationConversionCacheEnabled(bool $presentationConversionCacheEnabled) + * @method bool|null isAllowOverrideClientSettingsOnCreateCall() + * @method $this setAllowOverrideClientSettingsOnCreateCall(bool $allowOverrideClientSettingsOnCreateCall) + * @method string getClientSettingsOverride() + * @method $this setClientSettingsOverride(string $clientSettingsOverride) */ class CreateMeetingParameters extends MetaParameters { @@ -239,6 +244,8 @@ class CreateMeetingParameters extends MetaParameters protected ?string $pluginManifests = null; protected ?string $pluginManifestsFetchUrl = null; protected ?bool $presentationConversionCacheEnabled = null; + protected ?bool $allowOverrideClientSettingsOnCreateCall = null; + protected ?string $clientSettingsOverride = null; /** * @var array @@ -249,7 +256,7 @@ public function __construct(protected string $meetingID, protected string $name) { $this->guestPolicy = GuestPolicy::ALWAYS_ACCEPT; - $this->ignoreProperties = ['disabledFeatures', 'disabledFeaturesExclude']; + $this->ignoreProperties = ['disabledFeatures', 'disabledFeaturesExclude', 'clientSettingsOverride']; } public function setEndCallbackUrl(string $endCallbackUrl): self @@ -381,12 +388,26 @@ public function getPresentations(): array return $this->presentations; } - public function getPresentationsAsXML(): string|false + public function getModules(): string { - $result = ''; + $xml = new SimpleXMLElementExtended(''); + $this->addPresentationsModule($xml); + $this->addClientSettingsOverrideModule($xml); + return $xml->asXML(); + } + + public function addClientSettingsOverrideModule(SimpleXMLElementExtended $xml): void + { + if (!empty($this->clientSettingsOverride)) { + $module = $xml->addChildWithCData('module', $this->clientSettingsOverride); + $module->addAttribute('name', 'clientSettingsOverride'); + } + } + + public function addPresentationsModule(SimpleXMLElementExtended $xml): void + { if (!empty($this->presentations)) { - $xml = new \SimpleXMLElement(''); $module = $xml->addChild('module'); $module->addAttribute('name', 'presentation'); @@ -404,10 +425,7 @@ public function getPresentationsAsXML(): string|false $document[0] = $content; } } - $result = $xml->asXML(); } - - return $result; } public function getHTTPQuery(): string diff --git a/src/Util/SimpleXMLElementExtended.php b/src/Util/SimpleXMLElementExtended.php new file mode 100644 index 00000000..d019374e --- /dev/null +++ b/src/Util/SimpleXMLElementExtended.php @@ -0,0 +1,24 @@ +ownerDocument; + $element->appendChild($docOwner->createCDATASection($value)); + + return $child; + } +} diff --git a/tests/fixtures/client_settings.xml b/tests/fixtures/client_settings.xml new file mode 100644 index 00000000..6ef5db4b --- /dev/null +++ b/tests/fixtures/client_settings.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/unit/Parameters/CreateMeetingParametersTest.php b/tests/unit/Parameters/CreateMeetingParametersTest.php index 29028494..be94bead 100644 --- a/tests/unit/Parameters/CreateMeetingParametersTest.php +++ b/tests/unit/Parameters/CreateMeetingParametersTest.php @@ -202,7 +202,7 @@ public function testGetPresentationsAsXMLWithUrl(): void $params = $this->generateCreateParams(); $createMeetingParams = $this->getCreateMock($params); $createMeetingParams->addPresentation('http://test-install.blindsidenetworks.com/default.pdf'); - $this->assertXmlStringEqualsXmlFile(__DIR__.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'fixtures'.\DIRECTORY_SEPARATOR.'presentation_with_url.xml', $createMeetingParams->getPresentationsAsXML()); + $this->assertXmlStringEqualsXmlFile(__DIR__.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'fixtures'.\DIRECTORY_SEPARATOR.'presentation_with_url.xml', $createMeetingParams->getModules()); } public function testGetPresentationsAsXMLWithUrlAndFilename(): void @@ -210,7 +210,7 @@ public function testGetPresentationsAsXMLWithUrlAndFilename(): void $params = $this->generateCreateParams(); $createMeetingParams = $this->getCreateMock($params); $createMeetingParams->addPresentation('http://test-install.blindsidenetworks.com/default.pdf', null, 'presentation.pdf'); - $this->assertXmlStringEqualsXmlFile(__DIR__.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'fixtures'.\DIRECTORY_SEPARATOR.'presentation_with_filename.xml', $createMeetingParams->getPresentationsAsXML()); + $this->assertXmlStringEqualsXmlFile(__DIR__.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'fixtures'.\DIRECTORY_SEPARATOR.'presentation_with_filename.xml', $createMeetingParams->getModules()); } public function testGetPresentationsAsXMLWithFile(): void @@ -218,7 +218,7 @@ public function testGetPresentationsAsXMLWithFile(): void $params = $this->generateCreateParams(); $createMeetingParams = $this->getCreateMock($params); $createMeetingParams->addPresentation('bbb_logo.png', file_get_contents(__DIR__.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'fixtures'.\DIRECTORY_SEPARATOR.'bbb_logo.png')); - $this->assertXmlStringEqualsXmlFile(__DIR__.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'fixtures'.\DIRECTORY_SEPARATOR.'presentation_with_embedded_file.xml', $createMeetingParams->getPresentationsAsXML()); + $this->assertXmlStringEqualsXmlFile(__DIR__.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'fixtures'.\DIRECTORY_SEPARATOR.'presentation_with_embedded_file.xml', $createMeetingParams->getModules()); } public function testUserCameraCap(): void @@ -272,4 +272,14 @@ public function testGuestPolicyAskModerator(): void $this->assertSame(GuestPolicy::ASK_MODERATOR, $createMeetingParams->getGuestPolicy()); $this->assertTrue($createMeetingParams->isGuestPolicyAskModerator()); } + + public function testClientSettingsOverride(): void + { + $params = $this->generateCreateParams(); + $createMeetingParams = $this->getCreateMock($params); + + $createMeetingParams->setClientSettingsOverride('{ "public": { "app": { "appName": "Test" } } }'); + + $this->assertXmlStringEqualsXmlFile(__DIR__.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'fixtures'.\DIRECTORY_SEPARATOR.'client_settings.xml', $createMeetingParams->getModules()); + } } From 7bee3e975c5fefde60d911120b60dd0de736036b Mon Sep 17 00:00:00 2001 From: Samuel Weirich <4281791+SamuelWei@users.noreply.github.com> Date: Sat, 5 Jul 2025 19:45:32 +0200 Subject: [PATCH 2/3] Update src/Util/SimpleXMLElementExtended.php Co-authored-by: Felix Jacobi --- src/Util/SimpleXMLElementExtended.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Util/SimpleXMLElementExtended.php b/src/Util/SimpleXMLElementExtended.php index d019374e..d78c9e20 100644 --- a/src/Util/SimpleXMLElementExtended.php +++ b/src/Util/SimpleXMLElementExtended.php @@ -4,7 +4,7 @@ namespace BigBlueButton\Util; -class SimpleXMLElementExtended extends \SimpleXMLElement +final class SimpleXMLElementExtended extends \SimpleXMLElement { /** * Adds a child with $value inside CDATA. From ad60b153cd5507a3e4f9a91aa8eae0cc638b6dea Mon Sep 17 00:00:00 2001 From: Samuel Weirich <4281791+SamuelWei@users.noreply.github.com> Date: Tue, 8 Jul 2025 11:15:51 +0200 Subject: [PATCH 3/3] Add unit test --- .../Util/SimpleXMLElementExtendedTest.php | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 tests/unit/Util/SimpleXMLElementExtendedTest.php diff --git a/tests/unit/Util/SimpleXMLElementExtendedTest.php b/tests/unit/Util/SimpleXMLElementExtendedTest.php new file mode 100644 index 00000000..c29a09c7 --- /dev/null +++ b/tests/unit/Util/SimpleXMLElementExtendedTest.php @@ -0,0 +1,46 @@ +. + */ + +namespace BigBlueButton\Tests\Unit\Util; + +use BigBlueButton\Tests\Common\TestCase; +use BigBlueButton\Util\SimpleXMLElementExtended; + +/** + * @covers \BigBlueButton\Util\SimpleXMLElementExtended + */ +final class SimpleXMLElementExtendedTest extends TestCase +{ + /** + * Test adding a child element with CDATA content. + */ + public function testAddChildWithCData(): void + { + $xml = new SimpleXMLElementExtended(''); + $module = $xml->addChildWithCData('module', '{"foo": {"foo": "baa"}}'); + $module->addAttribute('name', 'clientSettingsOverride'); + + $expected = ' +'; + + $this->assertXmlStringEqualsXmlString($expected, $xml->asXML()); + } +}