/** * Move this competency so it sits in a new parent. * * Requires moodle/competency:competencymanage capability at the system context. * * @param int $id The id of the competency to move. * @param int $newparentid The new parent id for the competency. * @return boolean */ public static function set_parent_competency($id, $newparentid) { global $DB; static::require_enabled(); $current = new competency($id); // First we do a permissions check. require_capability('moodle/competency:competencymanage', $current->get_context()); if ($id == $newparentid) { throw new coding_exception('Can not set a competency as a parent of itself.'); } if ($newparentid == $current->get_parentid()) { throw new coding_exception('Can not move a competency to the same location.'); } // Some great variable assignment right here. $currentparent = $current->get_parent(); $parent = !empty($newparentid) ? new competency($newparentid) : null; $parentpath = !empty($parent) ? $parent->get_path() : '/0/'; // We're going to change quite a few things. $transaction = $DB->start_delegated_transaction(); // If we are moving a node to a child of itself: // - promote all the child nodes by one level. // - remove the rule on self. // - re-read the parent. $newparents = explode('/', $parentpath); if (in_array($current->get_id(), $newparents)) { $children = competency::get_records(array('parentid' => $current->get_id()), 'id'); foreach ($children as $child) { $child->set_parentid($current->get_parentid()); $child->update(); } // Reset the rule on self as our children have changed. $current->reset_rule(); // The destination parent is one of our descendants, we need to re-fetch its values (path, parentid). $parent->read(); } // Reset the rules of initial parent and destination. if (!empty($currentparent)) { $currentparent->reset_rule(); $currentparent->update(); } if (!empty($parent)) { $parent->reset_rule(); $parent->update(); } // Do the actual move. $current->set_parentid($newparentid); $result = $current->update(); // All right, let's commit this. $transaction->allow_commit(); return $result; }