Admin: Add CSV user import history - refs BT#18111

pull/3893/head
Yannick Warnier 5 years ago
parent 99fc25a09d
commit f330069ac8
  1. 126
      main/admin/download_import_users.php
  2. 184
      main/admin/user_import.php

@ -0,0 +1,126 @@
<?php
/* For licensing terms, see /license.txt */
/**
* This tool allows platform admins to check history by csv file.
*/
$cidReset = true;
require_once __DIR__.'/../inc/global.inc.php';
// Set this option to true to enforce strict purification for usernames.
$purification_option_for_usernames = false;
$userId = api_get_user_id();
api_protect_admin_script(true, null);
api_protect_limit_for_session_admin();
set_time_limit(0);
/**
* Read all the archive files previously placed in app/cache/backup/import_users/[user]/
* when users were imported through CSV (one can only see the users imported by
* oneself)
* @return array Array of archives found in the app/cache/backup
*/
function readImportedUsersArchives(string $path = '', string $parentFile = null, int $userId = 0): array
{
$data = [];
if (empty($path)) {
$path = api_get_path(SYS_ARCHIVE_PATH).'backup/import_users/'.api_get_user_id();
}
foreach (scandir($path) as $dir) {
// exclude ".", ".." and ".htaccess"
if (in_array($dir, ['.', '..', '.htaccess'])) {
continue;
}
$currentPath = $path.DIRECTORY_SEPARATOR.$dir;
if (is_dir($currentPath)) {
$data[$dir] = readImportedUsersArchives($currentPath, $dir, $userId);
} elseif (is_file($currentPath)) {
if (strpos($dir, '.csv') !== false) {
$data[$dir] = $currentPath;
if (empty($_GET['download'])) {
continue;
}
$filename = substr($_GET['download'], -strlen($dir));
$time = (string) (int) substr($_GET['download'], 0, -strlen($dir));
// Clean against hacks
if ($filename == $dir) {
if (!Security::check_abs_path($path.DIRECTORY_SEPARATOR.$filename, $path)) {
continue;
}
DocumentManager::file_send_for_download($currentPath, true, $time.'_'.$filename);
}
}
}
}
return $data;
}
/**
* Print an HTML table of archives of imported users
* @return string HTML table or empty string if no results
*/
function getImportedUsersArchivesTable(): string
{
$data = readImportedUsersArchives();
if (empty($data)) {
return '';
}
$table = new HTML_Table(['class' => 'table table-responsive']);
$headers = [
get_lang('SelectUser'),
get_lang('FieldTypeDatetime'),
get_lang('Files'),
];
$row = 0;
$column = 0;
foreach ($headers as $header) {
$table->setHeaderContents($row, $column, $header);
$column++;
}
$row++;
$userId = api_get_user_id();
$userInfo = api_get_user_info($userId);
foreach ($data as $date => $elements) {
$dateTime = DateTime::createFromFormat('YmdHis', $date)->format('Y-m-d H:i:s');
$files = '';
foreach ($elements as $fileName => $file) {
$files .= "<a href='".api_get_self().'?download='.$date.'_'.$fileName."'>".
Display::return_icon('down.png', get_lang('Down'), '', ICON_SIZE_SMALL).
" $fileName </a> <br>";
}
if (!empty($files)) {
$table->setCellContents($row, 0, $userInfo['complete_name']);
$table->setCellContents($row, 1, $dateTime);
$table->setCellContents($row, 2, $files);
$row++;
}
}
return $table->toHtml();
}
$this_section = SECTION_PLATFORM_ADMIN;
$defined_auth_sources[] = PLATFORM_AUTH_SOURCE;
if (isset($extAuthSource) && is_array($extAuthSource)) {
$defined_auth_sources = array_merge($defined_auth_sources, array_keys($extAuthSource));
}
$tool_name = get_lang('History');
$interbreadcrumb[] = ['url' => 'index.php', 'name' => get_lang('PlatformAdmin')];
$interbreadcrumb[] = ['url' => 'user_import.php', 'name' => get_lang('ImportUserListXMLCSV')];
$reloadImport = (isset($_REQUEST['reload_import']) && (int) $_REQUEST['reload_import'] === 1);
$extra_fields = UserManager::get_extra_fields(0, 0, 5, 'ASC', true);
$printTable = getImportedUsersArchivesTable();
Display::display_header($tool_name);
$form = new FormValidator('user_import', 'post', api_get_self());
$form->addHeader($tool_name);
$defaults['formSent'] = 1;
$form->addHtml($printTable);
$form->display();
Display::display_footer();

@ -4,6 +4,7 @@
use Chamilo\CoreBundle\Entity\ExtraFieldOptions;
use ChamiloSession as Session;
use Ddeboer\DataImport\Writer\CsvWriter;
/**
* This tool allows platform admins to add users by uploading a CSV or XML file.
@ -18,6 +19,45 @@ api_protect_admin_script(true, null);
api_protect_limit_for_session_admin();
set_time_limit(0);
/**
* Create directories and subdirectories for backup import csv data.
*
* @param null $path
*
* @return string|null
*/
function createDirectory($path = null)
{
if ($path == null) {
return $path;
}
$path = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $path);
$realPath = explode(DIRECTORY_SEPARATOR, $path);
$data = '';
foreach ($realPath as $pth) {
if (strlen($pth) > 0) {
$data .= DIRECTORY_SEPARATOR.$pth;
if (!is_dir($data)) {
mkdir($data, api_get_permissions_for_new_directories());
$block =
'<FilesMatch "\.(csv|xml)$">
Order allow,deny
Deny from all
</FilesMatch>
Options -Indexes';
$fp = fopen($data.'/.htaccess', 'w');
if ($fp) {
fwrite($fp, $block);
}
fclose($fp);
}
}
}
return $data;
}
/**
* @param array $users
* @param bool $checkUniqueEmail
@ -212,14 +252,24 @@ function complete_missing_data($user)
* @uses \global variable $inserted_in_course, which returns the list of
* courses the user was inserted in
*/
function save_data($users, $sendMail = false)
{
function save_data(
$users,
$sendMail = false,
$targetFolder = null
) {
global $inserted_in_course, $extra_fields;
// Not all scripts declare the $inserted_in_course array (although they should).
if (!isset($inserted_in_course)) {
$inserted_in_course = [];
}
if (!empty($targetFolder)) {
$userSaved = [];
$userError = [];
$userWarning = [];
}
$usergroup = new UserGroup();
if (is_array($users)) {
$efo = new ExtraFieldOption('user');
@ -228,6 +278,7 @@ function save_data($users, $sendMail = false)
foreach ($users as &$user) {
if ($user['has_error']) {
$userError[] = $user;
continue;
}
@ -320,16 +371,113 @@ function save_data($users, $sendMail = false)
UserManager::update_extra_field_value($user_id, $key, $value);
}
$userSaved[] = $user;
} else {
$returnMessage = Display::return_message(get_lang('Error'), 'warning');
$userWarning[] = $user;
}
$user['message'] = $returnMessage;
}
}
// Save with success, error and warning users
if (!empty($targetFolder)) {
$header = [
'id',
'FirstName',
'LastName',
'Status',
'Email',
'UserName',
'message',
];
// Save user with success
if (count($userSaved) != 0) {
$csv_content = [];
$csv_row = $header;
$csv_content[] = $csv_row;
foreach ($userSaved as $user) {
$csv_row = [];
$csv_row[] = isset($user['id']) ? $user['id'] : '';
$csv_row[] = isset($user['FirstName']) ? $user['FirstName'] : '';
$csv_row[] = isset($user['LastName']) ? $user['LastName'] : '';
$csv_row[] = isset($user['Status']) ? $user['Status'] : '';
$csv_row[] = isset($user['Email']) ? $user['Email'] : '';
$csv_row[] = isset($user['UserName']) ? $user['UserName'] : '';
$csv_row[] = isset($user['message']) ? strip_tags($user['message']) : '';
$csv_content[] = $csv_row;
}
saveCsvFile($csv_content, $targetFolder.'user_success_'.count($userSaved));
}
if (count($userError) != 0) {
// Save user with error
$csv_content = [];
$csv_row = $header;
$csv_content[] = $csv_row;
foreach ($userError as $user) {
$csv_row = [];
$csv_row[] = isset($user['id']) ? $user['id'] : '';
$csv_row[] = isset($user['FirstName']) ? $user['FirstName'] : '';
$csv_row[] = isset($user['LastName']) ? $user['LastName'] : '';
$csv_row[] = isset($user['Status']) ? $user['Status'] : '-';
$csv_row[] = isset($user['Email']) ? $user['Email'] : '';
$csv_row[] = isset($user['UserName']) ? $user['UserName'] : '';
$csv_row[] = isset($user['message']) ? strip_tags($user['message']) : '';
$csv_content[] = $csv_row;
error_log(print_r($csv_row, 1));
}
saveCsvFile($csv_content, $targetFolder.'user_error_'.count($userError));
}
if (count($userWarning) != 0) {
// Save user with warning
$csv_content = [];
$csv_row = $header;
$csv_content[] = $csv_row;
foreach ($userWarning as $user) {
$csv_row = [];
$csv_row[] = isset($user['id']) ? $user['id'] : '';
$csv_row[] = isset($user['FirstName']) ? $user['FirstName'] : '';
$csv_row[] = isset($user['LastName']) ? $user['LastName'] : '';
$csv_row[] = isset($user['Status']) ? $user['Status'] : '';
$csv_row[] = isset($user['Email']) ? $user['Email'] : '';
$csv_row[] = isset($user['UserName']) ? $user['UserName'] : '';
$csv_row[] = isset($user['message']) ? strip_tags($user['message']) : '';
$csv_content[] = $csv_row;
}
saveCsvFile($csv_content, $targetFolder.'user_warning_'.count($userWarning));
}
}
return $users;
}
/**
* Save array to a specific file.
*
* @param array $data
* @param $file
* @param string $enclosure
*/
function saveCsvFile($data = [], $file = 'example', $enclosure = '"')
{
$filePath = $file.'.csv';
$stream = fopen($filePath, 'w');
$writer = new CsvWriter(';', $enclosure, $stream, true);
$writer->prepare();
foreach ($data as $item) {
if (empty($item)) {
$writer->writeItem([]);
continue;
}
$item = array_map('trim', $item);
$writer->writeItem($item);
}
$writer->finish();
return null;
}
/**
* @param array $users
* @param string $fileName
@ -463,12 +611,13 @@ function parse_xml_data($file, $sendEmail = 0, $checkUniqueEmail = true)
}
/**
* @param array $users
* @param bool $sendMail
* @param array $users
* @param bool $sendMail
* @param string $targetFolder
*/
function processUsers(&$users, $sendMail)
function processUsers(&$users, $sendMail, $targetFolder = null)
{
$users = save_data($users, $sendMail);
$users = save_data($users, $sendMail, $targetFolder);
$warningMessage = '';
if (!empty($users)) {
@ -538,12 +687,26 @@ if (isset($_POST['formSent']) && $_POST['formSent'] && $_FILES['import_file']['s
$resume = isset($_POST['resume_import']) ? true : false;
$uploadInfo = pathinfo($_FILES['import_file']['name']);
$ext_import_file = $uploadInfo['extension'];
$targetFolder = null;
$users = [];
if (in_array($ext_import_file, $allowed_file_mimetype)) {
if (strcmp($file_type, 'csv') === 0 &&
$ext_import_file == $allowed_file_mimetype[0]
) {
$user = api_get_user_info();
$userId = (int) $user['id'];
$today = new DateTime();
$today = $today->format('YmdHis');
$targetFolder = api_get_configuration_value('root_sys').'app/cache/backup/import_users';
$targetFolder .= DIRECTORY_SEPARATOR.$userId.DIRECTORY_SEPARATOR.$today;
$targetFolder = createDirectory($targetFolder).DIRECTORY_SEPARATOR;
$originalFile = $targetFolder.$_FILES['import_file']['name'];
// save original file
if (!file_exists($originalFile)) {
touch($originalFile);
file_put_contents($originalFile, file_get_contents($_FILES['import_file']['tmp_name']));
}
Session::erase('user_import_data_'.$userId);
$users = Import::csvToArray($_FILES['import_file']['tmp_name']);
$users = parse_csv_data(
@ -565,7 +728,7 @@ if (isset($_POST['formSent']) && $_POST['formSent'] && $_FILES['import_file']['s
$error_kind_file = false;
}
processUsers($users, $sendMail);
processUsers($users, $sendMail, $targetFolder);
if ($error_kind_file) {
Display::addFlash(
@ -733,6 +896,10 @@ if (!empty($extraSettings) && isset($extraSettings['options']) &&
}
$form->setDefaults($defaults);
if (is_dir(api_get_path(SYS_ARCHIVE_PATH).'backup/import_users')) {
// only show if backup exist
$form->addHtml("<a href='./download_import_users.php'>".get_lang('ViewHistoryChange')."</a>");
}
$form->display();
if ($formContinue) {
@ -741,7 +908,6 @@ if ($formContinue) {
if ($reloadImport) {
echo '<script>
$(function() {
function reload() {
$("#user_import_continue").submit();

Loading…
Cancel
Save