Skip to content

Instantly share code, notes, and snippets.

@mrclay
Created February 24, 2012 16:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrclay/1901985 to your computer and use it in GitHub Desktop.
Save mrclay/1901985 to your computer and use it in GitHub Desktop.
Delete duplicate enrol plugins caused by Moodle bug MDL-29414
<?php
/**
* Report and delete duplicate enrol plugins from courses, which arise by
* Moodle bug http://tracker.moodle.org/browse/MDL-29414
*/
class Moodle_EnrolDupeRemover {
/**
* @var Zend_Db_Adapter_Abstract
*/
protected $db;
/**
* @var string
*/
protected $prefix;
/**
* @param Zend_Db_Adapter_Abstract $db
* @param string $prefix
*/
public function __construct(Zend_Db_Adapter_Abstract $db, $prefix = 'mdl_') {
$this->db = $db;
$this->prefix = $prefix;
}
/**
* Get each combination of course and (guest/self) enrol plugin type where there
* are more than 2 instances. The first plugin id is returned so it can used when
* calling removeDupes()
*
* @return array
*/
public function getDupesReport() {
return $this->getAllDupes();
}
/**
* Removes duplicate "guest" and "self" enrol plugins from all courses, and
* returns number of duplicate rows removed for each course/type
*
* @return array
*/
public function batchRemoveDupes() {
$removals = array();
foreach ($this->getAllDupes() as $row) {
$removals[$row['courseId']][$row['enrolPluginType']] =
$this->removeDupes(
$row['courseId'],
$row['enrolPluginType'],
$row['firstEnrolPluginId']);
}
return $removals;
}
/**
* Remove duplicates of a sign type in a single course. If $originalPluginId is
* not provided, 1 additional query is used.
*
* @param int $courseId
* @param string $type (e.g. "guest")
* @param int $originalPluginId (if not provided, function will find it)
* @return int num rows removed
*/
public function removeDupes($courseId, $type, $originalPluginId = null) {
if (! $originalPluginId) {
// assume the earliest id is the original
$firstTwoIds = $this->db->fetchCol("
SELECT id FROM {$this->prefix}enrol
WHERE courseid = ?
AND enrol = ?
ORDER BY id
LIMIT 2
", array($courseId, $type));
if (! $firstTwoIds || count($firstTwoIds) == 1) {
return 0;
} else {
$originalPluginId = $firstTwoIds[0];
}
}
// delete rest
return $this->db->query("
DELETE FROM {$this->prefix}enrol
WHERE courseid = ?
AND enrol = ?
AND id != ?
", array($courseId, $type, $originalPluginId))->rowCount();
}
/**
* @return array
*/
protected function getAllDupes() {
$typesSet = $this->db->quote($this->getSingularTypes());
return $this->db->fetchAll("
SELECT
courseid AS courseId,
MIN(id) AS firstEnrolPluginId,
enrol AS enrolPluginType,
(COUNT(*) - 1) AS numDuplicates
FROM {$this->prefix}enrol
WHERE enrol IN ($typesSet)
GROUP BY courseid, enrol
HAVING COUNT(*) > 1
ORDER BY id
");
}
/**
* @return array
*/
protected function getSingularTypes() {
return array('guest', 'self');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment