marți, 6 mai 2025

Asignare profesori la curs folosind un fișier csv

 

1. Crearea fișierului CSV

Fișierul CSV trebuie să conțină cel puțin următoarele coloane:

  • username – numele de utilizator al persoanei căreia îi atribui rolul.

  • course1 – codul scurt al cursului în care va fi atribuit rolul.

  • role1 – rolul pe care dorești să-l atribui (în cazul tău: manager).

Dacă un utilizator trebuie să fie manager la mai multe cursuri, poți adăuga mai multe coloane course2, role2, etc.

Exemplu de fișier CSV

csv
username,course1,role1,course2,role2 profesor1,matematica,manager,fizica,manager profesor2,biologie,manager,, profesor3,chimie,manager,geografie,manager
  • matematica, fizica, biologie, etc. sunt codurile scurte ale cursurilor, pe care le poți găsi în setările fiecărui curs.

  • manager este numele rolului în sistem. Verifică în Site administration > Users > Permissions > Define roles dacă numele exact al rolului este "manager" (dacă nu, modifică-l corespunzător în fișier).

2. Importarea fișierului CSV în Moodle

  1. Mergi la:
    Site administration > Users > Accounts > Upload users

  2. Încarcă fișierul CSV

  3. Setează opțiunile de import:

    • Selectează Allow renaming and updating pentru a nu suprascrie utilizatorii existenți.

    • Asigură-te că Existing users este setat pe "Only update", astfel încât să nu creeze conturi noi.

  4. Finalizează importul și verifică dacă utilizatorii au fost atribuiți corect.


3. Verificarea atribuirii rolurilor

  • Navighează la Site administration > Users > Permissions > Assign system roles pentru a verifica dacă utilizatorii sunt în rolul corect.

  • De asemenea, poți accesa un curs și verifica în Participants dacă persoanele respective au rolul de Manager.

luni, 3 martie 2025

creare cursuri si incarcare cohorte folosind fisier csv

 Procedura de incărcare a cursurilor cu cohortele aferente se face în trei pași:

1. Se crează fisierul csv cu următoarea structură:

shortname fullname category format

Pentru completare automată la shortname se foloseste functia
="S3G"&ROW(A2)-1&"-Chestionar"
Iar pentru fullname:
="Grupa "&ROW(A2)-1&" - Chestionar de evaluare a calităţii şi impactului programului"
A cu coloana corespunzătoare (B)
category - este categoria unde se incarca cursul
format este topics
La portofoliu avem formulele: 
="S4G"&ROW(A2)-1&"PP"
="Grupa "&ROW(B2)-1&" - Portofoliu profesional personal"

La chestionar avem:
="S4G"&ROW(A2)-1&"-Chestionar"
="Grupa "&ROW(A2)-1&" -Chestionar de evaluare a calităţii şi impactului programului"

Se crează în plus coloana templatecourse, unde se pune numele scurt al cursului
Se incarca fisierul csv la incarcare cursuri. Se setează la 0 secțiunile sau anunțurile - Sunt 5 inițial

Astfel se incarca si activitatile. Atentie la Anunturi, ca se scrie de doua ori. Daca las Anunturi trebuie sa scriu 0 la nr Anunturi

3. Pentru incărcarea cohortelor cu metoda sincronizare cohortă iar cohorta incărcată să fie de tipul student se folosește un plugin numit Upload enrolment methods
https://moodle.org/plugins/tool_uploadenrolmentmethods
fisierul csv are formatul
operation method shortname metacohort disabled role
unde: 
Structura fișierului CSV trebuie să respecte formatul pluginului. Coloanele necesare sunt:
  • operation: „add” (pentru a adăuga metoda).

  • method: „cohort” (pentru sincronizare cohortă).

  • shortname: Numele scurt al cursului (trebuie să existe deja în Moodle).

  • metacohort: Identificatorul cohortului (idnumber, ex. CH1).

  • disabled: 0 (activ) sau 1 (dezactivat).

  • role: „student” (pentru a seta rolul utilizatorilor).
Merge fără ghilimele






marți, 11 februarie 2025

Course dedication

 Se face pe cohorte

Seria 2 - grupa 1

in equis, am folderul Utilizatori S2 - Timp acces

Fisier pentru fiecare grupa S2G1M1-4 pentru modulele 1 - 4

Pentru fiecare curs intru in modul de editare si adaug blocul configurable reports - users user time dedication. Filtrez după numatul de ore, selectez 50 si aleg primii 35


In folder am scriptul python care aduna in a 5-a pagina numărul de ore pentru fiecare cursant

marți, 4 februarie 2025

luni, 3 februarie 2025

Sincronizare cohorte la cursuri - EQUIS Exemplu seria 3

 Sincronizare cohorte la cursuri - Exemplu seria 3

creez fisierul c2cs3.csv cohort 2 courses seria 3, cu continutul 

samd...


Salvez fisierul in /home/moodle/csv/c2cs3.csv 
Am creat un fisier in /home/moodle/public_html/moodle/admin/sync_cohorts.php 
continutul fisierului php:

<?php
// Script pentru sincronizarea cohortelor cu cursurile in Moodle (fara pluginuri suplimentare)
define('CLI_SCRIPT', true);
require_once('/home/moodle/public_html/moodle/config.php');
require_once($CFG->libdir . '/clilib.php');
require_once($CFG->dirroot . '/enrol/locallib.php');

// Preluare parametri din linia de comanda
list($options, $unrecognized) = cli_get_params([
    'help' => false,
    'file' => null
], [
    'h' => 'help',
    'f' => 'file'
]);

if ($options['help'] || empty($options['file'])) {
    echo "\nScript pentru sincronizarea cohortelor cu cursurile.\n";
    echo "\nUtilizare:\n";
    echo "php sync_cohorts.php --file=/cale/catre/cohorts.csv\n";
    echo "\nParametri:\n";
    echo "  --file, -f    Calea catre fisierul CSV care contine cohortele si cursurile\n";
    echo "  --help, -h    Afiseaza acest mesaj de ajutor\n";
    exit(0);
}

// Verificare existenta fisier CSV
$csvfile = $options['file'];
if (!file_exists($csvfile)) {
    cli_error("Fisierul CSV nu a fost gasit: {$csvfile}");
}

// Citire fisier CSV
if (($handle = fopen($csvfile, 'r')) !== false) {
    $header = fgetcsv($handle);

    if ($header === false || count($header) < 2) {
        cli_error("Fisierul CSV trebuie sa contina cel putin doua coloane: cohortid si courseid.");
    }

    $cohort_col = array_search('cohortid', $header);
    $course_col = array_search('courseid', $header);

    if ($cohort_col === false || $course_col === false) {
        cli_error("Fisierul CSV trebuie sa contina coloanele 'cohortid' si 'courseid'.");
    }

    while (($data = fgetcsv($handle)) !== false) {
        $cohortid = trim($data[$cohort_col]);
        $courseid = trim($data[$course_col]);

        // Verificare existenta cohortei
        $cohort = $DB->get_record('cohort', ['idnumber' => $cohortid], '*', IGNORE_MISSING);
        if (!$cohort) {
            cli_writeln("Cohorta cu ID-ul '{$cohortid}' nu a fost gasita.");
            continue;
        }

        // Verificare existenta cursului
        if (is_numeric($courseid)) {
            $course = $DB->get_record('course', ['id' => $courseid], '*', IGNORE_MISSING);
        } else {
            $course = $DB->get_record('course', ['shortname' => $courseid], '*', IGNORE_MISSING);
        }

        if (!$course) {
            cli_writeln("Cursul cu ID-ul sau numele scurt '{$courseid}' nu a fost gasit.");
            continue;
        }

        // Adaugare metoda de inscriere Cohort Sync daca nu exista
        $enrol = enrol_get_plugin('cohort');
        $instances = enrol_get_instances($course->id, true);
        $instance_exists = false;

        foreach ($instances as $instance) {
            if ($instance->enrol === 'cohort' && $instance->customint1 == $cohort->id) {
                $instance_exists = true;
                break;
            }
        }

        if (!$instance_exists) {
            $enrol->add_instance($course, ['customint1' => $cohort->id]);
            cli_writeln("Cohorta '{$cohortid}' a fost sincronizata cu cursul '{$courseid}'.");
        } else {
            cli_writeln("Cohorta '{$cohortid}' este deja sincronizata cu cursul '{$courseid}'.");
        }
    }

    fclose($handle);
} else {
    cli_error("Nu s-a putut deschide fisierul CSV: {$csvfile}");
}

cli_writeln("Sincronizarea cohortelor a fost finalizata.");

--------------------------
Pentru că fisierul csv este făcut in windows, trebuie sa il formatam pentru unix
folosim 2 comenzi
sed -i '1s/^\xEF\xBB\xBF//' /home/moodle/csv/c2cs3.csv  
dos2unix /home/moodle/csv/c2cs3.csv 

Comanda de sincronizare este:
 php /home/moodle/public_html/moodle/admin/sync_cohorts.php --file=/home/moodle/csv/c2cs3.csv

Atenție! Scriptul nu asignează rolul de student pentru cursanți

-------------------------------------------------

Am modificat scriptul pentru a seta automat rolul utilizatorilor ca Student în momentul în care cohorta este sincronizată cu un curs. Acum include o verificare a rolului și setează roleid la rolul „student” (roleid = 5 în mod implicit în Moodle, dar verifică dacă este corect în baza ta de date).

Modificări aduse:

  1. Adăugată o coloană nouă în CSV:
    • Poți acum adăuga o coloană „role” în fișierul CSV pentru a specifica rolul (exemplu: student).
    • Dacă nu specifici rolul, scriptul va folosi implicit „student”.
  2. Setare automată a rolului pentru metoda „Cohort sync”
    • Scriptul verifică și setează rolul corect pentru cohorta sincronizată.

Modificarea scriptului PHP

Am adăugat suport pentru rol și verificarea roleid în baza de date.

<?php

// Script pentru sincronizarea cohortelor cu cursurile in Moodle și setarea rolului Student

define('CLI_SCRIPT', true);

require_once('/home/moodle/public_html/moodle/config.php');

require_once($CFG->libdir . '/clilib.php');

require_once($CFG->dirroot . '/enrol/locallib.php');


// Preluare parametri din linia de comandă

list($options, $unrecognized) = cli_get_params([

    'help' => false,

    'file' => null

], [

    'h' => 'help',

    'f' => 'file'

]);


if ($options['help'] || empty($options['file'])) {

    echo "\nScript pentru sincronizarea cohortelor cu cursurile și setarea rolului.\n";

    echo "\nUtilizare:\n";

    echo "php sync_cohorts.php --file=/cale/catre/cohorts.csv\n";

    echo "\nParametri:\n";

    echo "  --file, -f    Calea către fișierul CSV care conține cohortele, cursurile și rolul\n";

    echo "  --help, -h    Afișează acest mesaj de ajutor\n";

    exit(0);

}


// Verificare existență fișier CSV

$csvfile = $options['file'];

if (!file_exists($csvfile)) {

    cli_error("Fișierul CSV nu a fost găsit: {$csvfile}");

}


// Citire fișier CSV

if (($handle = fopen($csvfile, 'r')) !== false) {

    $header = fgetcsv($handle);


    if ($header === false || count($header) < 2) {

        cli_error("Fișierul CSV trebuie să conțină cel puțin două coloane: cohortid și courseid.");

    }


    $cohort_col = array_search('cohortid', $header);

    $course_col = array_search('courseid', $header);

    $role_col = array_search('role', $header);


    if ($cohort_col === false || $course_col === false) {

        cli_error("Fișierul CSV trebuie să conțină coloanele 'cohortid' și 'courseid'.");

    }


    while (($data = fgetcsv($handle)) !== false) {

        $cohortid = trim($data[$cohort_col]);

        $courseid = trim($data[$course_col]);

        $rolename = ($role_col !== false) ? trim($data[$role_col]) : 'student'; // Implicit student


        // Verificare existență cohortă

        $cohort = $DB->get_record('cohort', ['idnumber' => $cohortid], '*', IGNORE_MISSING);

        if (!$cohort) {

            cli_writeln("Cohorta cu ID-ul '{$cohortid}' nu a fost găsită.");

            continue;

        }


        // Verificare existență curs

        if (is_numeric($courseid)) {

            $course = $DB->get_record('course', ['id' => $courseid], '*', IGNORE_MISSING);

        } else {

            $course = $DB->get_record('course', ['shortname' => $courseid], '*', IGNORE_MISSING);

        }


        if (!$course) {

            cli_writeln("Cursul cu ID-ul sau numele scurt '{$courseid}' nu a fost găsit.");

            continue;

        }


        // Obține ID-ul rolului specificat

        $role = $DB->get_record('role', ['shortname' => $rolename], '*', IGNORE_MISSING);

        if (!$role) {

            cli_writeln("Rolul '{$rolename}' nu a fost găsit. Se utilizează rolul implicit 'student'.");

            $role = $DB->get_record('role', ['shortname' => 'student'], '*', IGNORE_MISSING);

        }

        if (!$role) {

            cli_error("Rolul 'student' nu a fost găsit în Moodle. Verifică lista de roluri disponibile.");

        }

        $roleid = $role->id;


        // Adaugă metoda de înscriere „Cohort Sync” dacă nu există

        $enrol = enrol_get_plugin('cohort');

        $instances = enrol_get_instances($course->id, true);

        $instance_exists = false;


        foreach ($instances as $instance) {

            if ($instance->enrol === 'cohort' && $instance->customint1 == $cohort->id) {

                // Actualizare rol dacă există deja

                if ($instance->roleid != $roleid) {

                    $DB->set_field('enrol', 'roleid', $roleid, ['id' => $instance->id]);

                    cli_writeln("Rolul pentru cohorta '{$cohortid}' în cursul '{$courseid}' a fost actualizat la '{$rolename}'.");

                }

                $instance_exists = true;

                break;

            }

        }


        if (!$instance_exists) {

            $instanceid = $enrol->add_instance($course, [

                'customint1' => $cohort->id,

                'roleid' => $roleid // Setează rolul selectat

            ]);

            cli_writeln("Cohorta '{$cohortid}' a fost sincronizată cu cursul '{$courseid}' și rolul '{$rolename}' (ID: {$roleid}).");

        }

    }


    fclose($handle);

} else {

    cli_error("Nu s-a putut deschide fișierul CSV: {$csvfile}");

}


cli_writeln("Sincronizarea cohortelor a fost finalizată.");

Cum să folosești noul script

  1. Creează un fișier CSV cu formatul:
cohortid,courseid,role
cohortA,course101,student
cohortB,course102,teacher

Rulează comanda:
Pentru că fisierul csv este făcut in windows, trebuie sa il formatam pentru unix
folosim 2 comenzi
sed -i '1s/^\xEF\xBB\xBF//' /home/moodle/csv/c2cs3.csv  
dos2unix /home/moodle/csv/c2cs3.csv 

Comanda de sincronizare este:
 php /home/moodle/public_html/moodle/admin/sync_cohorts.php --file=/home/moodle/csv/c2cs3.csv

Varianta 3
<?php
define('CLI_SCRIPT', true);
require_once('/home/moodle/public_html/moodle/config.php');
require_once($CFG->libdir . '/clilib.php');
require_once($CFG->dirroot . '/enrol/locallib.php');

list($options, $unrecognized) = cli_get_params([
    'help' => false,
    'file' => null
], [
    'h' => 'help',
    'f' => 'file'
]);

if ($options['help'] || empty($options['file'])) {
    echo "\nScript pentru sincronizarea cohortelor cu cursurile și atribuirea rolurilor.\n";
    echo "\nUtilizare:\n";
    echo "php sync_cohorts.php --file=/cale/catre/cohorts.csv\n";
    echo "\nStructura CSV:\n";
    echo "cohortid,courseid,role\n";
    exit(0);
}

$csvfile = $options['file'];
if (!file_exists($csvfile)) {
    cli_error("Fișierul CSV nu a fost găsit: {$csvfile}");
}

if (($handle = fopen($csvfile, 'r')) !== false) {
    $header = fgetcsv($handle);

    if ($header === false || count($header) < 3) {
        cli_error("Fișierul CSV trebuie să conțină cel puțin trei coloane: cohortid, courseid, role.");
    }

    $cohort_col = array_search('cohortid', $header);
    $course_col = array_search('courseid', $header);
    $role_col = array_search('role', $header);

    if ($cohort_col === false || $course_col === false || $role_col === false) {
        cli_error("Fișierul CSV trebuie să conțină coloanele 'cohortid', 'courseid' și 'role'.");
    }

    while (($data = fgetcsv($handle)) !== false) {
        $cohortid = trim($data[$cohort_col]);
        $courseid = trim($data[$course_col]);
        $rolename = trim($data[$role_col]);

        // Verificare cohortă
        $cohort = $DB->get_record('cohort', ['idnumber' => $cohortid], '*', IGNORE_MISSING);
        if (!$cohort) {
            cli_writeln("⚠ Cohorta '{$cohortid}' nu a fost găsită.");
            continue;
        }

        // Verificare curs
        if (is_numeric($courseid)) {
            $course = $DB->get_record('course', ['id' => $courseid], '*', IGNORE_MISSING);
        } else {
            $course = $DB->get_record('course', ['shortname' => $courseid], '*', IGNORE_MISSING);
        }

        if (!$course) {
            cli_writeln("⚠ Cursul '{$courseid}' nu a fost găsit.");
            continue;
        }

        // Verificare rol
        $role = $DB->get_record('role', ['shortname' => $rolename], '*', IGNORE_MISSING);
        if (!$role) {
            cli_writeln("⚠ Rolul '{$rolename}' nu a fost găsit.");
            continue;
        }

        // Obținere utilizatori cohortei
        $users = $DB->get_records('cohort_members', ['cohortid' => $cohort->id]);

        // Obținere context curs
        $context = context_course::instance($course->id);

        // Obținere metodă de înscriere 'cohort'
        $enrol = enrol_get_plugin('cohort');
        $instances = enrol_get_instances($course->id, true);
        $instance = null;

        foreach ($instances as $inst) {
            if ($inst->enrol === 'cohort' && $inst->customint1 == $cohort->id) {
                $instance = $inst;
                break;
            }
        }

        // Dacă nu există metoda de înscriere, o adăugăm
        if (!$instance) {
            $enrolid = $enrol->add_instance($course, ['customint1' => $cohort->id]);
            $instance = $DB->get_record('enrol', ['id' => $enrolid]);
            cli_writeln("- Cohorta '{$cohortid}' a fost sincronizată cu cursul '{$courseid}'.");
        } else {
            cli_writeln(" x Cohorta '{$cohortid}' era deja sincronizată cu cursul '{$courseid}'.");
        }

        // Înrolare utilizatori și atribuirea rolului
        foreach ($users as $user) {
            $userid = $user->userid;

            // Verificare dacă utilizatorul este deja înscris
            $exists = $DB->record_exists('user_enrolments', [
                'userid' => $userid,
                'enrolid' => $instance->id
            ]);

            if (!$exists) {
                // Înrolare utilizator
                $enrol->enrol_user($instance, $userid);
                cli_writeln("- Utilizatorul '{$userid}' a fost înscris în cursul '{$courseid}'.");
            }

            // Verificare dacă utilizatorul are deja rolul
            $role_assigned = $DB->record_exists('role_assignments', [
                'roleid' => $role->id,
                'userid' => $userid,
                'contextid' => $context->id
            ]);

            if (!$role_assigned) {
                // Atribuire rol utilizator
                $role_assignment = new stdClass();
                $role_assignment->roleid = $role->id;
                $role_assignment->contextid = $context->id;
                $role_assignment->userid = $userid;
                $role_assignment->timemodified = time();
                $DB->insert_record('role_assignments', $role_assignment);
                cli_writeln("- Utilizatorul '{$userid}' a primit rolul '{$rolename}' în cursul '{$courseid}'.");
            } else {
                cli_writeln("x Utilizatorul '{$userid}' are deja rolul '{$rolename}' în cursul '{$courseid}'.");
            }
        }
    }

    fclose($handle);
} else {
    cli_error("Eroare la deschiderea fișierului CSV: {$csvfile}");
}

cli_writeln("- Sincronizarea cohortelor și atribuirea rolurilor a fost finalizată.");

Rulează comanda:
Pentru că fisierul csv este făcut in windows, trebuie sa il formatam pentru unix
folosim 2 comenzi
sed -i '1s/^\xEF\xBB\xBF//' /home/moodle/csv/c2cs3.csv  
dos2unix /home/moodle/csv/c2cs3.csv 

Comanda de sincronizare este:
 php /home/moodle/public_html/moodle/admin/sync_cohorts.php --file=/home/moodle/csv/c2cs3.csv




vineri, 3 ianuarie 2025

Adaugare utilizatori in moodle folosind un script pyton

 Instalare Pyton

Scriptul este ăsta, se salveaza in folderul unde este fisierul excel ce contine in coloana A, numita Nume si prenume, numele complet al utilizatorului, cu litere mari, initiala tatalui prenumele si, in paranteze, unde este cazul, numele de dupa casatorie, iar in coloana b emailul. Scriptul adauga coloane pentru Nume, Prenume, username, scoate diacriticile.

Ce nu face, trebuie verificat si corectat, facut manual

1. Daca sunt doua nume, al doilea nume este scris cu litera mica, se corecteaza in fisierul final

2. Daca initiala tatalui contine diacritice, se corecteaza in fisierul initial

3. Daca initiala tatalui are doua initiale, se elimina una din ele in fisierul initial

4. Verifică spațiile dinaintea numelui

Se corecteaza fisierul de intrare, este la sfarsit: 

 Deschide fișierul Excel

input_file = "Seria2-G7.xlsx"

output_file = "tabel_procesat.xlsx"

Script pyton, salvat la mine ca procesare_tabel1.py

--------------------------------------

import openpyxl

import re

from unidecode import unidecode


# Funcție pentru a prelucra numele

def prelucrare_nume(nume):

    nume = re.sub(r"\s*[-–]\s*", "-", nume.strip())  # Normalizează separatorii între nume

    cuvinte = nume.split(" ")

    nume_final = "-".join([cuvant.capitalize() for cuvant in cuvinte if cuvant])

    return nume_final


# Funcție pentru a prelucra prenumele

def prelucrare_prenume(prenume):

    prenume = prelucrare_nume(prenume)

    prenume_list = prenume.split("-")

    

    # Capitalizează corect fiecare prenume

    prenume_list = [cuvant.capitalize() for cuvant in prenume_list]

    

    # Păstrează doar primele două prenume

    return "-".join(prenume_list[:2])


# Funcție pentru a genera username-ul

def genereaza_username(prenume, nume):

    prenume = unidecode(prenume.lower())

    nume = unidecode(nume.lower())

    return f"{prenume}.{nume}"


# Deschide fișierul Excel

input_file = "Seria2-G7.xlsx"

output_file = "tabel_procesat.xlsx"

wb = openpyxl.load_workbook(input_file)

sheet = wb.active


# Adaugă anteturile pentru noile coloane

sheet["C1"] = "Nume"

sheet["D1"] = "Prenume"

sheet["E1"] = "Username"


# Procesează fiecare rând

for row in sheet.iter_rows(min_row=2, max_row=sheet.max_row, min_col=1, max_col=1):

    celula_originala = row[0].value

    if celula_originala:

        # Extrage componentele din text

        pattern = r"^(.*?)(?:\s+[A-Z\.]+\s+)(.*?)(?:\s+\(.*?\))?$"

        match = re.match(pattern, celula_originala)

        if match:

            nume = prelucrare_nume(match.group(1))

            prenume = prelucrare_prenume(match.group(2))

            username = genereaza_username(prenume, nume)


            # Scrie datele în noile coloane

            sheet[f"C{row[0].row}"] = nume

            sheet[f"D{row[0].row}"] = prenume

            sheet[f"E{row[0].row}"] = username


# Salvează fișierul rezultat

wb.save(output_file)

print(f"Fișier procesat salvat ca {output_file}")