From 3bde07d3897c280724e68ce962b7a34dd0830de9 Mon Sep 17 00:00:00 2001 From: Julian Egelstaff Date: Fri, 1 Nov 2024 22:55:28 -0400 Subject: [PATCH] Smart handling of new/updated entries when importing (#559) * Main updates to UI and to the handling of determining entry IDs and the insert/update behaviour * Fixing up detection of user names, etc * Instantiating some variables we need * handling linked checkboxes, and interpreting uitexts * Turning on Import Data button even when there's a relationship * Improving filename of blank template * Force tab char when generating templates, presuming Excel is the platform * Adding tip about importing only to the main form --- modules/formulize/include/entriesdisplay.php | 2 +- modules/formulize/include/functions.php | 26 +- modules/formulize/include/import.php | 439 ++++++++-------- .../formulize/include/import_functions.php | 484 +++++++++++------- modules/formulize/language/english/main.php | 30 +- modules/formulize/language/french/main.php | 8 +- modules/formulize/sql/mysql.sql | 8 - modules/formulize/xoops_version.php | 11 +- 8 files changed, 558 insertions(+), 450 deletions(-) diff --git a/modules/formulize/include/entriesdisplay.php b/modules/formulize/include/entriesdisplay.php index 461525c09..b0b88fdca 100644 --- a/modules/formulize/include/entriesdisplay.php +++ b/modules/formulize/include/entriesdisplay.php @@ -1343,7 +1343,7 @@ function drawInterface($settings, $fid, $frid, $groups, $mid, $gperm_handler, $l $screenButtonText['addProxyButton'] = ""; } $screenButtonText['exportButton'] = !$lockcontrols ? $screen->getVar('useexport') : ""; - $screenButtonText['importButton'] = ($import_data = $gperm_handler->checkRight("import_data", $fid, $groups, $mid) AND !$frid) ? $screen->getVar('useimport') : ""; + $screenButtonText['importButton'] = $import_data = $gperm_handler->checkRight("import_data", $fid, $groups, $mid) ? $screen->getVar('useimport') : ""; $screenButtonText['notifButton'] = $screen->getVar('usenotifications'); $screenButtonText['currentViewList'] = $screen->getVar('usecurrentviewlist'); $screenButtonText['saveButton'] = !$lockcontrols ? $screen->getVar('desavetext') : ""; diff --git a/modules/formulize/include/functions.php b/modules/formulize/include/functions.php index 840c54979..1ac52e8d2 100644 --- a/modules/formulize/include/functions.php +++ b/modules/formulize/include/functions.php @@ -1228,7 +1228,7 @@ function prepExport($headers, $cols, $data, $fdchoice, $custdel, $template, $fid $lineStarted = true; } else { if ($template == "update") { - $csvfile = "\"" . _formulize_DE_IMPORT_IDREQCOL . "\"$fd\"" . _formulize_DE_CALC_CREATOR . "\""; + $csvfile = "\"" . _formulize_ENTRY_ID . "\"$fd\"" . _formulize_DE_CALC_CREATOR . "\""; $lineStarted = true; } else { $csvfile = "\"" . _formulize_DE_CALC_CREATOR . "\""; @@ -1358,8 +1358,15 @@ function prepExport($headers, $cols, $data, $fdchoice, $custdel, $template, $fid // grab and output any secondary data for the last entry, if there was any $csvfile = prepExportSecondaryData($csvfile, $cols, $fd, $secondaryData); - $tempfold = microtime(true); - $exfilename = _formulize_DE_XF . $tempfold . $fxt; + $form_handler = xoops_getmodulehandler('forms','formulize'); + $formObject = $form_handler->get($fid); + if (is_object($formObject)) { + $formTitle = "'".str_replace(array(" ", "-", "/", "'", "`", "\\", ".", "?", ",", ")", "(", "[", "]"), "_", trans(undoAllHTMLChars($formObject->getVar('title'))))."'"; + } else { + $formTitle = "a_form"; + } + + $exfilename = _formulize_EXPORT_FILENAME_TEXT."_".$formTitle."_".date("M_j_Y_Hi").".csv"; // open the output file for writing $wpath = XOOPS_ROOT_PATH. SPREADSHEET_EXPORT_FOLDER . "$exfilename"; @@ -1369,15 +1376,7 @@ function prepExport($headers, $cols, $data, $fdchoice, $custdel, $template, $fid fclose($exportfile); // garbage collection. delete files older than 6 hours - formulize_scandirAndClean(XOOPS_ROOT_PATH . SPREADSHEET_EXPORT_FOLDER, _formulize_DE_XF); - - // write id_reqs and tempfold to the DB if we're making an update template - if ($template == "update") { - $sql = "INSERT INTO " . $xoopsDB->prefix("formulize_valid_imports") . " (file, id_reqs) VALUES (\"$tempfold\", \"" . serialize($id_req) . "\")"; - if (!$res = $xoopsDB->queryF($sql)) { - exit("Error: could not write import information to the database. SQL: $sql
".$xoopsDB->error()); - } - } + formulize_scandirAndClean(XOOPS_ROOT_PATH . SPREADSHEET_EXPORT_FOLDER, _formulize_EXPORT_FILENAME_TEXT); return XOOPS_URL . SPREADSHEET_EXPORT_FOLDER . "$exfilename"; } @@ -1410,7 +1409,8 @@ function prepareCellForSpreadsheetExport($column, $entry) { case 1: default: // Google wants a ' and Excel wants a tab...assume makecsv is going to be imported into Google, and otherwise we're downloading for Excel - default preference for handling strings in csv's, so they import without being mangled. Setting for no intro char may be useful when exporting to other programs that suck in raw data. - $exportIntroChar = strstr(getCurrentURL(),'makecsv') ? "'" : "\t"; + // Exception: if makecsv is called from the import.php popup, because we need to use it there to make a simple spreadsheet, that will probably be edited on a desktop with Excel + $exportIntroChar = (strstr(getCurrentURL(),'makecsv') AND !strstr($_SERVER['HTTP_REFERER'], '/modules/formulize/include/import.php')) ? "'" : "\t"; } } diff --git a/modules/formulize/include/import.php b/modules/formulize/include/import.php index d97788b2b..bef60334b 100644 --- a/modules/formulize/include/import.php +++ b/modules/formulize/include/import.php @@ -1,218 +1,221 @@ - ## -############################################################################### -## This program is free software; you can redistribute it and/or modify ## -## it under the terms of the GNU General Public License as published by ## -## the Free Software Foundation; either version 2 of the License, or ## -## (at your option) any later version. ## -## ## -## You may not change or alter any portion of this comment or credits ## -## of supporting developers from this source code or any supporting ## -## source code which is considered copyrighted (c) material of the ## -## original comment or credit authors. ## -## ## -## This program is distributed in the hope that it will be useful, ## -## but WITHOUT ANY WARRANTY; without even the implied warranty of ## -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## -## GNU General Public License for more details. ## -## ## -## You should have received a copy of the GNU General Public License ## -## along with this program; if not, write to the Free Software ## -## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## -############################################################################### -## Author of this file: Freeform Solutions ## -## Project: Formulize ## -############################################################################### - -// This file contains the logic for the import popup - -// The other popups like this are handled by the following files: -// changecols.php -// advsearch.php -// changescope.php -// pickcalcs.php -// save.php - -// all of those use javascript to communicate options back to the parent window that opened them. -// The import process probably does not need to communicate back to the parent window, but if so, -// consult those files to see how that has been done in the past. - -require_once "../../../mainfile.php"; - -require_once "import_functions.php"; - -global $xoopsConfig; -// load the formulize language constants if they haven't been loaded already -- also other language constants for user registration - if ( file_exists(XOOPS_ROOT_PATH."/modules/formulize/language/".$xoopsConfig['language']."/main.php") ) { - include_once XOOPS_ROOT_PATH."/modules/formulize/language/".$xoopsConfig['language']."/main.php"; - } else { - include_once XOOPS_ROOT_PATH."/modules/formulize/language/english/main.php"; - } - if ( file_exists(XOOPS_ROOT_PATH."/language/".$xoopsConfig['language']."/user.php") ) { - include_once XOOPS_ROOT_PATH."/language/".$xoopsConfig['language']."/user.php"; - } else { - include_once XOOPS_ROOT_PATH."/language/english/user.php"; - } - - - -global $xoopsDB, $xoopsUser; - -$config_handler =& xoops_gethandler('config'); -$confType = defined('XOOPS_CONF_USER') ? XOOPS_CONF_USER : ICMS_CONF_USER; -$xoopsConfigUser =& $config_handler->getConfigsByCat($confType); - - -include_once XOOPS_ROOT_PATH.'/modules/formulize/include/functions.php'; - - // Set some required variables - $mid = getFormulizeModId(); - $fid=""; - if(!$fid = $_GET['fid']) { - $fid = intval($_POST['fid']); - } - $frid = ""; - $frid = isset($_GET['frid']) ? intval($_GET['frid']) : ""; - $frid = isset($_POST['frid']) ? intval($_POST['frid']) : $frid; - /*if(!$frid = $_GET['frid']) { - $frid = $_POST['frid']; - }*/ - - $gperm_handler = &xoops_gethandler('groupperm'); - $member_handler =& xoops_gethandler('member'); - $groups = $xoopsUser ? $xoopsUser->getGroups() : array(0=>XOOPS_GROUP_ANONYMOUS); - $uid = $xoopsUser->getVar('uid'); - - // additional check to see if the user has import_data permission for this form - if(!$scheck = security_check($fid, "", $uid, "", $groups, $mid, $gperm_handler) OR !$import_data = $gperm_handler->checkRight("import_data", $fid, $groups, $mid)) { - print "

" . _NO_PERM . "

"; - exit; - } - - -// main body of page and logic goes here... - -// basic premise is that we have the $fid, and that is the form that we are importing data into. -// We need a browse box that the user can use to select the .csv they have prepared, and then when -// they click the submit button to upload that file, presto, the import process begins. If there -// are parse errors on the file, the import process communicates them. If the parse is successful, -// the import begins and the user gets a message, maybe a report of the number of records entered into -// the DB, or whatever seems appropriate. Then there is a button to close the window. - -// This popup window can be reloaded and receive form submissions in it just like any other window, of -// course. It's essentially a compartmentalized extension of the main "list of entries" UI. - - -print ""; -print ""; -print ""; -print "" . _formulize_DE_IMPORTDATA . "\n"; - -print "\n"; -$themecss = xoops_getcss(); -//$themecss = substr($themecss, 0, -6); -//$themecss .= ".css"; -print "\n"; - -print ""; -print "
"; -print "
"; - -print ""; - -define("IMPORT_WRITE", true); -define("IMPORT_DEBUG", false); - -//define("IMPORT_WRITE", false); -//define("IMPORT_DEBUG", true); - -$errors = array(); - -// get id of profile form -$module_handler =& xoops_gethandler('module'); -$formulizeModule =& $module_handler->getByDirname("formulize"); -$formulizeConfig =& $config_handler->getConfigsByCat(0, $formulizeModule->getVar('mid')); -$regfid = $formulizeConfig['profileForm']; - -// Test if the filename of the temporary uploaded csv is empty -//$csv_name = @$_POST["csv_name"]; -$csv_name = @$_FILES['csv_name']['tmp_name']; -if($csv_name != "") -{ - //$csv_name = "../import/$csv_name.csv"; - print "\n"; -} -elseif(!strstr(getCurrentURL(), 'dara.daniels')) -{ - -print "\n"; -print "\n"; -print "". -"\n"; - -} else { - print "\n"; -} - -print ""; -print "
"; -print "
"; -print ""; + ## +############################################################################### +## This program is free software; you can redistribute it and/or modify ## +## it under the terms of the GNU General Public License as published by ## +## the Free Software Foundation; either version 2 of the License, or ## +## (at your option) any later version. ## +## ## +## You may not change or alter any portion of this comment or credits ## +## of supporting developers from this source code or any supporting ## +## source code which is considered copyrighted (c) material of the ## +## original comment or credit authors. ## +## ## +## This program is distributed in the hope that it will be useful, ## +## but WITHOUT ANY WARRANTY; without even the implied warranty of ## +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## +## GNU General Public License for more details. ## +## ## +## You should have received a copy of the GNU General Public License ## +## along with this program; if not, write to the Free Software ## +## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## +############################################################################### +## Author of this file: Freeform Solutions ## +## Project: Formulize ## +############################################################################### + +// This file contains the logic for the import popup + +// The other popups like this are handled by the following files: +// changecols.php +// advsearch.php +// changescope.php +// pickcalcs.php +// save.php + +// all of those use javascript to communicate options back to the parent window that opened them. +// The import process probably does not need to communicate back to the parent window, but if so, +// consult those files to see how that has been done in the past. + +require_once "../../../mainfile.php"; + +require_once "import_functions.php"; + +global $xoopsConfig; +// load the formulize language constants if they haven't been loaded already -- also other language constants for user registration + if ( file_exists(XOOPS_ROOT_PATH."/modules/formulize/language/".$xoopsConfig['language']."/main.php") ) { + include_once XOOPS_ROOT_PATH."/modules/formulize/language/".$xoopsConfig['language']."/main.php"; + } else { + include_once XOOPS_ROOT_PATH."/modules/formulize/language/english/main.php"; + } + if ( file_exists(XOOPS_ROOT_PATH."/language/".$xoopsConfig['language']."/user.php") ) { + include_once XOOPS_ROOT_PATH."/language/".$xoopsConfig['language']."/user.php"; + } else { + include_once XOOPS_ROOT_PATH."/language/english/user.php"; + } + + + +global $xoopsDB, $xoopsUser; + +$config_handler =& xoops_gethandler('config'); +$confType = defined('XOOPS_CONF_USER') ? XOOPS_CONF_USER : ICMS_CONF_USER; +$xoopsConfigUser =& $config_handler->getConfigsByCat($confType); + + +include_once XOOPS_ROOT_PATH.'/modules/formulize/include/functions.php'; + + // Set some required variables + $mid = getFormulizeModId(); + $fid=""; + if(!$fid = $_GET['fid']) { + $fid = intval($_POST['fid']); + } + $frid = ""; + $frid = isset($_GET['frid']) ? intval($_GET['frid']) : ""; + $frid = isset($_POST['frid']) ? intval($_POST['frid']) : $frid; + /*if(!$frid = $_GET['frid']) { + $frid = $_POST['frid']; + }*/ + + $gperm_handler = &xoops_gethandler('groupperm'); + $member_handler =& xoops_gethandler('member'); + $groups = $xoopsUser ? $xoopsUser->getGroups() : array(0=>XOOPS_GROUP_ANONYMOUS); + $uid = $xoopsUser->getVar('uid'); + + // additional check to see if the user has import_data permission for this form + if(!$scheck = security_check($fid, "", $uid, "", $groups, $mid, $gperm_handler) OR !$import_data = $gperm_handler->checkRight("import_data", $fid, $groups, $mid)) { + print "

" . _NO_PERM . "

"; + exit; + } + + +// main body of page and logic goes here... + +// basic premise is that we have the $fid, and that is the form that we are importing data into. +// We need a browse box that the user can use to select the .csv they have prepared, and then when +// they click the submit button to upload that file, presto, the import process begins. If there +// are parse errors on the file, the import process communicates them. If the parse is successful, +// the import begins and the user gets a message, maybe a report of the number of records entered into +// the DB, or whatever seems appropriate. Then there is a button to close the window. + +// This popup window can be reloaded and receive form submissions in it just like any other window, of +// course. It's essentially a compartmentalized extension of the main "list of entries" UI. + + +print ""; +print ""; +print ""; +print "" . _formulize_DE_IMPORTDATA . "\n"; + +print "\n"; +$themecss = xoops_getcss(); +//$themecss = substr($themecss, 0, -6); +//$themecss .= ".css"; +print "\n"; + +print ""; +print "
"; +print "
"; + +print ""; + +define("IMPORT_WRITE", true); +define("IMPORT_DEBUG", false); + +//define("IMPORT_WRITE", false); +//define("IMPORT_DEBUG", true); + +$errors = array(); + +// get id of profile form +$module_handler =& xoops_gethandler('module'); +$formulizeModule =& $module_handler->getByDirname("formulize"); +$formulizeConfig =& $config_handler->getConfigsByCat(0, $formulizeModule->getVar('mid')); +$regfid = $formulizeConfig['profileForm']; + +// Test if the filename of the temporary uploaded csv is empty +//$csv_name = @$_POST["csv_name"]; +$csv_name = @$_FILES['csv_name']['tmp_name']; +if($csv_name != "") +{ + //$csv_name = "../import/$csv_name.csv"; + print "\n"; +} else { + + // provide a blank template, and a blank update template + // store the id_reqs and the filename in the DB for later reference in the case of the update template + + // determine if this is the profile form and if so, send special flag to template creation + + $cols1 = getAllColList($fid, "", $groups); + $cols = array('entry_id'); + foreach($cols1[$fid] as $col) { + $cols[] = $col['ele_id']; + } + $headers = getHeaders($cols, false); // false means we're sending element ids + $template = $regfid == $fid ? "blankprofile" : "blank"; + $blank_template = prepExport($headers, $cols, "", "comma", "", $template, $fid); + + $pkOptions = "\n"; + foreach($headers as $header) { + $pkOptions .= "\n"; + } + + print "\n"; + print "". + "\n"; + + print "\n"; + + +} + +print ""; +print "
"; +print "
+ + + + + +"; +print ""; diff --git a/modules/formulize/include/import_functions.php b/modules/formulize/include/import_functions.php index 707c2fed6..67dd6c1e0 100644 --- a/modules/formulize/include/import_functions.php +++ b/modules/formulize/include/import_functions.php @@ -38,41 +38,36 @@ // [4] (array) column headings to formulize form elements // [8] formulize form handle -//function importCsv(& $importSets, $id_reqs, $regfid) -function importCsv($csv_name, $id_reqs, $regfid, $validateOverride) { +function importCsv($csv_name, $regfid, $validateOverride, $pkColumn=false) { + global $errors; $importSet = array(); $importSet[] = $csv_name; - importCsvSetup($importSet, $id_reqs); // will be false on blank templates and user profile templates - - if ((is_array($id_reqs) AND !isset($importSet[7]['idreqs'])) OR ($regfid == $importSet[4] AND !is_array($id_reqs) AND (!isset($importSet[7]['username']) OR !isset($importSet[7]['fullname']) OR !isset($importSet[7]['password']) OR !isset($importSet[7]['email']) OR !isset($importSet[7]['regcode'])))) { - // necessary metadata columns not present in file - echo "
csv not imported!
Required metadata columns (ie: user who made entry, ID numbers, or account information) not present in the file."; - } else { - if (IMPORT_DEBUG) { - importCsvDebug($importSet); - } - - if (importCsvValidate($importSet, $id_reqs, $regfid, $validateOverride)) { - importCsvProcess($importSet, $id_reqs, $regfid, $validateOverride); - - echo "\n"; - } else { - echo "
csv not imported!"; - if (!empty($errors)) { - echo "
    "; - foreach ($errors as $error) { - echo $error; - } - echo "
"; - } - } - } // end of if metadata columns not present + importCsvSetup($importSet, $pkColumn); + + if (IMPORT_DEBUG) { + importCsvDebug($importSet); + } + + if (importCsvValidate($importSet, $regfid, $validateOverride)) { + importCsvProcess($importSet, $regfid, $validateOverride, $pkColumn); + + echo "\n"; + } else { + echo "
csv not imported!"; + if (!empty($errors)) { + echo "
    "; + foreach ($errors as $error) { + echo $error; + } + echo "
"; + } + } echo "** Finished

"; @@ -81,8 +76,9 @@ function importCsv($csv_name, $id_reqs, $regfid, $validateOverride) { } -function importCsvSetup(&$importSet, $id_reqs) { +function importCsvSetup(&$importSet, $pkColumn=false) { global $xoopsDB; + $pkColumn = $pkColumn ? $pkColumn : _formulize_ENTRY_ID; // First cell on the first line of the csv file contained the form name. // This is now provided through formulize variable $fid which is now the id, @@ -132,35 +128,32 @@ function importCsvSetup(&$importSet, $id_reqs) { $cell = $importSet[3][$column]; // need to record location of: _formulize_DE_CALC_CREATOR plus five user profile metadata fields, if they are necessary - if (!is_array($id_reqs)) { - // if we're dealing with a blank template... - if ($cell == _formulize_DE_CALC_CREATOR) { - $importSet[7]['creator'] = $column; - } - if ($cell == _formulize_DE_IMPORT_USERNAME) { - $importSet[7]['username'] = $column; - } - if ($cell == _formulize_DE_IMPORT_FULLNAME) { - $importSet[7]['fullname'] = $column; - } - if ($cell == _formulize_DE_IMPORT_PASSWORD) { - $importSet[7]['password'] = $column; - } - if ($cell == _formulize_DE_IMPORT_EMAIL) { - $importSet[7]['email'] = $column; - } - if ($cell == _formulize_DE_IMPORT_REGCODE) { - $importSet[7]['regcode'] = $column; - } - if ($cell == _formulize_DE_IMPORT_NEWENTRYID) { - // columns with this exact heading will have this entry id used - $importSet[7]['usethisentryid'] = $column; - } - } else { - if ($cell == _formulize_DE_IMPORT_IDREQCOL) { - $importSet[7]['idreqs'] = $column; - } - } + // if we're dealing with a blank template... + if ($cell == _formulize_DE_CALC_CREATOR) { + $importSet[7]['creator'] = $column; + } + if ($cell == _formulize_DE_IMPORT_USERNAME) { + $importSet[7]['username'] = $column; + } + if ($cell == _formulize_DE_IMPORT_FULLNAME) { + $importSet[7]['fullname'] = $column; + } + if ($cell == _formulize_DE_IMPORT_PASSWORD) { + $importSet[7]['password'] = $column; + } + if ($cell == _formulize_DE_IMPORT_EMAIL) { + $importSet[7]['email'] = $column; + } + if ($cell == _formulize_DE_IMPORT_REGCODE) { + $importSet[7]['regcode'] = $column; + } + if ($cell == _formulize_DE_IMPORT_NEWENTRYID) { + // columns with this exact heading will have this entry id used + $importSet[7]['usethisentryid'] = $column; + } + if ($cell == $pkColumn) { + $importSet[7]['idreqs'] = $column; + } $mapIndex = -1; @@ -176,6 +169,7 @@ function importCsvSetup(&$importSet, $id_reqs) { // links? switch($form_elementsq[$element]["ele_type"]) { case "select": + case "checkbox": $ele_value = unserialize($form_elementsq[$element]["ele_value"]); $options = $ele_value[2]; @@ -212,16 +206,16 @@ function importCsvSetup(&$importSet, $id_reqs) { } -function importCsvValidate(&$importSet, $id_reqs, $regfid, $validateOverride=false) { +function importCsvValidate(&$importSet, $regfid, $validateOverride=false) { if ($validateOverride) { return true; } $elementHandler = xoops_getmodulehandler('elements', 'formulize'); - global $errors, $xoopsDB; + global $errors, $xoopsDB, $fid, $xoopsUser; - $output = "** Validating
Csv: " . $importSet[0][0] . "
" . - "Form: name: " . $importSet[2] . - ", id: " . $importSet[4] . "
    "; + $output = "** Validating
    From csv file: " . $importSet[0][0] . "
    " . + "Into form: " . $importSet[2] . + " (id " . $importSet[4] . ")
      "; $links = count((array) $importSet[6]); $GLOBALS['formulize_ignoreColumnsOnImport'] = array(); @@ -238,7 +232,8 @@ function importCsvValidate(&$importSet, $id_reqs, $regfid, $validateOverride=fal || $importSet[3][$link] == _formulize_DE_IMPORT_EMAIL || $importSet[3][$link] == _formulize_DE_IMPORT_REGCODE || $importSet[3][$link] == _formulize_DE_IMPORT_IDREQCOL - || $importSet[3][$link] == _formulize_DE_IMPORT_NEWENTRYID)) + || $importSet[3][$link] == _formulize_DE_IMPORT_NEWENTRYID + || $importSet[3][$link] == _formulize_ENTRY_ID)) { print "

      Warning: column " . $importSet[3][$link] . " was not found in form.

      "; $GLOBALS['formulize_ignoreColumnsOnImport'][$link] = true; @@ -277,12 +272,10 @@ function importCsvValidate(&$importSet, $id_reqs, $regfid, $validateOverride=fal if ($importSet[6][$link] == -1) { // this is not a found column in the form // disallow profile metdata fields from being blank - if (!is_array($id_reqs) AND $importSet[4] == $regfid) { + if ($importSet[4] == $regfid) { if ($link == $importSet[7]['username'] OR $link == $importSet[7]['fullname'] OR $link == $row[$importSet[7]['password']] OR $link == $importSet[7]['email'] OR $link == $importSet[7]['regcode']) { $errors[] = "
    1. line " . $rowCount . ", column " . $importSet[3][$link] . ",
      Field cannot be blank
    2. "; } - } elseif (is_array($id_reqs) AND $link == $importSet[7]['idreqs']) { - $errors[] = "
    3. line " . $rowCount . ",
      No ID number specified
    4. "; } } @@ -307,7 +300,7 @@ function importCsvValidate(&$importSet, $id_reqs, $regfid, $validateOverride=fal } // check validity of account creation stuff - if (!is_array($id_reqs) AND $importSet[4] == $regfid) { + if ($importSet[4] == $regfid) { include_once XOOPS_ROOT_PATH . "/modules/reg_codes/include/functions.php"; $stop = userCheck($row[$importSet[7]['username']], $row[$importSet[7]['email']], $row[$importSet[7]['password']], $row[$importSet[7]['password']], $row[$importSet[7]['regcode']]); if ($stop) { @@ -315,19 +308,30 @@ function importCsvValidate(&$importSet, $id_reqs, $regfid, $validateOverride=fal } } - // check validity of the idreqs - if (is_array($id_reqs) AND $link == $importSet[7]['idreqs']) { - if (!in_array($cell_value, $id_reqs)) { - $errors[] = "
    5. line " . $rowCount . ",
      Invalid ID number specified
    6. "; - } - } - // check validity of entry ids if a special entry_ids column is included // store the entry ids that are specified, and then we'll check for the existence of any of them after we're done looping if (isset($importSet[7]['usethisentryid']) AND $link == $importSet[7]['usethisentryid']) { $useTheseEntryIds[] = $cell_value; } + + // check validity of the idreqs + if ($link == $importSet[7]['idreqs'] AND $cell_value) { + if(formulizePermHandler::user_can_edit_entry($fid, ($xoopsUser ? $xoopsUser->getVar('uid') : 0), $cell_value) === false) { + $errors[] = "
    7. line " . $rowCount . ",
      Invalid entry identifier specified. You do not have permission to modify the entry.
    8. "; + } + } + } else { + + // check validity of the idreqs + if ($link == $importSet[7]['idreqs'] AND $cell_value) { + if($entryId = getImportEntryIdFromPkColumnValue($cell_value, $element)) { + if(formulizePermHandler::user_can_edit_entry($fid, ($xoopsUser ? $xoopsUser->getVar('uid') : 0), $entryId) === false) { + $errors[] = "
    9. line " . $rowCount . ",
      Invalid entry identifier specified. You do not have permission to modify the entry.
    10. "; + } + } + } + // check columns from form switch($element["ele_type"]) { case "select": @@ -432,11 +436,11 @@ function importCsvValidate(&$importSet, $id_reqs, $regfid, $validateOverride=fal if ($ele_value[1]) { // Multiple options $options = $ele_value[2]; + $uiTexts = unserialize($element["ele_uitext"]); $items = explode("\n", $cell_value); foreach ($items as $item) { $item_value = trim($item); - - if (!in_array($item_value, (array)$options, true)) { + if (!in_array($item_value, (array)$options, true) AND !in_array($item_value, (array)$uiTexts, true)) { // last option causes strict matching by type $foundit = false; foreach ($options as $thisoption=>$default_value) { @@ -461,7 +465,8 @@ function importCsvValidate(&$importSet, $id_reqs, $regfid, $validateOverride=fal } else { // Single option $options = $ele_value[2]; - if (!in_array($cell_value, (array)$options, true)) { + $uiTexts = unserialize($element["ele_uitext"]); + if (!in_array(trim($cell_value), (array)$options, true) AND !in_array(trim($cell_value), (array)$uiTexts, true)) { // last option causes strict matching by type // then do a check against the translated options foreach ($options as $thisoption=>$default_value) { @@ -485,41 +490,78 @@ function importCsvValidate(&$importSet, $id_reqs, $regfid, $validateOverride=fal case "checkbox": - $options = unserialize($element["ele_value"]); - $options = $options[2]; - if(strstr($cell_value, "\n")) { - $items = explode("\n", $cell_value); - } else { - $items = explode(",", $cell_value); - } - foreach ($items as $item) { - $item_value = trim($item); - if (!in_array($item_value, (array)$options, true)) { - // last option causes strict matching by type - $foundit = false; - $hasother = false; - foreach ($options as $thisoption=>$default_value) { - if (trim($item_value) == trim(trans($thisoption))) { - $foundit = true; - } - if (preg_match('/\{OTHER\|+[0-9]+\}/', $thisoption)) { - $hasother = true; - } - } - if (!$foundit AND !$hasother) { - $keys_output = implode(', ', array_keys((array)$options)); - $errors[] = "
    11. line " . $rowCount . - ", column " . $importSet[3][$link] . - ",
      found: " . $item_value . - ", was expecting: { " . $keys_output . " }
    12. "; - } - } - } + + $ele_value = unserialize($element["ele_value"]); + if (isset($importSet[5][1][$link]) AND !strstr($cell_value, ",") AND (!is_numeric($cell_value) OR $cell_value < 10000000)) + { + // Linked element, but allow entries with commas to pass through unvalidated, and also allow through numeric values with no commas, if they are really big (assumption is big numbers are some kind of special entry_id reference, as in the case of UofT) + $linkElement = $importSet[5][1][$link]; + + if (!$ele_value['snapshot']) { + $items = explode("\n", $cell_value); + list($all_valid_options, $all_valid_options_ids) = getElementOptions($linkElement[2]['ele_handle'], $linkElement[2]['id_form']); + foreach ($items as $item) + { + $item_value = trim($item); + + if (!in_array($item_value, $all_valid_options)) { + $foundit = false; + foreach ($all_valid_options as $thisoption) { + if (trim($item_value) == stripslashes(trim(trans($thisoption)))) { // stripslashes is necessary only because the data contains slashes in the database (which it should not, so this should be removed when that is fixed) + $foundit = true; + break; + } + } + if (!$foundit) { + $some_options = array_slice($all_valid_options, 0, 20); + $errors[] = "
    13. line " . $rowCount . + ", column " . $importSet[3][$link] . + ",
      found: " . $item_value . + ", was expecting values such as: " . + stripslashes(implode(", ", $some_options)) . "
    14. "; + } + } + } + } + } else { + $options = unserialize($element["ele_value"]); + $uiTexts = unserialize($element["ele_uitext"]); + $options = $options[2]; + if(strstr($cell_value, "\n")) { + $items = explode("\n", $cell_value); + } else { + $items = explode(",", $cell_value); + } + foreach ($items as $item) { + $item_value = trim($item); + if (!in_array($item_value, (array)$options, true) AND !in_array($item_value, (array)$uiTexts, true)) { + // last option causes strict matching by type + $foundit = false; + $hasother = false; + foreach ($options as $thisoption=>$default_value) { + if (trim($item_value) == trim(trans($thisoption))) { + $foundit = true; + } + if (preg_match('/\{OTHER\|+[0-9]+\}/', $thisoption)) { + $hasother = true; + } + } + if (!$foundit AND !$hasother) { + $keys_output = implode(', ', array_keys((array)$options)); + $errors[] = "
    15. line " . $rowCount . + ", column " . $importSet[3][$link] . + ",
      found: " . $item_value . + ", was expecting: { " . $keys_output . " }
    16. "; + } + } + } + } break; case "radio": $options = unserialize($element["ele_value"]); - if (!in_array($cell_value, (array)$options, true)) { + $uiTexts = unserialize($element["ele_uitext"]); + if (!in_array(trim($cell_value), (array)$options, true) AND !in_array(trim($cell_value), (array)$uiTexts, true)) { // last option causes strict matching by type // then do a check against the translated options $foundit = false; @@ -602,9 +644,11 @@ function importCsvValidate(&$importSet, $id_reqs, $regfid, $validateOverride=fal } -function importCsvProcess(& $importSet, $id_reqs, $regfid, $validateOverride) { - global $xoopsDB, $xoopsUser, $xoopsConfig, $myts; // $xoopsDB is required by q +function importCsvProcess(& $importSet, $regfid, $validateOverride, $pkColumn=false) { + global $xoopsDB, $xoopsUser, $xoopsConfig, $myts, $fid; $elementHandler = xoops_getmodulehandler('elements', 'formulize'); + $gperm_handler = xoops_gethandler('groupperm'); + $userHasImportPermission = $gperm_handler->checkRight("import_data", $fid, ($xoopsUser ? $xoopsUser->getGroups() : array(XOOPS_GROUP_ANONYMOUS)), getFormulizeModId()); if (!$myts) { $myts =& MyTextSanitizer::getInstance(); } @@ -664,6 +708,7 @@ function importCsvProcess(& $importSet, $id_reqs, $regfid, $validateOverride) { $other_values = array(); $usersMap = array(); $entriesMap = array(); + $newEntriesMap = array(); $notEntriesList = array(); while (!feof($importSet[1])) { $row = fgetcsv($importSet[1], 99999); @@ -671,9 +716,13 @@ function importCsvProcess(& $importSet, $id_reqs, $regfid, $validateOverride) { if (is_array($row) AND count((array) $row) > 1) { $rowCount++; $this_id_req = ""; - if (is_array($id_reqs)) { // get the id_req if necessary. will happen regardless of position of idreq column - $this_id_req = $row[$importSet[7]['idreqs']]; - } + if(isset($importSet[7]['idreqs'])) { + if(!$pkColumn OR $pkColumn == _formulize_ENTRY_ID OR (isset($_POST['usePkColumnAsEntryId']) AND $_POST['usePkColumnAsEntryId'])) { + $this_id_req = $row[$importSet[7]['idreqs']]; + } elseif($pkColumn) { + $this_id_req = getImportEntryIdFromPkColumnValue($row[$importSet[7]['idreqs']], $importSet[5][0][$importSet[6][$importSet[7]['idreqs']]]); + } + } $links = count((array) $importSet[6]); for ($link = 0; $link < $links; $link++) { @@ -702,7 +751,7 @@ function importCsvProcess(& $importSet, $id_reqs, $regfid, $validateOverride) { // if this is the registration form, and we're making new entries, then handle the creation of the necessary user account // need to get the five userprofile fields from the form, $importSet[7] contains the keys for them -- email, username, fullname, password, regcode - if ($regfid == $importSet[4] AND !is_array($id_reqs)) { + if ($regfid == $importSet[4]) { $up_regcode = $row[$importSet[7]['regcode']]; $up_username = $row[$importSet[7]['username']]; $up_fullname = $row[$importSet[7]['fullname']]; @@ -848,13 +897,16 @@ function importCsvProcess(& $importSet, $id_reqs, $regfid, $validateOverride) { // Multiple options $element_value = ""; $options = $ele_value[2]; + $uiTexts = unserialize($element["ele_uitext"]); $items = explode("\n", $row_value); foreach ($items as $item) { $item_value = trim($item); - if (!in_array($item_value, (array)$options, true)) { + if(in_array($item_value, (array)$uiTexts, true)) { + $item_value = array_search($item_value, $uiTexts, true); + } elseif (!in_array($item_value, (array)$options, true)) { // last option causes strict matching by type foreach ($options as $thisoption=>$default_value) { - if (trim($item_value) == trim(trans($thisoption))) { + if ($item_value == trim(trans($thisoption))) { $item_value = $thisoption; break; } @@ -866,14 +918,17 @@ function importCsvProcess(& $importSet, $id_reqs, $regfid, $validateOverride) { } else { // Single option $options = $ele_value[2]; - if (!in_array($row_value, (array)$options, true)) { - // last option causes strict matching by type - foreach ($options as $thisoption=>$default_value) { - if (trim($row_value) == trim(trans($thisoption))) { - $row_value = $thisoption; - break; - } - } + $uiTexts = unserialize($element["ele_uitext"]); + if(in_array(trim($row_value), (array)$uiTexts, true)) { + $row_value = array_search(trim($row_value), $uiTexts, true); + } elseif (!in_array(trim($row_value), (array)$options, true)) { + // last option causes strict matching by type + foreach ($options as $thisoption=>$default_value) { + if (trim($row_value) == trim(trans($thisoption))) { + $row_value = $thisoption; + break; + } + } } } } elseif (strstr($row_value, ",") OR (is_numeric($row_value) AND $row_value > 10000000)) { @@ -889,51 +944,94 @@ function importCsvProcess(& $importSet, $id_reqs, $regfid, $validateOverride) { case "checkbox": - $options = unserialize($element["ele_value"]); - $element_value = ""; - $options = $options[2]; - if(strstr($row_value, "\n")) { - $items = explode("\n", $row_value); - } else { - $items = explode(",", $row_value); - } - foreach ($items as $item) { - $item_value = trim($item); - if (!in_array($item_value, (array)$options, true)) { - // last option causes strict matching by type - $foundit = false; - $hasother = false; - foreach ($options as $thisoption=>$default_value) { - if (trim($item_value) == trim(trans($thisoption))) { - $item_value = $thisoption; - $foundit = true; - } - if (preg_match('/\{OTHER\|+[0-9]+\}/', $thisoption)) { - $hasother = $thisoption; - } - if($foundit AND $hasother) { break; } // no need to keep looking for stuff - } - if ($foundit) { - $element_value .= "*=+*:" . $item_value; - } elseif ($hasother) { - $other_values[] = "INSERT INTO " . $xoopsDB->prefix("formulize_other") . " (id_req, ele_id, other_text) VALUES (\"$max_id_req\", \"" . $element["ele_id"] . "\", \"" . $myts->htmlSpecialChars(trim($item_value)) . "\")"; - $element_value .= "*=+*:" . $hasother; - } elseif (!$validateOverride) { - print "ERROR: INVALID TEXT FOUND FOR A CHECKBOX ITEM -- $item_value -- IN ROW:
      "; - print_r($row); - print "

      "; - } - } else { - $element_value .= "*=+*:" . $item_value; - } - } - $row_value = $element_value; + $ele_value = unserialize($element["ele_value"]); + if ($importSet[5][1][$link] AND !strstr($row_value, ",") + AND (!is_numeric($row_value) OR $row_value < 10000000)) + { + // Linked element + $linkElement = $importSet[5][1][$link]; + $ele_value = unserialize($element["ele_value"]); + list($all_valid_options, $all_valid_options_ids) = getElementOptions($linkElement[2]['ele_handle'], $linkElement[2]['id_form']); + if (!$ele_value['snapshot']) { + // Multiple options + $element_value = $linkElement[0] . "#*=:*" . + $linkElement[1] . "#*=:*"; + $items = explode("\n", $row_value); + if($ele_value['snapshot']) { + $row_value = ''; + if(count((array) $items)>1) { + $row_value .= '*=+*:'; + } + $row_value .= implode('*=+*:',$items); + } else { + $row_value = ","; + foreach ($items as $item) { + $item_value = trim($item); + if ($optionIndex = array_search($item_value, $all_valid_options)) { + $ele_id = $all_valid_options_ids[$optionIndex]; + } else { + foreach ($all_valid_options as $optionIndex=>$thisoption) { + if (trim($item_value) == trim(trans($thisoption))) { + $item_value = $thisoption; + $ele_id = $all_valid_options_ids[$optionIndex]; + break; + } + } + } + $row_value .= $ele_id . ","; + } + } + } + } else { + $options = unserialize($element["ele_value"]); + $uiTexts = unserialize($element["ele_uitext"]); + $element_value = ""; + $options = $options[2]; + if(strstr($row_value, "\n")) { + $items = explode("\n", $row_value); + } else { + $items = explode(",", $row_value); + } + foreach ($items as $item) { + $item_value = trim($item); + if (!in_array($item_value, (array)$options, true)) { + // last option causes strict matching by type + $foundit = false; + $hasother = false; + foreach ($options as $thisoption=>$default_value) { + if ($item_value == trim(trans($thisoption))) { + $item_value = $thisoption; + $foundit = true; + } + if (preg_match('/\{OTHER\|+[0-9]+\}/', $thisoption)) { + $hasother = $thisoption; + } + if($foundit AND $hasother) { break; } // no need to keep looking for stuff + } + if ($foundit) { + $element_value .= "*=+*:" . $item_value; + } elseif(in_array($item_value, (array)$uiTexts, true)) { + $element_value .= "*=+*:" . array_search($item_value, $uiTexts, true); + } elseif ($hasother) { + $other_values[] = "INSERT INTO " . $xoopsDB->prefix("formulize_other") . " (id_req, ele_id, other_text) VALUES (\"$max_id_req\", \"" . $element["ele_id"] . "\", \"" . $myts->htmlSpecialChars(trim($item_value)) . "\")"; + $element_value .= "*=+*:" . $hasother; + } elseif (!$validateOverride) { + print "ERROR: INVALID TEXT FOUND FOR A CHECKBOX ITEM -- $item_value -- IN ROW:
      "; + print_r($row); + print "

      "; + } + } else { + $element_value .= "*=+*:" . $item_value; + } + } + $row_value = $element_value; + } break; - - case "radio": + case "radio": $options = unserialize($element["ele_value"]); - if (!in_array($row_value, (array)$options, true)) { + $uiTexts = unserialize($element["ele_uitext"]); + if (!in_array(trim($row_value), (array)$options, true)) { // last option causes strict matching by type $foundit = false; $hasother = false; @@ -947,7 +1045,9 @@ function importCsvProcess(& $importSet, $id_reqs, $regfid, $validateOverride) { $hasother = $thisoption; } } - if (!$foundit AND $hasother) { + if(!$foundit AND in_array(trim($row_value), (array)$uiTexts, true)) { + $row_value = array_search(trim($row_value), $uiTexts, true); + } elseif (!$foundit AND $hasother) { $other_values[] = "INSERT INTO " . $xoopsDB->prefix("formulize_other") . " (id_req, ele_id, other_text) VALUES (\"$max_id_req\", \"" . $element["ele_id"] . "\", \"" . $myts->htmlSpecialChars(trim($row_value)) . "\")"; $row_value = $hasother; } elseif (!$foundit AND !$validateOverride) { @@ -992,7 +1092,9 @@ function importCsvProcess(& $importSet, $id_reqs, $regfid, $validateOverride) { } // end of looping through $links (columns?) // now that we've recorded all the values, do the actual updating/inserting of this record - if ($this_id_req) { + // WRITING DATA COULD/SHOULD BE DONE WITH DATA HANDLER CLASS writeEntry METHOD!? -- THAT WOULD INVOKE ON BEFORE SAVE AND ON AFTER SAVE PROPERLY, STANDARDIZE EVERYTHING, ETC + // AND DATA IS ALREADY IN DATABASE READY FORMAT NOW, SO JUST USE THE fieldValues ARRAY? BUT DOING SO AND TESTING IS BEYOND THE SCOPE OF CURRENT WORK + if ($data_handler->entryExists($this_id_req) AND $userHasImportPermission AND formulizePermHandler::user_can_edit_entry($fid, ($xoopsUser ? $xoopsUser->getVar('uid') : 0), $this_id_req)) { // first, record a revisions if necessary formulize_updateRevisionData($formObject, $this_id_req, true); @@ -1019,8 +1121,9 @@ function importCsvProcess(& $importSet, $id_reqs, $regfid, $validateOverride) { $entriesMap[] = $this_id_req; $notEntriesList['update_entry'][$importSet[4]][] = $this_id_req; // log the notification info } - } else { + } elseif($userHasImportPermission) { // inserting a new entry + $newEntryId = intval($this_id_req); $fields = ""; $values = ""; $element_handler = xoops_getmodulehandler('elements', 'formulize'); @@ -1038,7 +1141,7 @@ function importCsvProcess(& $importSet, $id_reqs, $regfid, $validateOverride) { } $entryIdFieldText = $newEntryId ? "entry_id, " : ""; - $newEntryId .= $newEntryId ? ", " : ""; + $newEntryId = $newEntryId ? $newEntryId.", " : ""; $insertElement = "INSERT INTO " . $xoopsDB->prefix("formulize_".$importSet[8])." (".$entryIdFieldText."creation_datetime, mod_datetime, creation_uid, mod_uid".$fields.") VALUES (".$newEntryId."NOW(), NOW(), '" . intval($form_uid) . "', '" . intval($form_proxyid)."'".$values.")"; if (IMPORT_WRITE) { @@ -1057,6 +1160,7 @@ function importCsvProcess(& $importSet, $id_reqs, $regfid, $validateOverride) { $usersMap[] = $form_uid; $insertedId = $xoopsDB->getInsertId(); $entriesMap[] = $insertedId; + $newEntriesMap[] = $insertedId; $notEntriesList['new_entry'][$importSet[4]][] = $insertedId; // log the notification info } } else { @@ -1073,7 +1177,7 @@ function importCsvProcess(& $importSet, $id_reqs, $regfid, $validateOverride) { // if new entries were created... include_once XOOPS_ROOT_PATH . "/modules/formulize/class/data.php"; $data_handler = new formulizeDataHandler($id_form); - if (!$groupResult = $data_handler->setEntryOwnerGroups($usersMap, $entriesMap)) { + if (!$groupResult = $data_handler->setEntryOwnerGroups($usersMap, $newEntriesMap)) { print "ERROR: failed to write the entry ownership information to the database.
      ".$xoopsDB->error()."
      "; } } @@ -1143,23 +1247,34 @@ function getElementOptions($ele_handle, $fid) { } -// THERE IS A BUG HERE WHICH CAUSES IT NOT TO COME UP WITH THE RIGHT ID WHEN PASSED A FULL NAME??? function getUserID($stringName) { global $xoopsDB, $xoopsUser; - $sql = "SELECT uid FROM " . $xoopsDB->prefix("users") . - " WHERE uname='" . formulize_db_escape(str_replace("'","'",$stringName)) . "'"; + // if no valid name passed in, return current user's id + if(!$stringName OR (!is_numeric($stringName) AND trim($stringName) == "")) { + return $xoopsUser->getVar('uid'); + } + + // if passed a number, return that + if (is_numeric($stringName)) { + return $stringName; + } + // try to look up user by full name + $sql = "SELECT uid FROM " . $xoopsDB->prefix("users") . + " WHERE uname='" . formulize_db_escape($stringName) . "'"; $result = $xoopsDB->query($sql); if ($xoopsDB->getRowsNum($result) > 0) { $item = $xoopsDB->fetchArray($result); if (@$item["uid"]) { return $item["uid"]; } + + // try to lookup by login name } else { // or, if no username match found, get the first matching full name -- added June 29, 2006 $sql = "SELECT uid FROM " . $xoopsDB->prefix("users") . - " WHERE name='" . formulize_db_escape($stringName) . "'"; + " WHERE login_name='" . formulize_db_escape($stringName) . "'"; if ($result = $xoopsDB->query($sql)) { $item = $xoopsDB->fetchArray($result); @@ -1169,11 +1284,7 @@ function getUserID($stringName) { } } - if (is_numeric($stringName)) { - return $stringName; - } - - // instead of returning 0, return the current user's ID -- added June 29, 2006 + // instead of returning nothing, return the current user's ID -- added June 29, 2006 return $xoopsUser->getVar('uid'); } @@ -1291,3 +1402,10 @@ function importCsvDebug(& $importSet) { echo $output . ""; } + +function getImportEntryIdFromPkColumnValue($value, $element) { + if($value==="") { return ""; } + $handle = $element['ele_handle']; + $data_handler = new formulizeDataHandler($element["id_form"]); + return $data_handler->findFirstEntryWithValue($handle, $value); +} diff --git a/modules/formulize/language/english/main.php b/modules/formulize/language/english/main.php index d2df3e6c5..b6abb6949 100644 --- a/modules/formulize/language/english/main.php +++ b/modules/formulize/language/english/main.php @@ -1,5 +1,6 @@ Open the file you downloaded in a spreadsheet program, like Excel, and modify it so it contains the data you want to upload. You don't have to do this right now, you can modify the file and come back later to upload it.

      -

      When you save the file, make sure you save it in .csv format. If you save it in a different format, like .xls, then the import process won't work!

      "); +

      When you save the file, make sure you save it in .csv format. If you save it in a different format, like .xls, then the import process won't work!

      + +

      You can only import data to the main form, not any subforms or other connected forms. To import data to a connected form, you need to use a screen that is based on that form. You should import data to the primary form first, so that when you import data into other forms, they can link to the entries you have already imported. ie: Import the 'Countries' data first, then import the 'Cities.' That way, if the City form contains a link to its Country entry, the Country data will already be in place.

      +"); define("_formulize_DE_IMPORT_INSTNEWPROFILE","

      If you are creating new entries in the user profile form, you must include a unique username, a full name, a password, a unique e-mail address and a valid registration code for each entry. A new user account will be created for each entry, based on the information you provide.

      "); -define("_formulize_DE_IMPORT_INSTUPDATE", "

      If you are updating existing entries, do not change or remove the '_1148849956' part of the file name! Do not add any other '_' characters either. Also, do not alter the ID numbers in each row of the file. All that information uniquely identifies the entries associated with each row.

      +define("_formulize_DE_IMPORT_INSTUPDATE", "

      To update existing entries, make sure you leave the values in the '"._formulize_ENTRY_ID."' column unchanged, because that is how Formulize can tell which entry you are editing. You can also choose to use a different column to identify the entries, as long as it has a unique value for every entry (such as a student number, employee number, etc).

      -

      Every row in the spreadsheet (after the headings) represents one entry in the form. So if you want to import three entries, then you need to have three rows of data in the spreadsheet. The order of the rows does not matter. If you are updating entries and you delete rows from the spreadsheet, that will not delete those entries from the database.

      +

      Every row in the spreadsheet (after the headings) represents one entry in the form. So if you want to import three entries, then you need to have three rows of data in the spreadsheet. The order of the rows does not matter. If you download a spreadsheet with all your data, and you delete rows from the spreadsheet and then upload it, that will not delete those entries from the database. That will simply update the entries that you did include in the spreadsheet.

      If a question has a choice of answers, the information in your spreadsheet must match exactly with the options in the form. This includes spelling, capitalization and spacing. Some questions in some forms allow you to select more than one answer; for instance, a series of checkboxes. To include multiple answers in your spreadsheet, each answer must be in the same cell with a line break between them. In Excel, press ALT-Enter after each answer to add a line break.

      "); define("_formulize_DE_IMPORT_NEWENTRYID", "Use this entry id"); -define("_formulize_DE_IMPORT_INSTNEW", "

      If you are creating new entries, then the column called \"" . _formulize_DE_CALC_CREATOR . "\" can have the username or full name of the person who should be recorded as the entry's creator. If you leave that column blank, then you will be recorded as the creator. If you are updating existing entries, then this column is ignored.

      If you are creating new entries, and you want to override the primary key that the database gives to each entry, then you can include a column called \"" . _formulize_DE_IMPORT_NEWENTRYID . "\" and put the entry ids you want to use in that column. If you don't understand what this means, then simply don't add this column to your spreadsheet.

      "); +define("_formulize_DE_IMPORT_INSTNEW", "

      If you are creating new entries, then the column called '" . _formulize_DE_CALC_CREATOR . "' can have the username or full name of the person who should be recorded as the entry's creator. If you leave that column blank, then you will be recorded as the creator. If you are updating existing entries, then this column is ignored.

      "); define("_formulize_DE_IMPORT_BACK", "Go Back"); -define("_formulize_DE_IMPORT_EITHEROR", "You can either add new entries to a form, or update existing entries. You cannot do both at once."); define("_formulize_DE_IMPORT_OR", "OR"); -define("_formulize_DE_IMPORT_BLANK", "If you want to add new entries to this form..."); -define("_formulize_DE_IMPORT_BLANK2", "Right-click here and save the necessary template."); -define("_formulize_DE_IMPORT_DATATEMP", "If you want to update entries in this form..."); -define("_formulize_DE_IMPORT_DATATEMP2", "Click here to get a template with your entries in it."); +define("_formulize_DE_IMPORT_BLANK2", "Blank for making new entries"); +define("_formulize_DE_IMPORT_DATATEMP2", "With data for editing entries"); define("_formulize_DE_IMPORT_DATATEMP3", "Templates always include all columns regardless of what columns are currently selected. Templates only include the rows (entries) that are currently visible. To include all entries, turn off all searches and other filters."); define("_formulize_DE_IMPORT_DATATEMP4", "After you have downloaded the template, and made your changes,"); define("_formulize_DE_IMPORT_DATATEMP5", "go back to the import page and upload your template."); @@ -762,8 +764,6 @@ define("_formulize_CLOSE_FORM_ELEMENT", "You need to close the form element that is open first before you edit this one"); -define("_formulize_ENTRY_ID", "Entry ID"); - define("_formulize_FROM", "From:"); define("_formulize_TO", "To:"); diff --git a/modules/formulize/language/french/main.php b/modules/formulize/language/french/main.php index 691fc1516..61445233e 100644 --- a/modules/formulize/language/french/main.php +++ b/modules/formulize/language/french/main.php @@ -313,17 +313,13 @@ define("_formulize_DE_IMPORT_FULLNAME", "Nom complet"); define("_formulize_DE_IMPORT_GO", "Unvoyer"); define("_formulize_DE_IMPORT_IDREQCOL", "ID number of this entry (do NOT remove or modify this column)"); -define("_formulize_DE_IMPORT_INSTNEW", "

      If you are creating new entries, then the column called \"" . _formulize_DE_CALC_CREATOR . "\" can have the username or full name of the person who should be recorded as the entry's creator. If you leave that column blank, then you will be recorded as the creator. If you are updating existing entries, then this column is ignored.

      "); -define("_formulize_DE_IMPORT_INSTNEWPROFILE","

      If you are creating new entries in the user profile form, you must include a unique username, a full name, a password, a unique e-mail address and a valid registration code for each entry. A new user account will be created for each entry, based on the information you provide.

      "); -define("_formulize_DE_IMPORT_INSTRUCTIONS", "

      Open the file you downloaded in a spreadsheet program, like Excel, and modify it so it contains the data you want to upload. You don't have to do this right now, you can modify the file and come back later to upload it.

      When you save the file, make sure you save it in .csv format. If you save it in a different format, like .xls, then the import process won't work!

      "); -define("_formulize_DE_IMPORT_INSTUPDATE", "

      If you are updating existing entries, do not change or remove the '_1148849956' part of the file name! Do not add any other '_' characters either. Also, do not alter the ID numbers in each row of the file. All that information uniquely identifies the entries associated with each row.

      Every row in the spreadsheet (after the headings) represents one entry in the form. So if you want to import three entries, then you need to have three rows of data in the spreadsheet. The order of the rows does not matter. If you are updating entries and you delete rows from the spreadsheet, that will not delete those entries from the database.

      If a question has a choice of answers, the information in your spreadsheet must match exactly with the options in the form. This includes spelling, capitalization and spacing. Some questions in some forms allow you to select more than one answer; for instance, a series of checkboxes. To include multiple answers in your spreadsheet, each answer must be in the same cell with a line break between them. In Excel, press ALT-Enter after each answer to add a line break.

      "); define("_formulize_DE_IMPORT_OR", "OR"); define("_formulize_DE_IMPORT_PASSWORD", "Mot de passe"); define("_formulize_DE_IMPORT_REGCODE", "Registration Code"); define("_formulize_DE_IMPORT_RESULTS", "Resultats..."); define("_formulize_DE_IMPORT_STEP1", "Etape 1: télécharger un fichier blanc ou avec des données"); -define("_formulize_DE_IMPORT_STEP2", "Etape 2: modifier le fichier téléchargé"); -define("_formulize_DE_IMPORT_STEP3", "Etape 3: envoyer le fichier modifié"); +define("_formulize_DE_IMPORT_STEP2", ""); +define("_formulize_DE_IMPORT_STEP3", "Etape 2: envoyer le fichier modifié"); define("_formulize_DE_IMPORT_USERNAME", "Nom d'utilisateur"); define("_formulize_DE_IMPORT_VALIDATEDATA", "Faire une validation automatique de la structure et des données dans le fichier .csv avant l'import actuel (vraiment recommandé!)"); define("_formulize_DE_IMPORTDATA", "Importer les entrées"); diff --git a/modules/formulize/sql/mysql.sql b/modules/formulize/sql/mysql.sql index 43b89d9ad..c1a785493 100755 --- a/modules/formulize/sql/mysql.sql +++ b/modules/formulize/sql/mysql.sql @@ -270,14 +270,6 @@ CREATE TABLE `formulize_screen` ( ) ENGINE=InnoDB; -CREATE TABLE formulize_valid_imports ( - import_id smallint(5) NOT NULL auto_increment, - file varchar(255) NOT NULL default '', - id_reqs text NOT NULL, - fid int(5), - PRIMARY KEY (`import_id`) -) ENGINE=InnoDB; - CREATE TABLE formulize_notification_conditions ( not_cons_id smallint(5) NOT NULL auto_increment, not_cons_fid smallint(5) NOT NULL default 0, diff --git a/modules/formulize/xoops_version.php b/modules/formulize/xoops_version.php index 4b528ebaf..f24c64217 100644 --- a/modules/formulize/xoops_version.php +++ b/modules/formulize/xoops_version.php @@ -67,7 +67,7 @@ "formulize_screen_multipage", "formulize_screen_listofentries", "formulize_screen_template", - "formulize_screen_calendar", + "formulize_screen_calendar", "formulize_entry_owner_groups", "formulize_application_form_link", "formulize_applications", @@ -78,11 +78,11 @@ "formulize_procedure_logs", "formulize_procedure_logs_params", "formulize_deletion_logs", - "formulize_apikeys", + "formulize_apikeys", "formulize_tokens", - "formulize_digest_data", - "formulize_passcodes", - "tfa_codes" + "formulize_digest_data", + "formulize_passcodes", + "tfa_codes" ); $modversion['formulize_exportable_tables'] = array( @@ -238,7 +238,6 @@ ) ) ), - "formulize_valid_imports" => array(), "formulize_screen" => array( "fields" => array("title", "type"), "joins" => array(