Exemple #1
0
 /**
  * Move a slot from its current location to a new location.
  *
  * After callig this method, this class will be in an invalid state, and
  * should be discarded if you want to manipulate the structure further.
  *
  * @param int $idmove id of slot to be moved
  * @param int $idbefore id of slot to come before slot being moved
  * @param int $page new page number of slot being moved
  * @return void
  */
 public function move_slot($idmove, $idbefore, $page)
 {
     global $DB;
     $this->check_can_be_edited();
     $movingslot = $this->slots[$idmove];
     if (empty($movingslot)) {
         throw new moodle_exception('Bad slot ID ' . $idmove);
     }
     $movingslotnumber = (int) $movingslot->slot;
     // Empty target slot means move slot to first.
     if (empty($idbefore)) {
         $targetslotnumber = 0;
     } else {
         $targetslotnumber = (int) $this->slots[$idbefore]->slot;
     }
     // Work out how things are being moved.
     $slotreorder = array();
     if ($targetslotnumber > $movingslotnumber) {
         $slotreorder[$movingslotnumber] = $targetslotnumber;
         for ($i = $movingslotnumber; $i < $targetslotnumber; $i++) {
             $slotreorder[$i + 1] = $i;
         }
     } else {
         if ($targetslotnumber < $movingslotnumber - 1) {
             $slotreorder[$movingslotnumber] = $targetslotnumber + 1;
             for ($i = $targetslotnumber + 1; $i < $movingslotnumber; $i++) {
                 $slotreorder[$i] = $i + 1;
             }
         }
     }
     $trans = $DB->start_delegated_transaction();
     // Slot has moved record new order.
     if ($slotreorder) {
         update_field_with_unique_index('quiz_slots', 'slot', $slotreorder, array('quizid' => $this->get_quizid()));
     }
     // Page has changed. Record it.
     if (!$page) {
         $page = 1;
     }
     if ($movingslot->page != $page) {
         $DB->set_field('quiz_slots', 'page', $page, array('id' => $movingslot->id));
     }
     $emptypages = $DB->get_fieldset_sql("\n                SELECT DISTINCT page - 1\n                  FROM {quiz_slots} slot\n                 WHERE quizid = ?\n                   AND page > 1\n                   AND NOT EXISTS (SELECT 1 FROM {quiz_slots} WHERE quizid = ? AND page = slot.page - 1)\n              ORDER BY page - 1 DESC\n                ", array($this->get_quizid(), $this->get_quizid()));
     foreach ($emptypages as $page) {
         $DB->execute("\n                    UPDATE {quiz_slots}\n                       SET page = page - 1\n                     WHERE quizid = ?\n                       AND page > ?\n                    ", array($this->get_quizid(), $page));
     }
     $trans->allow_commit();
 }
 public function test_reorder_rows()
 {
     global $DB;
     $dbman = $DB->get_manager();
     $this->resetAfterTest();
     $table = new xmldb_table('test_table');
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $tablename = $table->getName();
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('otherid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
     $table->add_field('sortorder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
     $table->add_field('otherdata', XMLDB_TYPE_TEXT, 'big', null, null, null);
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->add_key('unique', XMLDB_KEY_UNIQUE, array('otherid', 'sortorder'));
     $dbman->create_table($table);
     // Rows intentionally added in a slightly 'random' order.
     // Note we are testing hat the otherid = 1 rows don't get messed up,
     // as well as testing that the otherid = 2 rows are updated correctly.
     $DB->insert_record($tablename, array('otherid' => 2, 'sortorder' => 1, 'otherdata' => 'To become 4'));
     $DB->insert_record($tablename, array('otherid' => 2, 'sortorder' => 2, 'otherdata' => 'To become 1'));
     $DB->insert_record($tablename, array('otherid' => 1, 'sortorder' => 1, 'otherdata' => 'Other 1'));
     $DB->insert_record($tablename, array('otherid' => 1, 'sortorder' => 2, 'otherdata' => 'Other 2'));
     $DB->insert_record($tablename, array('otherid' => 2, 'sortorder' => 3, 'otherdata' => 'To stay at 3'));
     $DB->insert_record($tablename, array('otherid' => 2, 'sortorder' => 4, 'otherdata' => 'To become 2'));
     update_field_with_unique_index($tablename, 'sortorder', array(1 => 4, 2 => 1, 3 => 3, 4 => 2), array('otherid' => 2));
     $this->assertEquals(array(3 => (object) array('id' => 3, 'otherid' => 1, 'sortorder' => 1, 'otherdata' => 'Other 1'), 4 => (object) array('id' => 4, 'otherid' => 1, 'sortorder' => 2, 'otherdata' => 'Other 2')), $DB->get_records($tablename, array('otherid' => 1), 'sortorder'));
     $this->assertEquals(array(2 => (object) array('id' => 2, 'otherid' => 2, 'sortorder' => 1, 'otherdata' => 'To become 1'), 6 => (object) array('id' => 6, 'otherid' => 2, 'sortorder' => 2, 'otherdata' => 'To become 2'), 5 => (object) array('id' => 5, 'otherid' => 2, 'sortorder' => 3, 'otherdata' => 'To stay at 3'), 1 => (object) array('id' => 1, 'otherid' => 2, 'sortorder' => 4, 'otherdata' => 'To become 4')), $DB->get_records($tablename, array('otherid' => 2), 'sortorder'));
 }
Exemple #3
0
 /**
  * Move a slot from its current location to a new location.
  *
  * After callig this method, this class will be in an invalid state, and
  * should be discarded if you want to manipulate the structure further.
  *
  * @param int $idmove id of slot to be moved
  * @param int $idmoveafter id of slot to come before slot being moved
  * @param int $page new page number of slot being moved
  * @param bool $insection if the question is moving to a place where a new
  *      section starts, include it in that section.
  * @return void
  */
 public function move_slot($idmove, $idmoveafter, $page)
 {
     global $DB;
     $this->check_can_be_edited();
     $movingslot = $this->slots[$idmove];
     if (empty($movingslot)) {
         throw new \moodle_exception('Bad slot ID ' . $idmove);
     }
     $movingslotnumber = (int) $movingslot->slot;
     // Empty target slot means move slot to first.
     if (empty($idmoveafter)) {
         $moveafterslotnumber = 0;
     } else {
         $moveafterslotnumber = (int) $this->slots[$idmoveafter]->slot;
     }
     // Check the target page number is OK.
     if ($page == 0) {
         $page = 1;
     }
     if ($moveafterslotnumber > 0 && $page < $this->get_page_number_for_slot($moveafterslotnumber) || $page < 1) {
         throw new \coding_exception('The target page number is too small.');
     } else {
         if (!$this->is_last_slot_in_quiz($moveafterslotnumber) && $page > $this->get_page_number_for_slot($moveafterslotnumber + 1)) {
             throw new \coding_exception('The target page number is too large.');
         }
     }
     // If the action came in as moving a slot to itself, normalise this to
     // moving the slot to after the previosu slot.
     if ($moveafterslotnumber == $movingslotnumber) {
         $moveafterslotnumber = $moveafterslotnumber - 1;
     }
     // Work out how things are being moved.
     $slotreorder = array();
     if ($moveafterslotnumber > $movingslotnumber) {
         // Moving down.
         $slotreorder[$movingslotnumber] = $moveafterslotnumber;
         for ($i = $movingslotnumber; $i < $moveafterslotnumber; $i++) {
             $slotreorder[$i + 1] = $i;
         }
         $headingmoveafter = $movingslotnumber;
         if ($this->is_last_slot_in_quiz($moveafterslotnumber) || $page == $this->get_page_number_for_slot($moveafterslotnumber + 1)) {
             // We are moving to the start of a section, so that heading needs
             // to be included in the ones that move up.
             $headingmovebefore = $moveafterslotnumber + 1;
         } else {
             $headingmovebefore = $moveafterslotnumber;
         }
         $headingmovedirection = -1;
     } else {
         if ($moveafterslotnumber < $movingslotnumber - 1) {
             // Moving up.
             $slotreorder[$movingslotnumber] = $moveafterslotnumber + 1;
             for ($i = $moveafterslotnumber + 1; $i < $movingslotnumber; $i++) {
                 $slotreorder[$i] = $i + 1;
             }
             if ($page == $this->get_page_number_for_slot($moveafterslotnumber + 1)) {
                 // Moving to the start of a section, don't move that section.
                 $headingmoveafter = $moveafterslotnumber + 1;
             } else {
                 // Moving tot the end of the previous section, so move the heading down too.
                 $headingmoveafter = $moveafterslotnumber;
             }
             $headingmovebefore = $movingslotnumber + 1;
             $headingmovedirection = 1;
         } else {
             // Staying in the same place, but possibly changing page/section.
             if ($page > $movingslot->page) {
                 $headingmoveafter = $movingslotnumber;
                 $headingmovebefore = $movingslotnumber + 2;
                 $headingmovedirection = -1;
             } else {
                 $headingmoveafter = $movingslotnumber - 1;
                 $headingmovebefore = $movingslotnumber + 1;
                 $headingmovedirection = 1;
             }
         }
     }
     if ($this->is_only_slot_in_section($movingslotnumber)) {
         throw new \coding_exception('You cannot remove the last slot in a section.');
     }
     $trans = $DB->start_delegated_transaction();
     // Slot has moved record new order.
     if ($slotreorder) {
         update_field_with_unique_index('quiz_slots', 'slot', $slotreorder, array('quizid' => $this->get_quizid()));
     }
     // Page has changed. Record it.
     if ($movingslot->page != $page) {
         $DB->set_field('quiz_slots', 'page', $page, array('id' => $movingslot->id));
     }
     // Update section fist slots.
     $DB->execute("\n                UPDATE {quiz_sections}\n                   SET firstslot = firstslot + ?\n                 WHERE quizid = ?\n                   AND firstslot > ?\n                   AND firstslot < ?\n                ", array($headingmovedirection, $this->get_quizid(), $headingmoveafter, $headingmovebefore));
     // If any pages are now empty, remove them.
     $emptypages = $DB->get_fieldset_sql("\n                SELECT DISTINCT page - 1\n                  FROM {quiz_slots} slot\n                 WHERE quizid = ?\n                   AND page > 1\n                   AND NOT EXISTS (SELECT 1 FROM {quiz_slots} WHERE quizid = ? AND page = slot.page - 1)\n              ORDER BY page - 1 DESC\n                ", array($this->get_quizid(), $this->get_quizid()));
     foreach ($emptypages as $page) {
         $DB->execute("\n                    UPDATE {quiz_slots}\n                       SET page = page - 1\n                     WHERE quizid = ?\n                       AND page > ?\n                    ", array($this->get_quizid(), $page));
     }
     $trans->allow_commit();
 }
Exemple #4
0
        ksort($newslotorder);
        $currentpage = 1;
        $currentslot = 1;
        $slotreorder = array();
        $slotpages = array();
        foreach ($newslotorder as $slotnumber) {
            if ($slotnumber == 0) {
                $currentpage += 1;
                continue;
            }
            $slotreorder[$slotnumber] = $currentslot;
            $slotpages[$currentslot] = $currentpage;
            $currentslot += 1;
        }
        $trans = $DB->start_delegated_transaction();
        update_field_with_unique_index('quiz_slots',
                'slot', $slotreorder, array('quizid' => $quiz->id));
        foreach ($slotpages as $slotnumber => $page) {
            $DB->set_field('quiz_slots', 'page', $page, array('quizid' => $quiz->id, 'slot' => $slotnumber));
        }
        $trans->allow_commit();
        $deletepreviews = true;
    }

    // If rescaling is required save the new maximum.
    $maxgrade = unformat_float(optional_param('maxgrade', -1, PARAM_RAW));
    if ($maxgrade >= 0) {
        quiz_set_grade($maxgrade, $quiz);
    }

    if ($deletepreviews) {
        quiz_delete_previews($quiz);