Fix #1394 & Fix #1393 & Fix #1392 Import users trough CSV is broken

This commit is contained in:
Nicolas Le Goff
2013-08-05 14:20:54 +02:00
parent 2f864ca2e7
commit 4c59c755ff
4 changed files with 236 additions and 174 deletions

View File

@@ -576,32 +576,47 @@ class Users implements ControllerProviderInterface
})->bind('users_display_import_file'); })->bind('users_display_import_file');
$controllers->post('/import/file/', function(Application $app, Request $request) { $controllers->post('/import/file/', function(Application $app, Request $request) {
if ((null === $file = $request->files->get('files')) || !$file->isValid()) { if ((null === $file = $request->files->get('files')) || !$file->isValid()) {
return $app->redirectPath('users_display_import_file', array('error' => 'file-invalid')); return $app->redirectPath('users_display_import_file', array('error' => 'file-invalid'));
} }
$array = \format::csv_to_arr($file->getPathname()); $equivalenceToMysqlField = self::getEquivalenceToMysqlField();
$loginDefined = $pwdDefined = $mailDefined = false;
$equivalenceToMysqlField = Users::getEquivalenceToMysqlField();
$loginDefined = $pwdDefined = false;
$loginNew = array(); $loginNew = array();
$out = array('ignored_row' => array(), 'errors' => array()); $out = array(
'ignored_row' => array(),
'errors' => array()
);
$nbUsrToAdd = 0; $nbUsrToAdd = 0;
for ($j = 0; $j < sizeof($array[0]); $j++) { $lines = \format::csv_to_arr($file->getPathname());
$array[0][$j] = trim(mb_strtolower($array[0][$j]));
if (!isset($equivalenceToMysqlField[$array[0][$j]])) { $roughColumns = array_shift($lines);
$out['ignored_row'][] = $array[0][$j];
} else { $columnsSanitized = array_map(function($columnName) {
if (($equivalenceToMysqlField[$array[0][$j]]) == 'usr_login') { return trim(mb_strtolower($columnName));
}, $roughColumns);
$columns = array_filter($columnsSanitized, function ($columnName) use (&$out, $equivalenceToMysqlField) {
if (!isset($equivalenceToMysqlField[$columnName])) {
$out['ignored_row'][] = $columnName;
return false;
}
return true;
});
foreach($columns as $columnName) {
if ($equivalenceToMysqlField[$columnName] === 'usr_login') {
$loginDefined = true; $loginDefined = true;
} }
if (($equivalenceToMysqlField[$array[0][$j]]) == 'usr_password') { if (($equivalenceToMysqlField[$columnName]) === 'usr_password') {
$pwdDefined = true; $pwdDefined = true;
} }
if (($equivalenceToMysqlField[$columnName]) === 'usr_mail') {
$mailDefined = true;
} }
} }
@@ -613,72 +628,78 @@ class Users implements ControllerProviderInterface
return $app->redirectPath('users_display_import_file', array('error' => 'row-pwd')); return $app->redirectPath('users_display_import_file', array('error' => 'row-pwd'));
} }
$nbLines = sizeof($array); if (!$mailDefined) {
$nbCols = sizeof($array[0]); return $app->redirectPath('users_display_import_file', array('error' => 'row-mail'));
}
for ($i = 1; $i < $nbLines; $i++) { foreach ($lines as $nbLine => $line) {
$hasVerifLogin = false; $loginValid = false;
$hasVerifPwd = false; $pwdValid = false;
$mailValid = false;
for ($j = 0; $j < $nbCols; $j++) { foreach ($columns as $nbCol => $colName) {
$array[$i][$j] = trim($array[$i][$j]); if (!isset($equivalenceToMysqlField[$colName])) {
unset($lines[$nbCol]);
if (!isset($equivalenceToMysqlField[$array[0][$j]])) {
continue; continue;
} }
if (($equivalenceToMysqlField[$array[0][$j]]) == 'usr_login') { $sqlField = $equivalenceToMysqlField[$colName];
$loginToAdd = $array[$i][$j]; $value = $line[$nbCol];
if ($loginToAdd == "") { if ($sqlField === 'usr_login') {
$out['errors'][] = sprintf(_("Login line %d is empty"), $i); $loginToAdd = $value;
} elseif (isset($loginNew[$loginToAdd])) { if ($loginToAdd === "") {
$out['errors'][] = sprintf(_("Login line %d is empty"), $nbLine + 1);
} elseif (in_array($loginToAdd, $loginNew)) {
$out['errors'][] = sprintf(_("Login %s is already defined in the file at line %d"), $loginToAdd, $i); $out['errors'][] = sprintf(_("Login %s is already defined in the file at line %d"), $loginToAdd, $i);
} else { } else {
if (\User_Adapter::get_usr_id_from_login($app, $loginToAdd)) { if (\User_Adapter::get_usr_id_from_login($app, $loginToAdd)) {
$out['errors'][] = sprintf(_("Login %s already exists in database"), $loginToAdd); $out['errors'][] = sprintf(_("Login %s already exists in database"), $loginToAdd);
} else { } else {
$loginNew[$loginToAdd] = ($i + 1); $loginValid = true;
} }
} }
$hasVerifLogin = true;
} }
if (($equivalenceToMysqlField[$array[0][$j]]) == 'usr_password') { if ($loginValid && $sqlField === 'usr_mail') {
$passwordToVerif = $array[$i][$j]; $mailToAdd = $value;
if ($passwordToVerif == "") { if ($mailToAdd === "") {
$out['errors'][] = sprintf(_("Mail line %d is empty"), $nbLine + 1);
} else if (false !== \User_Adapter::get_usr_id_from_email($app, $mailToAdd)) {
$out['errors'][] = sprintf(_("Email '%s' for login '%s' already exists in database"), $mailToAdd, $loginToAdd);
} else {
$mailValid = true;
}
}
if ($sqlField === 'usr_password') {
$passwordToVerif = $value;
if ($passwordToVerif === "") {
$out['errors'][] = sprintf(_("Password is empty at line %d"), $i); $out['errors'][] = sprintf(_("Password is empty at line %d"), $i);
} else {
$pwdValid = true;
}
}
} }
$hasVerifPwd = true; if ($loginValid && $pwdValid && $mailValid) {
} $loginNew[] = $loginToAdd;
if ($hasVerifLogin && $hasVerifPwd) {
$j = $nbCols;
}
if (($j + 1) >= $nbCols) {
if (count($out['errors']) === 0) {
$nbUsrToAdd++; $nbUsrToAdd++;
} }
} }
}
}
if (count($out['errors']) > 0) { if (count($out['errors']) > 0 && $nbUsrToAdd === 0) {
return $app['twig']->render('admin/user/import/file.html.twig', array( return $app['twig']->render('admin/user/import/file.html.twig', array(
'errors' => $out['errors'] 'errors' => $out['errors']
)); ));
} elseif ($nbUsrToAdd === 0) {
return $app->redirectPath('users_display_import_file', array('error' => 'no-user'));
} else {
for ($i = 1; $i < sizeof($array); $i++) {
for ($j = 0; $j < sizeof($array[0]); $j++) { {
if ((isset($array[$i][$j]) && trim($array[$i][$j]) == "") || (!isset($equivalenceToMysqlField[$array[0][$j]])))
unset($array[$i][$j]);
}
} }
if ($nbUsrToAdd === 0) {
return $app->redirectPath('users_display_import_file', array(
'error' => 'no-user'
));
} }
$sql = " $sql = "
@@ -699,15 +720,20 @@ class Users implements ControllerProviderInterface
return $app['twig']->render('/admin/user/import/view.html.twig', array( return $app['twig']->render('/admin/user/import/view.html.twig', array(
'nb_user_to_add' => $nbUsrToAdd, 'nb_user_to_add' => $nbUsrToAdd,
'models' => $models, 'models' => $models,
'array_serialized' => serialize($array) 'lines_serialized' => serialize($lines),
'columns_serialized' => serialize($columns),
'errors' => $out['errors']
)); ));
}
})->bind('users_submit_import_file'); })->bind('users_submit_import_file');
$controllers->post('/import/', function(Application $app, Request $request) { $controllers->post('/import/', function(Application $app, Request $request) {
$nbCreation = 0; $nbCreation = 0;
if ((null === $serializedArray = $request->request->get('sr')) || ('' === $serializedArray)) { if ((null === $serializedColumns = $request->request->get('sr_columns')) || ('' === $serializedColumns)) {
$app->abort(400);
}
if ((null === $serializedLines = $request->request->get('sr_lines')) || ('' === $serializedLines)) {
$app->abort(400); $app->abort(400);
} }
@@ -715,27 +741,30 @@ class Users implements ControllerProviderInterface
$app->abort(400); $app->abort(400);
} }
$array = unserialize($serializedArray); $lines = unserialize($serializedLines);
$columns = unserialize($serializedColumns);
$nbLines = sizeof($array);
$nbCols = sizeof($array[0]);
$equivalenceToMysqlField = Users::getEquivalenceToMysqlField(); $equivalenceToMysqlField = Users::getEquivalenceToMysqlField();
for ($i = 1; $i < $nbLines; $i++) { foreach ($lines as $nbLine => $line) {
$curUser = null; $curUser = array();
for ($j = 0; $j < $nbCols; $j++) { foreach ($columns as $nbCol => $colName) {
if (!isset($equivalenceToMysqlField[$array[0][$j]])) if (!isset($equivalenceToMysqlField[$colName]) || !isset($line[$nbCol])) {
continue; continue;
if ($equivalenceToMysqlField[$array[0][$j]] == "usr_sexe" && isset($array[$i][$j])) { }
switch ($array[$i][$j]) {
$sqlField = $equivalenceToMysqlField[$colName];
$value = trim($line[$nbCol]);
if ($sqlField === "usr_sexe") {
switch ($value) {
case "Mlle": case "Mlle":
case "Mlle.": case "Mlle.":
case "mlle": case "mlle":
case "Miss": case "Miss":
case "miss": case "miss":
case "0": case "0":
$curUser[$equivalenceToMysqlField[$array[0][$j]]] = 0; $curUser[$sqlField] = 0;
break; break;
case "Mme": case "Mme":
@@ -743,7 +772,7 @@ class Users implements ControllerProviderInterface
case "Ms": case "Ms":
case "Ms.": case "Ms.":
case "1": case "1":
$curUser[$equivalenceToMysqlField[$array[0][$j]]] = 1; $curUser[$sqlField] = 1;
break; break;
case "M": case "M":
@@ -753,21 +782,19 @@ class Users implements ControllerProviderInterface
case "Monsieur": case "Monsieur":
case "Mister": case "Mister":
case "2": case "2":
$curUser[$equivalenceToMysqlField[$array[0][$j]]] = 2; $curUser[$sqlField] = 2;
break; break;
} }
} else { } else {
if (isset($array[$i][$j])) { $curUser[$sqlField] = $value;
$curUser[$equivalenceToMysqlField[$array[0][$j]]] = trim($array[$i][$j]);
}
}
} }
} }
if (isset($curUser['usr_login']) && trim($curUser['usr_login']) !== '' && isset($curUser['usr_password']) && trim($curUser['usr_password']) !== "") { if (isset($curUser['usr_login']) && trim($curUser['usr_login']) !== ''
$loginNotExist = !\User_Adapter::get_usr_id_from_login($app, $curUser['usr_login']); && isset($curUser['usr_password']) && trim($curUser['usr_password']) !== ''
&& isset($curUser['usr_mail']) && trim($curUser['usr_mail']) !== '') {
if ($loginNotExist) { if (false === \User_Adapter::get_usr_id_from_login($app, $curUser['usr_login'])
&& false === \User_Adapter::get_usr_id_from_email($app, $curUser['usr_mail'])) {
$NewUser = \User_Adapter::create($app, $curUser['usr_login'], $curUser['usr_password'], $curUser['usr_mail'], false); $NewUser = \User_Adapter::create($app, $curUser['usr_login'], $curUser['usr_password'], $curUser['usr_mail'], false);
if (isset($curUser['defaultftpdatasent'])) { if (isset($curUser['defaultftpdatasent'])) {
@@ -826,6 +853,7 @@ class Users implements ControllerProviderInterface
$nbCreation++; $nbCreation++;
} }
} }
}
return $app->redirectPath('admin_users_search', array('user-updated' => $nbCreation)); return $app->redirectPath('admin_users_search', array('user-updated' => $nbCreation));
})->bind('users_submit_import'); })->bind('users_submit_import');

View File

@@ -12,6 +12,8 @@
{% trans 'Row login is missing, script has stopped' %} {% trans 'Row login is missing, script has stopped' %}
{% elseif error == 'row-pwd' %} {% elseif error == 'row-pwd' %}
{% trans 'Row password is missing, script has stopped' %} {% trans 'Row password is missing, script has stopped' %}
{% elseif error == 'row-mail' %}
{% trans 'Row mail is missing, script has stopped' %}
{% elseif error == 'no-user' %} {% elseif error == 'no-user' %}
{% trans 'The file does not contains any user to add' %} {% trans 'The file does not contains any user to add' %}
{% endif %} {% endif %}

View File

@@ -1,22 +1,54 @@
{% if nb_user_to_add > 0 and models|length > 0%}
{# Display errors #}
{% if errors|length > 0 %}
<div class="well import-errors">
<h4 class="alert-heading">{% trans %}The following errors have been detected{% endtrans %}</h4>
<ul class="unstyled text-error">
{% for error in errors %}
<li>{{ error }}</li>
{% endfor%}
</ul>
{% trans %}Would you like to continue ?{% endtrans %}
<div>
<a href="#" class="no-ajax btn btn-primary accept-import">{% trans %}Yes{% endtrans %}</a>
<a href="{{ path('users_display_import_file') }}" target="right" class="btn">{% trans %}no{% endtrans %}</a>
</div>
</div>
<script type="text/javascript">
{# If the user agrees to continue despite errors, show wrapper #}
$("a.accept-import").bind("click", function(e) {
$(".import-errors").remove();
$(".wrapper").removeClass("hidden");
});
</script>
{% endif %}
{# Hide wrapper if there are errors #}
<div class="wrapper {% if errors|length > 0 %}hidden{% endif %}">
<div class="page-header"> <div class="page-header">
<h1>{% trans 'Apply a model' %} <small>({{ nb_user_to_add }} {% trans 'Users' %})</small></h1> <h1>{% trans 'Apply a model' %} <small>({{ nb_user_to_add }} {% trans 'Users' %})</small></h1>
</div> </div>
{% if nb_user_to_add > 0 and models|length > 0 %}
<form method="post" name="importform2" action="{{ path('users_submit_import') }}" ENCTYPE="multipart/form-data" > <form method="post" name="importform2" action="{{ path('users_submit_import') }}" ENCTYPE="multipart/form-data" >
<textarea style="display:none;" name="sr">{{ array_serialized }}</textarea> <textarea class="hidden" name="sr_lines">{{ lines_serialized }}</textarea>
<textarea class="hidden" name="sr_columns">{{ columns_serialized }}</textarea>
<select name="modelToApply"> <select name="modelToApply">
{% for model in models %} {% for model in models %}
<option value='{{ model['usr_id'] }}'>{{ model['usr_login'] }}</option> <option value='{{ model['usr_id'] }}'>{{ model['usr_login'] }}</option>
{% endfor %} {% endfor %}
</select> </select>
<div class="form-actions"> <div class="form-actions">
<button class="btn btn-primary" type="submit">Save changes</button> <button class="btn btn-primary" type="submit">{% trans %}Save changes{% endtrans %}</button>
<button class="btn">Cancel</button> <a href="{{ path('users_display_import_file') }}" target="right" class="btn">{% trans %}Cancel{% endtrans %}</a>
</div> </div>
</form> </form>
</div>
{% elseif models|length == 0 %} {% elseif models|length == 0 %}
<div class="alert alert-block"> <div class="alert alert-block">
{% trans 'You need define a model before importing a list of users' %} {% trans 'You need define a model before importing a list of users' %}
</div> </div>
{% elseif nb_user_to_add == 0 %}
<div class="alert alert-block">
{% trans 'There is no user to add.' %}
</div>
{% endif %} {% endif %}