1919class ExternalModule extends AbstractExternalModule {
2020 private $ survey_APF_fields = [];
2121
22+ function isFirstRepeatEventOrForm () {
23+ $ val = ($ this ->isFirstRepeatEvent () || $ this ->isFirstRepeatForm ());
24+ return $ val ;
25+ }
26+
27+ function isNthRepeatEventOrForm () {
28+ $ val = ($ this ->isNthRepeatEvent () || $ this ->isNthRepeatForm ());
29+ return $ val ;
30+ }
31+
2232 /**
23- * Returns true if the event is either a "Repeat Entire Event" or "Repeat Instrument" repeating event .
33+ * Returns true if the event is a "Repeat Entire Event (repeat all instruments together)" and is the first instance .
2434 */
25- function isRepeatEvent () {
26- $ val = ($ this ->isRepeatEntireEvent () || $ this ->isRepeatInstrument ());
27- return $ val ;
35+ function isFirstRepeatEvent () {
36+ if ($ _GET ['instance ' ] == 1 && $ GLOBALS ['isRepeatingEvent ' ]) {
37+ return true ;
38+ }
39+ return false ;
2840 }
2941
3042 /**
31- * Returns true if the event is a "Repeat Entire Event (repeat all instruments together)" and is not first instance.
43+ * Returns true if the event is a "Repeat Entire Event (repeat all instruments together)" and is NOT first instance.
3244 */
33- function isRepeatEntireEvent () {
34- // The first instance of Repeating events are treated differently from events where $_GET['instance'] > 1.
35- // For the first instance, we look at previous event. For $_GET['instance'] > 1, we look at the current event.
36- // Because $GLOBALS['isRepeatingEvent'] is true regardless of the instance of the event, we also check for the current instance.
45+ function isNthRepeatEvent () {
3746 if ($ _GET ['instance ' ] > 1 && $ GLOBALS ['isRepeatingEvent ' ]) {
3847 return true ;
3948 }
4049 return false ;
4150 }
4251
4352 /**
44- * Returns true if the event is a "Repeat Instrument (repeat independently of each other)".
53+ * Returns true if the event is a "Repeat Instrument (repeat independently of each other)" and is the first instance.
4554 */
46- function isRepeatInstrument () {
47- return $ GLOBALS ['isRepeatingForm ' ];
55+ function isFirstRepeatForm () {
56+ return ($ _GET ['instance ' ] == 1 && $ GLOBALS ['isRepeatingForm ' ]);
57+ }
58+
59+ /**
60+ * Returns true if the event is a "Repeat Instrument (repeat independently of each other)" and is NOT the first instance.
61+ */
62+ function isNthRepeatForm () {
63+ return ($ _GET ['instance ' ] > 1 && $ GLOBALS ['isRepeatingForm ' ]);
4864 }
4965
5066 /**
@@ -192,29 +208,27 @@ function setDefaultValues() {
192208 $ source_form = $ Proj ->metadata [$ source_field ]['form_name ' ];
193209
194210 // Getting previous event ID.
195- // For non repeating events the previous event is the closest event prior to the current event
196- // For repeating events, (Repeat Entire Event & Repeat Instrument) the previous event is the current event
211+ // For the first instance of a repeating event/form, the previous event is the closest saved event/form prior to the current event/form.
212+ // For the nth instance of a repeating event/form, the previous event is the current event.
197213 foreach ($ events as $ event ) {
198- // Only break for non repeating events.
199- // Non repeating events should not get data from current event, whereas, repeating events with instances depend on data from the current event i.e., $_GET['event_id']
200- if ($ event == $ _GET ['event_id ' ] && !$ this ->isRepeatEvent ()) {
214+ if (!in_array ($ source_form , $ Proj ->eventsForms [$ event ])) {
201215 break ;
202216 }
203217
204- if (in_array ($ source_form , $ Proj ->eventsForms [$ event ]) && !$ this ->isRepeatEvent ()) {
205- $ prev_event = $ event ;
206- $ form_name = "" ;
207- } elseif (in_array ($ source_form , $ Proj ->eventsForms [$ event ]) && $ this ->isRepeatEntireEvent ()) {
208- $ prev_event = $ _GET ['event_id ' ];
209- $ form_name = "" ;
218+ // Only break for the first instance of an event/form.
219+ // First instance events or forms need data from previous events/forms, whereas, nth repeating events/forms depend on data from the current event i.e., $_GET['event_id']
220+ if ($ event == $ _GET ['event_id ' ] && $ this ->isFirstRepeatEventOrForm ()) {
210221 break ;
211- } elseif (in_array ($ source_form , $ Proj ->eventsForms [$ event ]) && $ this ->isRepeatInstrument ()) {
212- // Repeat instruments behave differently from 'Repeat Entire Event' and non repeating events.
213- // Repeat instruments require the $Proj->metadata[$field_name]['form_name'] when looking up the data from the event
222+ }
223+
224+ // Set the previous event for first instance of a repeat event/form to the previous event.
225+ // Set the previous event for the nth instance of a repeat event/form to the current event.
226+ if ($ this ->isFirstRepeatEventOrForm ()) {
227+ $ prev_event = $ event ;
228+ } elseif ($ this ->isNthRepeatEventOrForm ()) {
214229 $ prev_event = $ _GET ['event_id ' ];
215- $ form_name = $ source_form ;
216230 break ;
217- }
231+ }
218232 }
219233
220234 if (!$ prev_event ) {
@@ -225,12 +239,20 @@ function setDefaultValues() {
225239 // isset returns true for event instances when $prev_event_field_value is equal to an empty string ("").
226240 // An additional check to verify the value is not empty is required.
227241 $ prev_event_field_value = $ data [$ prev_event ][$ source_field ];
242+
243+ // The object returned by $instances = $data['repeat_instances'][$event] changes dependening on if the data is from an event or a form.
244+ // For repeating events, the key for $instances is an empty string ("") i.e., ["": ...]
245+ // For repeating forms, the key for $instances is the form name i.e., ["baseline_data": ...]
246+ $ instances = ($ data ['repeat_instances ' ][$ prev_event ][$ source_form ]) ?? ($ data ['repeat_instances ' ][$ prev_event ]["" ]);
247+
228248 if (isset ($ prev_event_field_value ) && !empty ($ prev_event_field_value )) {
229249 $ default_value = $ prev_event_field_value ;
230- } elseif (isset ($ data [ ' repeat_instances ' ][ $ prev_event ][ $ form_name ] )) {
250+ } elseif (isset ($ instances )) {
231251 // Handling repeat events by using the most recent instance of the previous event to source values
232- $ most_recent_instance = array_slice ($ data ['repeat_instances ' ][$ prev_event ][$ form_name ], -1 )[0 ];
233- $ default_value = $ most_recent_instance [$ source_field ];
252+ // $instances are out of order when form data is deleted.
253+ // In that case, using array_slice($instances, -1)[0] is unreliable and can return the wrong instance.
254+ $ max = max (array_keys ($ instances ));
255+ $ default_value = $ instances [$ max ][$ source_field ];
234256 }
235257
236258 // Handling checkboxes case.
0 commit comments