@@ -114,6 +114,7 @@ public function addTab($tabId, $tab)
114114 if (empty ($ tabId )) {
115115 throw new \Exception (__ ('Please correct the tab configuration and try again. Tab Id should be not empty ' ));
116116 }
117+
117118 if (is_array ($ tab )) {
118119 $ this ->_tabs [$ tabId ] = new \Magento \Framework \DataObject ($ tab );
119120 } elseif ($ tab instanceof \Magento \Framework \DataObject) {
@@ -123,13 +124,15 @@ public function addTab($tabId, $tab)
123124 }
124125 } elseif (is_string ($ tab )) {
125126 $ this ->_addTabByName ($ tab , $ tabId );
127+
126128 if (!$ this ->_tabs [$ tabId ] instanceof TabInterface) {
127129 unset($ this ->_tabs [$ tabId ]);
128130 return $ this ;
129131 }
130132 } else {
131133 throw new \Exception (__ ('Please correct the tab configuration and try again. ' ));
132134 }
135+
133136 if ($ this ->_tabs [$ tabId ]->getUrl () === null ) {
134137 $ this ->_tabs [$ tabId ]->setUrl ('# ' );
135138 }
@@ -140,10 +143,7 @@ public function addTab($tabId, $tab)
140143
141144 $ this ->_tabs [$ tabId ]->setId ($ tabId );
142145 $ this ->_tabs [$ tabId ]->setTabId ($ tabId );
143-
144- if ($ this ->_activeTab === null ) {
145- $ this ->_activeTab = $ tabId ;
146- }
146+
147147 if (true === $ this ->_tabs [$ tabId ]->getActive ()) {
148148 $ this ->setActiveTab ($ tabId );
149149 }
@@ -232,33 +232,108 @@ protected function _setActiveTab($tabId)
232232 */
233233 protected function _beforeToHtml ()
234234 {
235+ $ this ->_tabs = $ this ->reorderTabs ();
236+
235237 if ($ activeTab = $ this ->getRequest ()->getParam ('active_tab ' )) {
236238 $ this ->setActiveTab ($ activeTab );
237239 } elseif ($ activeTabId = $ this ->_authSession ->getActiveTabId ()) {
238240 $ this ->_setActiveTab ($ activeTabId );
239241 }
240242
241- $ _new = [];
243+ if ($ this ->_activeTab === null && !empty ($ this ->_tabs )) {
244+ /** @var TabInterface $tab */
245+ $ this ->_activeTab = (reset ($ this ->_tabs ))->getId ();
246+ }
247+
248+ $ this ->assign ('tabs ' , $ this ->_tabs );
249+ return parent ::_beforeToHtml ();
250+ }
251+
252+ /**
253+ * Reorder the tabs.
254+ *
255+ * @return array
256+ */
257+ private function reorderTabs ()
258+ {
259+ $ orderByIdentity = [];
260+ $ orderByPosition = [];
261+ $ position = 100 ;
262+
263+ /**
264+ * Set the initial positions for each tab.
265+ *
266+ * @var string $key
267+ * @var TabInterface $tab
268+ */
242269 foreach ($ this ->_tabs as $ key => $ tab ) {
243- foreach ($ this ->_tabs as $ k => $ t ) {
244- if ($ t ->getAfter () == $ key ) {
245- $ _new [$ key ] = $ tab ;
246- $ _new [$ k ] = $ t ;
247- } else {
248- if (!$ tab ->getAfter () || !in_array ($ tab ->getAfter (), array_keys ($ this ->_tabs ))) {
249- $ _new [$ key ] = $ tab ;
250- }
251- }
252- }
270+ $ tab ->setPosition ($ position );
271+
272+ $ orderByIdentity [$ key ] = $ tab ;
273+ $ orderByPosition [$ position ] = $ tab ;
274+
275+ $ position += 100 ;
253276 }
254277
255- $ this ->_tabs = $ _new ;
256- unset($ _new );
278+ return $ this ->applyTabsCorrectOrder ($ orderByPosition , $ orderByIdentity );
279+ }
280+
281+ /**
282+ * @param array $orderByPosition
283+ * @param array $orderByIdentity
284+ *
285+ * @return array
286+ */
287+ private function applyTabsCorrectOrder (array $ orderByPosition , array $ orderByIdentity )
288+ {
289+ $ positionFactor = 1 ;
290+
291+ /**
292+ * Rearrange the positions by using the after tag for each tab.
293+ *
294+ * @var integer $position
295+ * @var TabInterface $tab
296+ */
297+ foreach ($ orderByPosition as $ position => $ tab ) {
298+ if (!$ tab ->getAfter () || !in_array ($ tab ->getAfter (), array_keys ($ orderByIdentity ))) {
299+ $ positionFactor = 1 ;
300+ continue ;
301+ }
302+
303+ $ grandPosition = $ orderByIdentity [$ tab ->getAfter ()]->getPosition ();
304+ $ newPosition = $ grandPosition + $ positionFactor ;
257305
258- $ this ->assign ('tabs ' , $ this ->_tabs );
259- return parent ::_beforeToHtml ();
306+ unset($ orderByPosition [$ position ]);
307+ $ orderByPosition [$ newPosition ] = $ tab ;
308+ $ tab ->setPosition ($ newPosition );
309+
310+ $ positionFactor ++;
311+ }
312+
313+ return $ this ->finalTabsSortOrder ($ orderByPosition );
260314 }
261315
316+ /**
317+ * Apply the last sort order to tabs.
318+ *
319+ * @param array $orderByPosition
320+ *
321+ * @return array
322+ */
323+ private function finalTabsSortOrder (array $ orderByPosition )
324+ {
325+ ksort ($ orderByPosition );
326+
327+ $ ordered = [];
328+
329+ /** @var TabInterface $tab */
330+ foreach ($ orderByPosition as $ tab ) {
331+ $ ordered [$ tab ->getId ()] = $ tab ;
332+ }
333+
334+ return $ ordered ;
335+ }
336+
262337 /**
263338 * @return string
264339 */
0 commit comments