@@ -6,6 +6,7 @@ class XMLModifier
66 private $ modDir ;
77 private $ rootDir ;
88 private $ bakFiles = [];
9+ private static $ active_modules = [];
910
1011 public function __construct ($ rootDir , $ modDir )
1112 {
@@ -16,6 +17,11 @@ public function __construct($rootDir, $modDir)
1617 public function apply ()
1718 {
1819 foreach (glob ($ this ->modDir . '*/*/*.ocmod.xml ' ) as $ file ) {
20+ $ module_name = basename (dirname (dirname ($ file )));
21+ if (!$ this ->isActiveModule ($ module_name )) {
22+ continue ;
23+ }
24+
1925 $ xml = simplexml_load_file ($ file );
2026 foreach ($ xml ->file as $ f ) {
2127 $ relPath = (string ) $ f ['path ' ];
@@ -65,60 +71,52 @@ public function apply()
6571 $ index = isset ($ searchNode ['index ' ]) ? (int )$ searchNode ['index ' ] : -1 ;
6672
6773 $ lines = explode ("\n" , $ modified );
68- $ newLines = [];
6974 $ matchCount = 0 ;
75+ $ targetIndex = isset ($ searchNode ['index ' ]) ? (int )$ searchNode ['index ' ] : -1 ;
7076
71- for ($ i = 0 ; $ i < count ($ lines ); $ i ++) {
72- $ line = $ lines [$ i ];
73- $ check = $ searchTrim ? trim ($ line ) : $ line ;
77+ for ($ line_id = 0 ; $ line_id < count ($ lines ); $ line_id ++) {
78+ $ line = $ lines [$ line_id ];
7479
75- if (strpos ($ check , $ search ) !== false ) {
76- $ shouldApply = ($ index === -1 || $ matchCount === $ index );
80+ if (strpos ($ line , $ search ) !== false ) {
81+ // Respect index="X"
82+ if ($ targetIndex !== -1 && $ matchCount !== $ targetIndex ) {
83+ $ matchCount ++;
84+ continue ;
85+ }
7786 $ matchCount ++;
7887
79- if ($ shouldApply ) {
80- switch ($ position ) {
81- case 'before ' :
82- $ newLines [] = $ add ;
83- $ newLines [] = $ line ;
84- break ;
85-
86- case 'after ' :
87- $ newLines [] = $ line ;
88-
89- // Offset controls how many lines after the match we skip before injecting
90- for ($ j = 1 ; $ j <= $ offset && ($ i + $ j ) < count ($ lines ); $ j ++) {
91- $ newLines [] = $ lines [$ i + $ j ];
92- }
93-
94- $ newLines [] = $ add ;
95-
96- // Advance $i by offset lines, since we already added them
97- $ i += $ offset ;
98- break ;
99-
100- case 'replace ' :
101- // Preserve indentation of the original line
102- preg_match ('/^(\s*)/ ' , $ line , $ indentMatch );
103- $ indent = $ indentMatch [1 ] ?? '' ;
104-
105- // Indent each line of the injected code
106- $ indentedAdd = implode ("\n" , array_map (function ($ l ) use ($ indent ) {
107- return $ indent . $ l ;
108- }, explode ("\n" , $ add )));
109-
110- $ newLines [] = $ indentedAdd ;
111- break ;
112- }
113- } else {
114- $ newLines [] = $ line ;
88+ switch ($ position ) {
89+ default :
90+ case 'replace ' :
91+ $ new_lines = explode ("\n" , $ add );
92+
93+ if ($ offset < 0 ) {
94+ array_splice ($ lines , $ line_id + $ offset , abs ($ offset ) + 1 , $ new_lines );
95+ $ line_id -= $ offset ;
96+ } else {
97+ array_splice ($ lines , $ line_id , $ offset + 1 , $ new_lines );
98+ }
99+ break ;
100+
101+ case 'before ' :
102+ $ new_lines = explode ("\n" , $ add );
103+ array_splice ($ lines , max (0 , $ line_id - $ offset ), 0 , $ new_lines );
104+ $ line_id += count ($ new_lines );
105+ break ;
106+
107+ case 'after ' :
108+ $ new_lines = explode ("\n" , $ add );
109+ array_splice ($ lines , min (count ($ lines ), ($ line_id + 1 ) + $ offset ), 0 , $ new_lines );
110+ $ line_id += count ($ new_lines );
111+ break ;
115112 }
116- } else {
117- $ newLines [] = $ line ;
113+
114+ // Stop if specific index matched (no need to continue)
115+ if ($ targetIndex !== -1 ) break ;
118116 }
119117 }
120118
121- $ modified = implode ("\n" , $ newLines );
119+ $ modified = implode ("\n" , $ lines );
122120 }
123121 }
124122
@@ -129,6 +127,17 @@ public function apply()
129127 return true ;
130128 }
131129
130+ private function isActiveModule ($ moduleName )
131+ {
132+ // Only apply if installed and active
133+ if ($ moduleName && (in_array ($ moduleName , self ::$ active_modules ) || \Module::isEnabled ($ moduleName ))) {
134+ self ::$ active_modules [] = $ moduleName ;
135+ return true ;
136+ }
137+
138+ return false ;
139+ }
140+
132141 public function revert ()
133142 {
134143 $ directory = $ this ->rootDir ;
@@ -154,7 +163,7 @@ public function revert()
154163 return true ;
155164 }
156165
157- private function getBackupFiles ()
166+ public function getBackupFiles ()
158167 {
159168 return $ this ->bakFiles ;
160169 }
0 commit comments