Hint: A new version which combines file upload and the copy & paste option can be found at the following post
http://www.phplist.com/forums/viewtopic.php?p=9961#9961
This is a solution to import without file uploading for the topic 'import emails with different values for attributes' in PHPlist 2.8.12.
This topic calls admin/import2.php. But the real code to be changed is found in admin/commonlib/pages/importcsv.php. The solution is also useable for older versions of PHP (tested with v4.1.2).
This kind of import is not straight forward because none existing import fields will interrupt the process and all email data as well as accompanying information has to be stored temporarily at some place. In the original version email data is stored in a temporary file, any other information (as the file name of the temporary file etc.) is stored in the persistent session array $_SESSION, which keeps accessible on subsequent page requests.
I have encountered some problems with this method but it is not clear what are the precise reasons. The problems result probably from the mix of the old version I have had to deal with, changing the folder for temporary files in 'config/config.php' and possibly from the well hated 'safe mode' of PHP.
Basically the changes to be made to paste the email data in a textarea field in the import form is the same as Mario A. Valdez-Ramirez did describe at the beginning of this topic. The difference is to keep the email data persistent for some time between page requests. I did this by storing the email data itself in the $_SESSION["import_file"] variable instead of the file name of the temporary file. In this way the changes to be made to the code keep minimal.
This did not need to much time. But to solve the other small problems did need a day of work. This includes a modification of the .htaccess file (as I can not change php.ini) which is necessary for older versions of PHP.
Modifications at public_html/lists/.htaccess
- Code: Select all
# 'php_value' is wrong for magic_quotes_gpc because it's a logical value.
# Instead php_flag has to be used. This may be necessary only with older
# versions of PHP. PHP 5.x seems to be more tolerant or ignore it.
# (see PHP manual, section 9. Runtime Configuration, Running PHP as an Apache module)
# php_value magic_quotes_gpc on
php_flag magic_quotes_gpc on
# If you have changed the folder for temporary files in config.php you may
# have to adjust the path for the session information too. This may be a
# problem of older versions of PHP (lower 4.3?).
# (see PHP manual, section Session Functions)
php_value session.save_path "/PathToYourHttpRootFolder/tmp"
# 'register_globals on' should be used with versions of PHP lower than 4.3,
# because PHPlist uses the $_SESSION array as well as the functions
# session_register(), session_is_registered() and session_unregister().
# (see PHP manual, section Session Functions)
php_flag register_globals on
# It is not possible to switch the safe_mode in .htaccess files.
# (see PHP manual, section 9. Runtime Configuration, Running PHP as an Apache module)
# php_admin_flag safe_mode off
Please insert the following comment at line 2 of admin/commonlib/pages/importcsv.php
- Code: Select all
### JT: Comment
# This file has been modified to import csv-address-data not with browser
# file upload from a loacal file but from an added <textarea> field in the
# HTML form of the import2 page. Simply paste the csv-file in the textarea
# field of your browser. Then continue as if you have set an upload file. I
# have tested it successfully with a file size of 142 KB / 1800 addresses.
# But I don't know the limitations in size of this upload method because the
# data has to be stored temporarily in a session variable of the global
# array $_SESSION. Normally the session array is stored as a file in the
# configured tmp/ folder of the server. Therefore size limitations should be
# rather high. But there may be other limitations.
#
# This is a convenient way to keep that data persistent for more than one
# page request without file uploads into the server file system. It is
# necessary because there may be new additional colums and the import process
# has to be interrupted. A page has to be shown where the user can assign the
# new fields to existing ones. After this the import of data has to be repeated
# and can be loaded from the session variable.
### /JT: Comment
At the beginning of the second PHP block (about line 27)
- Code: Select all
##### JT: Modified code part1 for import via <textarea> begins
# This should resolve a problem with older versions of PHP (lower than 4.3?).
session_start();
##### /JT: Modified code part1 for import via <textarea> ends
Then deactivate the first lines of function clearImport() (about line 43)
- Code: Select all
### JT: Deactivated original code part1
# if (is_file($_SESSION["import_file"])) {
# unlink($_SESSION["import_file"]);
# }
### /JT: Deactivated original code part1
Next is short after the beginning of "if(isset($_POST["import"])) { ..." (about line 84)
- Code: Select all
### JT: Deactivated original code part2
# if(!$_FILES["import_file"]) {
# Fatal_Error("File is either too large or does not exist.");
# return;
# }
# if(empty($_FILES["import_file"])) {
# Fatal_Error("No file was specified. Maybe the file is too big? ");
# return;
# }
# if (filesize($_FILES["import_file"]['tmp_name']) > 1000000) {
# # if we allow more, we will certainly run out of memory
# Fatal_Error("File too big, please split it up into smaller ones");
# return;
# }
# if( !preg_match("/^[0-9A-Za-z_\.\-\/\s \(\)]+$/", $_FILES["import_file"]["name"]) ) {
# Fatal_Error("Use of wrong characters in filename: ".$_FILES["import_file"]["name"]);
# return;
# }
### /JT: Deactivated original code part2
##### JT: Modified code part2 for import via <textarea> begins
if(!($_POST["import_elist"])) {
Fatal_Error("No list was specified.");
return;
}
##### /JT: Modified code part2 for import via <textarea> ends
Some lines further the third part of substitution (about line 108)
- Code: Select all
### JT: Deactivated original code part3
# if ($_FILES["import_file"] && $_FILES["import_file"]['size'] > 10) {
# $newfile = $GLOBALS['tmpdir'].'/'. $_FILES['import_file']['name'].time();
# move_uploaded_file($_FILES['import_file']['tmp_name'], $newfile);
# $_SESSION["import_file"] = $newfile;
# if( !($fp = fopen ($newfile, "r"))) {
# Fatal_Error("Cannot read ".$newfile." is not readable !");
# return;
# }
# fclose($fp);
# } elseif ($_FILES["import_file"]) {
# Fatal_Error("Something went wrong while uploading the file. Empty file received. Maybe the file is too big, or you have no permissions to read it.");
# return;
# }
### /JT: Deactivated original code part3
##### JT: Modified code part3 for import via <textarea> begins
# Set the import file name with the import data itself from the textarea field.
if (!$_SESSION["import_file"]) {
$_SESSION["import_file"] = $_POST["import_elist"];
}
##### /JT: Modified code part3 for import via <textarea> ends
Part 4 is the trick to reassign the email data from the session array to the processing variable short after "if ($_SESSION["import_file"]) { ...".
Since $_SESSION["import_file"] is always defined after the first initialisation this happens not only once, but several times during subsequent page requests. (about line 150)
- Code: Select all
### JT: Deactivated original code part4
# $fp = fopen ($_SESSION["import_file"], "r");
# $email_list = fread($fp, filesize ($_SESSION["import_file"]));
# fclose($fp);
### /JT: Deactivated original code part4
##### JT: Modified code part4 for <textarea> import begins
$email_list = $_SESSION["import_file"];
##### JT: Modified code part4 for <textarea> import ends
Part5 solves a problem in definition of the numbers of imported colums (about line 314)
- Code: Select all
### JT: Deactivated original code part5
# if (sizeof($values) != (sizeof($_SESSION["import_attribute"]) + sizeof($_SESSION["system_attributes"]))
# && $test_import && $_POST["show_warnings"])
# Warn("Record has more values than header indicated (".
# sizeof($values). "!=".
# (sizeof($_SESSION["import_attribute"]) + sizeof($_SESSION["system_attributes"]))
# ."), this may cause trouble: $index");
### /JT: Deactivated original code part5
##### JT: Modified code part5 for import via upload file begins
# The original comparison ignores that sizeof($values) also contains the field 'Email' which
# is not contained in 'import_attribute' and 'system_attributes'.
if ((sizeof($values)-1) != (sizeof($_SESSION["import_attribute"]) + sizeof($_SESSION["system_attributes"]))
&& $test_import && $_POST["show_warnings"])
Warn("Record has more values than header indicated (".
(sizeof($values)-1). "!=".
(sizeof($_SESSION["import_attribute"]) + sizeof($_SESSION["system_attributes"]))
."), this may cause trouble: $index");
##### /JT: Modified code part5 for import via upload file ends
At last part 6 is HTML code with fragments of PHP. It generates the textarea field in the HTML form for import (about line 680)
- Code: Select all
<!--
### JT: Deactivated original code part6
# <tr><td>File containing emails:<br/>
# </td><td><input type="file" name="import_file">
# <br/>The following limits are set by your server:<br/>
# Maximum size of a total data sent to server: <b><?=ini_get("post_max_size")?></b><br/>
# Maximum size of each individual file: <b><?=ini_get("upload_max_filesize")?></b>
# <br/>PHPlist will not process files larger that 1Mb
# </td></tr>
### /JT: Deactivated original code part6
-->
<!-- ##### JT: Modified code part6 for <textarea> import begins -->
<tr>
<td>List of emails:<br/></td>
<td>
The following limits are set by your server:<br/>
Maximum size of a total data sent to server: <b><?=ini_get("post_max_size")?></b><br/>
Maximum size of each individual file: <b><?=ini_get("upload_max_filesize")?></b><br/>
PHPlist will not process files larger that 1Mb
</td>
</tr>
<tr><td colspan="2"><textarea name="import_elist" rows="20" cols="80" wrap="off"></textarea></td></tr>
<!-- ##### JT: Modified code part6 for <textarea> import ends -->