@@ -47,6 +47,8 @@ class qtype_questionpy_question extends question_graded_automatically_with_count
4747 public string $ packagehash ;
4848 /** @var string */
4949 public string $ questionstate ;
50+ /** @var question_data */
51+ public question_data $ questiondata ;
5052 /** @var stored_file|null */
5153 private ?stored_file $ packagefile ;
5254
@@ -75,14 +77,18 @@ class qtype_questionpy_question extends question_graded_automatically_with_count
7577 *
7678 * @param string $packagehash
7779 * @param string $questionstate
80+ * @param question_data $questiondata
7881 * @param stored_file|null $packagefile
7982 * @param api $api
8083 */
81- public function __construct (string $ packagehash , string $ questionstate , ?stored_file $ packagefile , api $ api ) {
84+ public function __construct (
85+ string $ packagehash , string $ questionstate , question_data $ questiondata , ?stored_file $ packagefile , api $ api
86+ ) {
8287 parent ::__construct ();
8388 $ this ->api = $ api ;
8489 $ this ->packagehash = $ packagehash ;
8590 $ this ->questionstate = $ questionstate ;
91+ $ this ->questiondata = $ questiondata ;
8692 $ this ->packagefile = $ packagefile ;
8793 }
8894
@@ -118,8 +124,7 @@ public function start_attempt(question_attempt_step $step, $variant): void {
118124 global $ PAGE ;
119125
120126 try {
121- // Unfortunately, we cannot access attempt data, as the attempt is not stored in the database at this point of time.
122- $ attributes = null ;
127+ $ attributes = $ this ->get_requested_attributes ();
123128 $ attempt = $ this ->api ->package ($ this ->packagehash , $ this ->packagefile )
124129 ->start_attempt ($ this ->questionstate , $ variant , $ attributes );
125130
@@ -184,18 +189,11 @@ public function apply_attempt_state(question_attempt_step $step) {
184189 /* TODO: This method is also called from question_attempt->regrade and
185190 question_attempt->start_question_based_on, where we shouldn't need to get the UI. */
186191 try {
187- if ($ this ->id !== null ) {
188- $ questiondata = question_data::from_question_id ($ this ->id );
189- $ requestedattributes = $ questiondata ->permissions ?->attributes;
190- if ($ requestedattributes ) {
191- $ attributes = $ this ->get_bridge ()->get_attributes ($ requestedattributes );
192- }
193- }
194-
192+ $ attributes = $ this ->get_requested_attributes ();
195193 $ attempt = $ this ->api ->package ($ this ->packagehash , $ this ->packagefile )
196194 ->view_attempt (
197195 $ this ->questionstate ,
198- $ attributes ?? null ,
196+ $ attributes ,
199197 $ this ->attemptstate ,
200198 $ this ->scoringstate ,
201199 $ lastresponse
@@ -433,11 +431,14 @@ public function make_behaviour(question_attempt $qa, $preferredbehaviour): quest
433431 * Get the QuestionPy bridge used to retrieve additional information about an attempt.
434432 *
435433 * @throws moodle_exception
436- * @return question_bridge_base
434+ * @return question_bridge_base|null
437435 */
438- public function get_bridge (): question_bridge_base {
436+ public function get_bridge (): ? question_bridge_base {
439437 if ($ this ->bridge === null ) {
440- $ this ->bridge = question_bridge_base::create ($ this ->get_behaviour ()->get_qa ());
438+ $ attempt = $ this ->get_behaviour ()->get_qa ();
439+ if ($ attempt ->get_database_id () !== null && is_numeric ($ attempt ->get_usage_id ())) {
440+ $ this ->bridge = question_bridge_base::create ($ attempt );
441+ }
441442 }
442443 return $ this ->bridge ;
443444 }
@@ -454,4 +455,15 @@ public function get_bridge(): question_bridge_base {
454455 public function set_bridge (question_bridge_base $ bridge ): void {
455456 $ this ->bridge = $ bridge ;
456457 }
458+
459+ /**
460+ * Retrieves the requested attributes if any.
461+ *
462+ * @return array|null
463+ * @throws moodle_exception
464+ */
465+ private function get_requested_attributes (): ?array {
466+ $ attributes = $ this ->questiondata ->permissions ?->attributes;
467+ return $ attributes ? $ this ->get_bridge ()?->get_attributes($ attributes ) : null ;
468+ }
457469}
0 commit comments