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}")


marți, 10 septembrie 2024

Activare Win / Office

 

https://massgrave.dev/

Download / How to use it?​

  1. Open PowerShell (Not CMD). To do that, right-click on the Windows start menu and select PowerShell or Terminal.
  2. Copy and paste the code below and press enter
irm https://get.activated.win | iex
More options
  1. You will see the activation options. Choose [1] HWID for Windows activation. Choose [2] Ohook for Office activation.
  2. That's all

note
  • The IRM command in PowerShell downloads a script from a specified URL, and the IEX command executes it.
  • Always double-check the URL before executing the command and verify the source if manually downloading files.
  • Be cautious, as some spread malware disguised as MAS by using different URLs in the IRM command.

MAS Latest Release​

Last Release - v2.7 (6-Sep-2024)
GitHub / Bitbucket / Codeberg


Features​

  • HWID (Digital License) Method to Permanently Activate Windows
  • Ohook Method to Permanently Activate Office
  • KMS38 Method to Activate Windows/Server Till the Year 2038
  • Online KMS Method to Activate Windows/Server/Office For 180 Days (Lifetime With Renewal Task)
  • Advanced Activation Troubleshooting
  • $OEM$ Folders For Preactivation
  • Change Windows Edition
  • Change Office Edition
  • Check Windows/Office Activation Status
  • Available in All In One and Separate Files Versions
  • Fully Open Source and Based on Batch Scripts
  • Fewer Antivirus Detections

Activations Summary​

Activation TypeSupported ProductActivation PeriodIs Internet Needed?
HWIDWindows 10-11PermanentYes
OhookOfficePermanentNo
KMS38Windows 10-11-ServerTill the Year 2038No
Online KMSWindows / Office180 Days. Lifetime With Renewal TaskYes

For more details, use the respective activation details in Docs.
To activate unsupported products such as Office on Mac, check here.


luni, 12 februarie 2024

ejobs pe feaa

  <?php if ($this->countModules('ejobs')) { ?> 

        <div id="ejobs" class="clearfix">

        

          <div class="wrapper">

             

                <jdoc:include type="modules" name="ejobs" />

          

            </div>

        

        </div><!-- ejobs -->    

        <?php } ?>

in index.html din template

linia 283

marți, 30 ianuarie 2024

Mutare Bitspec j3 pe s132 si upgrade la J4

 i creez bitspec3 in s132. ownerul este 132.

2. Copiez kickstart si jpa in folder. Nu uit să modific userul din root in s132

3. pornesc restorele cu akeeba. versiunea initiala e php 7.4, dar merge

Atentie. Verifici ce versiune de php ai in virtualmin, daca este 8.x nu merge

4. Fisiere ce trebuie modificate: in htacces 

#Options +FollowSymlinks

Options +SymLinksifOwnerMatch

in configuration .php: 
public $cookie_domain = '.bitspec.com';

public $cookie_domain = 's132.central.ucv.ro';

5. restaurare database: modific user, parola si database name : bitspec_db1
6. copiezi .htacces si configuration.php pe site
7. mergi la Administrator, apoi la extensions -: manage, cauti jlms si le dezactivezi, dacă le găsesti
8. Mergi la Components - Joomla update
9. Updatezi la Joomla 3.10
10. In optiuni, modificam Update Channel din default in Jooomla Next si salvam
Updatam cu JA extension manager, daca nu merge in setari avem de reintrodus credentialele.
11. important - Opresti postfixul sau sistemul de email din joomla control panel, ca vrea sa trimită enailuri aiurea 
12. Instalezi versiuni noi pentru Payplans, Jomsocial, Joomlde, Easyblog, JCE, Akeeba,  Jspeed (ecentual astuia ii dai disable, daca nu il vede sistemul), RS firewall, Extly. Kunena nu merge decat 3.14, vom vedea daca il dezactivam sau nu
RS Form! pro
Paycart trebuie inlocuit cu payplans. Pentru asta, in modulul din frontpage se fac modificări.
Se creează planuri noi in payplans, se adauga in meniurile cursurilor, se actualizează modulul de voucers in module manager

13. Facem un akeeba update la acest punct
14. 
Pentru Kunena, NU se dezinstalează din Joomla, ca se pierde meniul, baza de date ramane, in J4 se va face o instalare noua a Kunena.
https://www.kunena.org/forum/general-questions-and-how-tos/164828-kunena-forum-package-not-compatible-with-joomla-3-to-joomla-4-upgrade
15. Se dezinstalează paycart,. Dezinstalezi Clickdesk, TCPPDF (e pentru Virtuemart), Xmap

Dezactivezi tot, iclusiv templateul Uber - facem default protostar
din table extensions and modules elimin câmpul extra_params, posibil să fi fost inserat de către Uber
Se dezinstalează RS Firewall, Payplans, Crisp - versiunea veche, restul se face disable, Jomsocial, Joomdle, Easyblog.
Perfect publisher se dezactivează, se dezactivează și pluginurile pentru easyblog, jomsocial, kunena
Se dezinstalează JCE, Foundry, RBSL Framework, JA Content Type, RSForm PDF, recaptcha, ARI tot ce gasim

Din baza de date se sterg in extensions PKG Joomla, JA facebook, rocksrocket
Se dezactivează JA google map, JA GDPR

Se face update.

Se instalează versiuni noi de Kunena - rescrie kunena, payplans, jomsocial, easyblog - ultimele 3 au si instalere RS forms instalează si se activează, joomdle, rs firewall, JCE și Akeeba. Se reface templateul default Uber Default

In kunena forum, la templates, - Aurelia, dai disable la boostrap.