diff --git a/composer.json b/composer.json index 0e0a0f91..41aa5d42 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "smartling/wordpress-connector", "license": "GPL-2.0-or-later", - "version": "5.3.3", + "version": "5.3.4", "description": "", "type": "wordpress-plugin", "repositories": [ diff --git a/inc/Smartling/ContentTypes/Elementor/Elements/MegaMenu.php b/inc/Smartling/ContentTypes/Elementor/Elements/MegaMenu.php new file mode 100644 index 00000000..c5720cba --- /dev/null +++ b/inc/Smartling/ContentTypes/Elementor/Elements/MegaMenu.php @@ -0,0 +1,93 @@ +getIntSettingByKey($key, $this->settings); + if ($id !== null) { + $return->addContent(new Content($id, ContentTypeHelper::POST_TYPE_ATTACHMENT), $this->id, "settings/$key"); + } + } + + foreach ($this->settings['menu_items'] ?? [] as $index => $item) { + if (isset($item[self::SETTING_KEY_DYNAMIC]) && is_array($item[self::SETTING_KEY_DYNAMIC])) { + $path = "settings/menu_items/$index/" . self::SETTING_KEY_DYNAMIC; + foreach ($this->getRelatedFromDynamic($item[self::SETTING_KEY_DYNAMIC], $path) as $relatedItem) { + $return->addContent($relatedItem->getContent(), $relatedItem->getContainerId(), $relatedItem->getPath()); + } + } + } + + return $return; + } + + public function getTranslatableStrings(): array + { + $return = parent::getTranslatableStrings(); + + if (array_key_exists('menu_name', $this->settings)) { + $return[$this->id]['menu_name'] = $this->settings['menu_name']; + } + + foreach ($this->settings['menu_items'] ?? [] as $item) { + if (!array_key_exists('_id', $item)) { + $this->getLogger()->warning("Missing _id for menu item in $this->id"); + continue; + } + $key = "menu_items/{$item['_id']}"; + if (array_key_exists('item_title', $item)) { + $return[$this->id][$key]['item_title'] = $item['item_title']; + } + } + + return $return; + } + + public function setTargetContent( + ExternalContentElementor $externalContentElementor, + RelatedContentInfo $info, + array $strings, + SubmissionEntity $submission, + ): static { + $this->raw = parent::setTargetContent($externalContentElementor, $info, $strings, $submission)->toArray(); + $this->settings = $this->raw['settings'] ?? []; + + foreach ($strings[$this->id] ?? [] as $array) { + if (is_array($array)) { + foreach ($array as $id => $values) { + foreach ($this->settings['menu_items'] ?? [] as $index => $item) { + if (($item['_id'] ?? '') === $id) { + foreach ($values as $property => $value) { + $this->settings['menu_items'][$index][$property] = $value; + } + } + } + } + } + } + $this->raw['settings'] = $this->settings; + + return new static($this->raw); + } +} diff --git a/readme.txt b/readme.txt index 6ac1193b..d3386109 100755 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Tags: translation, localization, multilingual, internationalization, smartling Requires at least: 5.5 Tested up to: 6.9 Requires PHP: 8.0 -Stable tag: 5.3.3 +Stable tag: 5.3.4 License: GPLv2 or later Translate content in WordPress quickly and seamlessly with Smartling, the industry-leading Translation Management System. @@ -62,6 +62,9 @@ Additional information on the Smartling Connector for WordPress can be found [he 3. Track translation status within WordPress from the Submissions Board. View overall progress of submitted translation requests as well as resend updated content. == Changelog == += 5.3.4 = +* Added support for Elementor mega-menu widget + = 5.3.3 = * Added support for Elementor gallery widget diff --git a/smartling-connector.php b/smartling-connector.php index 1abef387..e3eb7628 100755 --- a/smartling-connector.php +++ b/smartling-connector.php @@ -11,7 +11,7 @@ * Plugin Name: Smartling Connector * Plugin URI: https://www.smartling.com/products/automate/integrations/wordpress/ * Description: Integrate your WordPress site with Smartling to upload your content and download translations. - * Version: 5.3.3 + * Version: 5.3.4 * Author: Smartling * Author URI: https://www.smartling.com * License: GPL-2.0+ diff --git a/tests/Smartling/ContentTypes/Elementor/MegaMenuTest.php b/tests/Smartling/ContentTypes/Elementor/MegaMenuTest.php new file mode 100644 index 00000000..a838e151 --- /dev/null +++ b/tests/Smartling/ContentTypes/Elementor/MegaMenuTest.php @@ -0,0 +1,227 @@ + '7399cf4', + 'elType' => 'widget', + 'widgetType' => 'mega-menu', + 'settings' => $settings, + 'elements' => [], + ]); + } + + public function testGetType(): void + { + $this->assertEquals('mega-menu', $this->makeWidget()->getType()); + } + + public function testGetRelatedReturnsSvgIconIds(): void + { + $widget = $this->makeWidget([ + 'menu_item_icon' => ['value' => ['url' => 'https://example.com/right.svg', 'id' => 21340], 'library' => 'svg'], + 'menu_toggle_icon_normal' => ['value' => ['url' => 'https://example.com/menu.svg', 'id' => 1203], 'library' => 'svg'], + 'menu_toggle_icon_active' => ['value' => ['url' => 'https://example.com/close.svg', 'id' => 21246], 'library' => 'svg'], + ]); + + $list = $widget->getRelated()->getRelatedContentList(); + + $this->assertArrayHasKey(ContentTypeHelper::POST_TYPE_ATTACHMENT, $list); + $this->assertContains(21340, $list[ContentTypeHelper::POST_TYPE_ATTACHMENT]); + $this->assertContains(1203, $list[ContentTypeHelper::POST_TYPE_ATTACHMENT]); + $this->assertContains(21246, $list[ContentTypeHelper::POST_TYPE_ATTACHMENT]); + } + + public function testGetRelatedSkipsEmptyIconId(): void + { + $widget = $this->makeWidget([ + 'menu_item_icon_active' => ['value' => '', 'library' => ''], + ]); + + $list = $widget->getRelated()->getRelatedContentList(); + + $this->assertArrayNotHasKey(ContentTypeHelper::POST_TYPE_ATTACHMENT, $list); + } + + public function testGetRelatedExtractsDynamicTagFromMenuItem(): void + { + $widget = $this->makeWidget([ + 'menu_items' => [ + [ + '_id' => '1dc9acb', + 'item_title' => 'Customers', + '__dynamic__' => [ + 'item_link' => '[elementor-tag id="70af237" name="internal-url" settings="%7B%22type%22%3A%22post%22%2C%22post_id%22%3A%228603%22%7D"]', + ], + ], + ], + ]); + + $list = $widget->getRelated()->getRelatedContentList(); + + $this->assertArrayHasKey(ContentTypeHelper::CONTENT_TYPE_POST, $list); + $this->assertContains(8603, $list[ContentTypeHelper::CONTENT_TYPE_POST]); + } + + public function testGetTranslatableStringsReturnsMenuName(): void + { + $widget = $this->makeWidget(['menu_name' => 'Menu']); + + $strings = $widget->getTranslatableStrings(); + + $this->assertArrayHasKey('7399cf4', $strings); + $this->assertEquals('Menu', $strings['7399cf4']['menu_name']); + } + + public function testGetTranslatableStringsReturnsItemTitles(): void + { + $widget = $this->makeWidget([ + 'menu_items' => [ + ['_id' => 'c819dfc', 'item_title' => 'Products', 'item_dropdown_content' => 'yes'], + ['_id' => '88cdd5a', 'item_title' => 'Solutions', 'item_dropdown_content' => 'yes'], + ['_id' => '8934ff0', 'item_title' => 'Support'], + ], + ]); + + $strings = $widget->getTranslatableStrings(); + + $this->assertEquals('Products', $strings['7399cf4']['menu_items/c819dfc']['item_title']); + $this->assertEquals('Solutions', $strings['7399cf4']['menu_items/88cdd5a']['item_title']); + $this->assertEquals('Support', $strings['7399cf4']['menu_items/8934ff0']['item_title']); + } + + public function testSetTargetContentAppliesTranslatedMenuName(): void + { + $proxy = $this->createMock(WordpressFunctionProxyHelper::class); + $externalContentElementor = $this->createMock(ExternalContentElementor::class); + $externalContentElementor->method('getWpProxy')->willReturn($proxy); + + $widget = $this->makeWidget(['menu_name' => 'Menu']); + + $strings = [ + '7399cf4' => ['menu_name' => 'Menü'], + ]; + + $result = $widget->setTargetContent( + $externalContentElementor, + new RelatedContentInfo([]), + $strings, + $this->createMock(SubmissionEntity::class), + )->toArray(); + + $this->assertEquals('Menü', $result['settings']['menu_name']); + } + + public function testSetTargetContentAppliesTranslatedItemTitles(): void + { + $proxy = $this->createMock(WordpressFunctionProxyHelper::class); + $externalContentElementor = $this->createMock(ExternalContentElementor::class); + $externalContentElementor->method('getWpProxy')->willReturn($proxy); + + $widget = $this->makeWidget([ + 'menu_items' => [ + ['_id' => 'c819dfc', 'item_title' => 'Products'], + ['_id' => '88cdd5a', 'item_title' => 'Solutions'], + ], + ]); + + $strings = [ + '7399cf4' => [ + 'menu_items' => [ + 'c819dfc' => ['item_title' => 'Produkte'], + '88cdd5a' => ['item_title' => 'Lösungen'], + ], + ], + ]; + + $result = $widget->setTargetContent( + $externalContentElementor, + new RelatedContentInfo([]), + $strings, + $this->createMock(SubmissionEntity::class), + )->toArray(); + + $this->assertEquals('Produkte', $result['settings']['menu_items'][0]['item_title']); + $this->assertEquals('Lösungen', $result['settings']['menu_items'][1]['item_title']); + } + + public function testSetTargetContentAppliesTranslatedMenuNameAndItemTitlesTogether(): void + { + $proxy = $this->createMock(WordpressFunctionProxyHelper::class); + $externalContentElementor = $this->createMock(ExternalContentElementor::class); + $externalContentElementor->method('getWpProxy')->willReturn($proxy); + + $widget = $this->makeWidget([ + 'menu_name' => 'Menu', + 'menu_items' => [ + ['_id' => 'c819dfc', 'item_title' => 'Products'], + ['_id' => '88cdd5a', 'item_title' => 'Solutions'], + ], + ]); + + $strings = [ + '7399cf4' => [ + 'menu_name' => 'Menü', + 'menu_items' => [ + 'c819dfc' => ['item_title' => 'Produkte'], + '88cdd5a' => ['item_title' => 'Lösungen'], + ], + ], + ]; + + $result = $widget->setTargetContent( + $externalContentElementor, + new RelatedContentInfo([]), + $strings, + $this->createMock(SubmissionEntity::class), + )->toArray(); + + $this->assertEquals('Menü', $result['settings']['menu_name']); + $this->assertEquals('Produkte', $result['settings']['menu_items'][0]['item_title']); + $this->assertEquals('Lösungen', $result['settings']['menu_items'][1]['item_title']); + } + + public function testSetTargetContentUpdatesIconId(): void + { + $sourceId = 21340; + $targetId = 99999; + + $proxy = $this->createMock(WordpressFunctionProxyHelper::class); + $externalContentElementor = $this->createMock(ExternalContentElementor::class); + $externalContentElementor->method('getTargetId') + ->with(0, $sourceId, 0, ContentTypeHelper::POST_TYPE_ATTACHMENT) + ->willReturn($targetId); + $externalContentElementor->method('getWpProxy')->willReturn($proxy); + + $submission = $this->createMock(SubmissionEntity::class); + $submission->method('getSourceBlogId')->willReturn(0); + $submission->method('getTargetBlogId')->willReturn(0); + + $widget = $this->makeWidget([ + 'menu_item_icon' => ['value' => ['url' => 'https://example.com/right.svg', 'id' => $sourceId], 'library' => 'svg'], + ]); + + $info = $widget->getRelated(); + + $result = $widget->setTargetContent( + $externalContentElementor, + $info, + [], + $submission, + )->toArray(); + + $this->assertEquals($targetId, $result['settings']['menu_item_icon']['value']['id']); + } +} diff --git a/tests/Smartling/ContentTypes/ExternalContentElementorTest.php b/tests/Smartling/ContentTypes/ExternalContentElementorTest.php index ba13c117..31b08ad0 100644 --- a/tests/Smartling/ContentTypes/ExternalContentElementorTest.php +++ b/tests/Smartling/ContentTypes/ExternalContentElementorTest.php @@ -271,6 +271,14 @@ public function extractElementorDataProvider(): array 'b966541/0841fb9/2dd1556/7399cf4/0b0011b/4ad1ceb/7a17916/caaf2cc/title' => 'Company – Let’s Talk', 'b966541/0841fb9/2dd1556/7399cf4/2012db2/e558561/text' => 'Contact Us', 'b966541/0841fb9/2dd1556/7399cf4/2012db2/0292a78/5227d76/icon_list/bb4f3a3/text' => 'China (CN)', + 'b966541/0841fb9/2dd1556/7399cf4/menu_name' => 'Menu', + 'b966541/0841fb9/2dd1556/7399cf4/menu_items/c819dfc/item_title' => 'Products', + 'b966541/0841fb9/2dd1556/7399cf4/menu_items/88cdd5a/item_title' => 'Solutions', + 'b966541/0841fb9/2dd1556/7399cf4/menu_items/1dc9acb/item_title' => 'Customers', + 'b966541/0841fb9/2dd1556/7399cf4/menu_items/0fc6785/item_title' => 'Resources', + 'b966541/0841fb9/2dd1556/7399cf4/menu_items/8934ff0/item_title' => 'Support', + 'b966541/0841fb9/2dd1556/7399cf4/menu_items/d7e704f/item_title' => 'Company', + 'b966541/0841fb9/2dd1556/7399cf4/menu_items/730c97a/item_title' => 'Contact Us', 'b966541/0841fb9/06f836b/9131e8d/text' => 'Contact Us', ], [ @@ -280,6 +288,9 @@ public function extractElementorDataProvider(): array 38, 40, 41, + 21340, + 1203, + 21246, 4830, ], ContentTypeHelper::CONTENT_TYPE_POST => [ @@ -288,6 +299,7 @@ public function extractElementorDataProvider(): array 2408, 17571, 9935, + 8603, ], ContentTypeHelper::CONTENT_TYPE_UNKNOWN => [ 31885,