FINAL suepr merge step : added all modules to this super repos

This commit is contained in:
Bachir Soussi Chiadmi
2015-04-19 16:46:59 +02:00
7585 changed files with 1723356 additions and 18 deletions

View File

@@ -0,0 +1,44 @@
Overview
========
Import users into Drupal from a csv file (comma separated file).
See files in user_import/supported/ for examples of the API in use.
hook_user_import_form_field_match()
===========================================
Add options to list of Drupal fields to match against column of data being imported.
hook_user_import_form_update_user()
===========================================
Add options to the import settings form.
hook_user_import_data()
===========================================
Manipulate imported data before creating or amending user accounts.
hook_user_import_after_save()
===========================================
Take action(s) after each user account is created or amended.
hook_user_import_imported()
===========================================
Take action(s) after import is complete.
hook_field_user_import_supported_alter(&$supported)
===========================================
Alter array of supported field types, allowing for adding custom field
processors. Example:
MODULE_field_user_import_supported_alter(&$supported) {
$supported['MODULE'] = array(
'validate' => 'MODULE_user_import_field_validator',
'save' => 'MODULE_user_import_field_processor',
);
}

View File

@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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.
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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@@ -0,0 +1,214 @@
********************************************************************
D R U P A L M O D U L E
********************************************************************
Name: User Import Module
Author: Robert Castelo <www.codepositive.com>
Drupal: 7.x
********************************************************************
DESCRIPTION:
Import users into Drupal from a CSV file (Comma Separated File).
Features include:
* Creates an account for each user
* Match CSV columns to profile fields.
* Can optionally use the file's first row to map csv data to user profile fields
* Option to create Usernames based on data from file, e.g. "John" + "Smith" => "JohnSmith"
* Usernames can be made of abbreviated data from file, e.g. "Jane" + "Doe" => "JDoe"
* Option to create random, human readable, Usernames
* Option to import passwords
* Option to create random passwords for each user
* Can set user roles
* Option to send welcome email, with account details to each new user
* Can set each user's contact form to enabled
* Test mode option to check for errors
* Processing can be triggered by cron or manually by an administrator
* Can stagger number of users imported, so that not too many emails are sent at one time
* Multiple files can be imported/tested at the same time
* Import into Organic Groups
* Import into Node Profile
* Option to make new accounts immediately active, or inactive until user logs in
* Use CSV file already uploaded through FTP (useful for large imports)
* Designed to be massively scalable
** Supported CSV File Formats **
The following settings are necessary when saving a csv file which will be used for the import.
File needs to be saved as "Character Set: Unicode (UTF-8)".
Field delimiter: ,
- can be configured as something else, a comma is the default though.
Text delimiter: "
- if there's an option to quote all text cells, enable it.
The 'Windows line endings' setting complies with all of the above.
If file import fails with "File copy failed: source file does not exist." try
setting the file extension to .txt.
** IMPORTANT **
- Note that Date fields are not yet supported.
- Note that passwords can only be imported as plain text, and will be converted to MD5 by Drupal.
- Note that if your data contains a backslash before the column separator it may not get imported as expected:
"123","abc\","def"
The second field will be imported as: abc","def
This has been fixed in PHP 5.3
********************************************************************
PREREQUISITES:
Must have customised Profile fields already entered
if data is to be imported into user profiles.
********************************************************************
INSTALLATION:
Note: It is assumed that you have Drupal up and running. Be sure to
check the Drupal web site if you need assistance.
1. Place the entire user_import directory into your Drupal directory:
sites/all/modules/
2. Enable the user_import modules by navigating to:
administer > modules
Click the 'Save configuration' button at the bottom to commit your
changes.
3. IMPORTANT - Navigate to:
admin/config/media/file-system
Set the 'Private file system path' field.
********************************************************************
CONFIGURATION:
Configuration for User Import:
'People'
-- 'Import'
-- 'Configure' (admin/people/user_import/configure)
* Uploads Directory
This option provides a directory where files can be uploaded, and then selected when setting up
an import. The uploads directory will be in your Private files directory:
[path to private files]/user_import/uploads/selectable
* Automated Imports
If this is set then each import template will have the option to create a matching directory which
will be scanned for any files that have been uploaded to it, and when a file is found it will
automatically be used to create new user accounts. Directories are scanned during cron runs.
Scanned directories will be in:
[path to private files]/user_import/uploads/[name of directory]
********************************************************************
USAGE
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
For more detailed instructions (with pictures) please go to the
documentation pages for this module:
http://drupal.org/node/137653
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1. To set permissions of who can import users into the site, navigate to:
'People'
-- 'Permissions'
-- 'User Import'
-- 'Import users' (admin/people/permissions)
2. To import users, navigate to:
'People'
-- 'Import'
-- 'New Import' (admin/people/user_import/add)
* Note that Drupal may require its caches to be flushed before the User Import menu options appear
3. Press the 'browse' button to select a file to import,
or select a file already added through FTP.
5. Click on Next.
6. Use the "Use Different CSV File" fieldset to remove and add a different CSV file
7. Under Field Match you should see the various columns from your profile page.
8. For each csv column select a Drupal field to map.
9. Under username select 'No', if the field is not to be used to generate the username, or select '1' - '4'
for the order to use the field in generating username.
Example: 'LastName' and 'FirstName' are fields to be used as username. So under the username
selection chose '1' for 'FirstName' and '2' for 'Lastname', and the username generated will be in
the form 'FirstNameLastName'.
10. Under Options you should see Ignore First Line ( use if the first row are labels ),
Contact, and Send Email. Select whichever is appropiate.
11. Under Role Assign select the roles the imported users will be assigned.
12. Under Email Message, you can override the default message sent to new users. Leave blank to use the default message.
13. Under Update Existing Users, you can set whether existing users matching ones from the CSV file will be updated, replaced or added.
12. Under Save Settings, you can save your settings for use on future imports.
13. Click "Test" to do an import without committing changes to the database. Fix any errors that are generated.
14. Click "Import" to complete the import.
********************************************************************
AUTHOR CONTACT
- Report Bugs/Request Features:
http://drupal.org/project/user_import
- Comission New Features:
http://drupal.org/user/3555/contact
- Want To Say Thank You:
http://www.amazon.com/gp/registry/O6JKRQEQ774F
********************************************************************
ACKNOWLEDGEMENT
- I looked at a script by David McIntosh (neofactor.com) before coding this module.
- Documentation help Steve (spatz4000)
- patch by mfredrickson
- patch by idealso
- code from Nedjo Rogers
********************************************************************
SPONSORS

View File

@@ -0,0 +1,37 @@
"First Name","Last Name","Password","Tel","Fax","Email","Blog","Contact","Contact Preference","Interests","CV","Birthday"
"12345","O'Neil","password1","","5678 76 55 6","john@example.com","http://www.example.com",1,"email",,"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis scelerisque, urna sit amet malesuada tincidunt, nisl lacus euismod tortor, at rhoncus quam nunc id quam. Cras pellentesque nunc et nunc. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce tristique massa at sapien. Morbi tincidunt cursus risus. Nulla facilisi. Vivamus tincidunt nisl sed felis. Duis nunc magna, viverra in, tristique ut, feugiat eget, metus. Aliquam tincidunt volutpat sem. Vivamus lectus felis, accumsan a, bibendum id, porttitor et; lectus.",11/10/1976
"Mandy","Smith-Jones","password2","","5678 76 55 5","mandy@example.com","http://www.example.com",1,"telephone","Drupal, PHP, CSS","Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis scelerisque, urna sit amet malesuada tincidunt, nisl lacus euismod tortor, at rhoncus quam nunc id quam. Cras pellentesque nunc et nunc. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce tristique massa at sapien. Morbi tincidunt cursus risus. Nulla facilisi. Vivamus tincidunt nisl sed felis. Duis nunc magna, viverra in, tristique ut, feugiat eget, metus. Aliquam tincidunt volutpat sem. Vivamus lectus felis, accumsan a, bibendum id, porttitor et; lectus.",
"édward","André","password3","0123 666666","5678 76 55 5","charles@example.com","http://www.example.com/charlessmith",,"post",,,
"ěddy","Szěged","","0123 45678","5678 76 55 5","sarah@example.com","http://www.example.com",1,"post",,"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis scelerisque, urna sit amet malesuada tincidunt, nisl lacus euismod tortor, at rhoncus quam nunc id quam. Cras pellentesque nunc et nunc. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce tristique massa at sapien. Morbi tincidunt cursus risus. Nulla facilisi. Vivamus tincidunt nisl sed felis. Duis nunc magna, viverra in, tristique ut, feugiat eget, metus. Aliquam tincidunt volutpat sem. Vivamus lectus felis, accumsan a, bibendum id, porttitor et; lectus.",
"šarah","Smithš","password3","0123 45678","5678 76 55 5","sarah_smith@example.com","http://www.example.com",0,"telephone",,,
"Helen","Doeč","password3","0123 45678","5678 76 55 5","helen@example.com","http://www.example.com",0,,,,
"Claire","Doe­s","password3","0123 45678","5678 76 55 5","claire@example.com","http://www.example.com",0,"email",,"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis scelerisque, urna sit amet malesuada tincidunt, nisl lacus euismod tortor, at rhoncus quam nunc id quam. Cras pellentesque nunc et nunc. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce tristique massa at sapien. Morbi tincidunt cursus risus. Nulla facilisi. Vivamus tincidunt nisl sed felis. Duis nunc magna, viverra in, tristique ut, feugiat eget, metus. Aliquam tincidunt volutpat sem. Vivamus lectus felis, accumsan a, bibendum id, porttitor et; lectus.",
"Victoria","Doe","password3","0123 45678|02 0897 456","5678 76 55 5","victoria@example.com","http://www.example.com",1,"post",,,
"James","Wilson","password3","0123 45678","5678 76 55 5","james@example.com","http://www.example.com",0,"post",,,
"Anna","Smith","password1","0123 45678","5678 76 55 6","anna@example.com","http://www.example.com",1,"email",,"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis scelerisque, urna sit amet malesuada tincidunt, nisl lacus euismod tortor, at rhoncus quam nunc id quam. Cras pellentesque nunc et nunc. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce tristique massa at sapien. Morbi tincidunt cursus risus. Nulla facilisi. Vivamus tincidunt nisl sed felis. Duis nunc magna, viverra in, tristique ut, feugiat eget, metus. Aliquam tincidunt volutpat sem. Vivamus lectus felis, accumsan a, bibendum id, porttitor et; lectus.",11/11/1976
"Tino","Smith","password2","0123 45678","5678 76 55 5","tino@example.com","http://www.example.com",1,"telephone","Drupal, PHP, CSS","Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis scelerisque, urna sit amet malesuada tincidunt, nisl lacus euismod tortor, at rhoncus quam nunc id quam. Cras pellentesque nunc et nunc. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce tristique massa at sapien. Morbi tincidunt cursus risus. Nulla facilisi. Vivamus tincidunt nisl sed felis. Duis nunc magna, viverra in, tristique ut, feugiat eget, metus. Aliquam tincidunt volutpat sem. Vivamus lectus felis, accumsan a, bibendum id, porttitor et; lectus.",
"Sofia","Smith","password3","0123 45678","5678 76 55 5","sofia@example.com","http://www.example.com/charlessmith",,"post",,,
"Steve","Smith","password3","0123 45678","5678 76 55 5","steve@example.com","http://www.example.com",1,"post",,"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis scelerisque, urna sit amet malesuada tincidunt, nisl lacus euismod tortor, at rhoncus quam nunc id quam. Cras pellentesque nunc et nunc. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce tristique massa at sapien. Morbi tincidunt cursus risus. Nulla facilisi. Vivamus tincidunt nisl sed felis. Duis nunc magna, viverra in, tristique ut, feugiat eget, metus. Aliquam tincidunt volutpat sem. Vivamus lectus felis, accumsan a, bibendum id, porttitor et; lectus.",
"Lucy","Smith","password3","0123 45678","5678 76 55 5","lucy@example.com","http://www.example.com",0,"telephone",,,
"Angie","Doe","password3","0123 45678","5678 76 55 5","angie@example.com","http://www.example.com",0,,,,
"Carmen","Doe","password3","0123 45678","5678 76 55 5","carmen@example.com","http://www.example.com",0,"email",,"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis scelerisque, urna sit amet malesuada tincidunt, nisl lacus euismod tortor, at rhoncus quam nunc id quam. Cras pellentesque nunc et nunc. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce tristique massa at sapien. Morbi tincidunt cursus risus. Nulla facilisi. Vivamus tincidunt nisl sed felis. Duis nunc magna, viverra in, tristique ut, feugiat eget, metus. Aliquam tincidunt volutpat sem. Vivamus lectus felis, accumsan a, bibendum id, porttitor et; lectus.",
"Paul","Doe","password3","0123 45678","5678 76 55 5","paul@example.com","http://www.example.com",1,"post",,,
"Jason","Wilson","password3","0123 45678","5678 76 55 5","jason@example.com","http://www.example.com",0,"post",,,
"Mike","Smith","password1","0123 45678","5678 76 55 6","mike@example.com","http://www.example.com",1,"email",,"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis scelerisque, urna sit amet malesuada tincidunt, nisl lacus euismod tortor, at rhoncus quam nunc id quam. Cras pellentesque nunc et nunc. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce tristique massa at sapien. Morbi tincidunt cursus risus. Nulla facilisi. Vivamus tincidunt nisl sed felis. Duis nunc magna, viverra in, tristique ut, feugiat eget, metus. Aliquam tincidunt volutpat sem. Vivamus lectus felis, accumsan a, bibendum id, porttitor et; lectus.",11/11/1976
"Mary","Smith","password2","0123 45678","5678 76 55 5","mary@example.com","http://www.example.com",1,"telephone","Drupal, PHP, CSS","Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis scelerisque, urna sit amet malesuada tincidunt, nisl lacus euismod tortor, at rhoncus quam nunc id quam. Cras pellentesque nunc et nunc. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce tristique massa at sapien. Morbi tincidunt cursus risus. Nulla facilisi. Vivamus tincidunt nisl sed felis. Duis nunc magna, viverra in, tristique ut, feugiat eget, metus. Aliquam tincidunt volutpat sem. Vivamus lectus felis, accumsan a, bibendum id, porttitor et; lectus.",
"Simon","Smith","password3","0123 45678","5678 76 55 5","simon@example.com","http://www.example.com/charlessmith",,"post",,,
"Kieran","Smith","password3","0123 45678","5678 76 55 5","kieran@example.com","http://www.example.com",1,"post",,"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis scelerisque, urna sit amet malesuada tincidunt, nisl lacus euismod tortor, at rhoncus quam nunc id quam. Cras pellentesque nunc et nunc. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce tristique massa at sapien. Morbi tincidunt cursus risus. Nulla facilisi. Vivamus tincidunt nisl sed felis. Duis nunc magna, viverra in, tristique ut, feugiat eget, metus. Aliquam tincidunt volutpat sem. Vivamus lectus felis, accumsan a, bibendum id, porttitor et; lectus.",
"Arthur","Smith","password3","0123 45678","5678 76 55 5","arthur@example.com","http://www.example.com",0,"telephone",,,
"Gwen","Doe","password3","0123 45678","5678 76 55 5","gwen@example.com","http://www.example.com",0,,,,
"Chester","Doe","password3","0123 45678","5678 76 55 5","chester@example.com","http://www.example.com",0,"email",,"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis scelerisque, urna sit amet malesuada tincidunt, nisl lacus euismod tortor, at rhoncus quam nunc id quam. Cras pellentesque nunc et nunc. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce tristique massa at sapien. Morbi tincidunt cursus risus. Nulla facilisi. Vivamus tincidunt nisl sed felis. Duis nunc magna, viverra in, tristique ut, feugiat eget, metus. Aliquam tincidunt volutpat sem. Vivamus lectus felis, accumsan a, bibendum id, porttitor et; lectus.",
"Dorothy","Doe","password3","0123 45678","5678 76 55 5","dorothy@example.com","http://www.example.com",1,"post",,,
"Cameron","Wilson","password3","0123 45678","5678 76 55 5","cameron@example.com","http://www.example.com",0,"post",,,
"Trisha","Smith","password1","0123 45678","5678 76 55 6","trisha@example.com","http://www.example.com",1,"email",,"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis scelerisque, urna sit amet malesuada tincidunt, nisl lacus euismod tortor, at rhoncus quam nunc id quam. Cras pellentesque nunc et nunc. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce tristique massa at sapien. Morbi tincidunt cursus risus. Nulla facilisi. Vivamus tincidunt nisl sed felis. Duis nunc magna, viverra in, tristique ut, feugiat eget, metus. Aliquam tincidunt volutpat sem. Vivamus lectus felis, accumsan a, bibendum id, porttitor et; lectus.",11/11/2001
"David","Smith","password2","0123 45678","5678 76 55 5","david@example.com","http://www.example.com",1,"telephone","Drupal, PHP, CSS","Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis scelerisque, urna sit amet malesuada tincidunt, nisl lacus euismod tortor, at rhoncus quam nunc id quam. Cras pellentesque nunc et nunc. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce tristique massa at sapien. Morbi tincidunt cursus risus. Nulla facilisi. Vivamus tincidunt nisl sed felis. Duis nunc magna, viverra in, tristique ut, feugiat eget, metus. Aliquam tincidunt volutpat sem. Vivamus lectus felis, accumsan a, bibendum id, porttitor et; lectus.",
"Peter","Smith","password3","0123 45678","5678 76 55 5","peter@example.com","http://www.example.com/charlessmith",,"post",,,
"Saul","Smith","password3","0123 45678","5678 76 55 5","saul@example.com","http://www.example.com",1,"post",,"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis scelerisque, urna sit amet malesuada tincidunt, nisl lacus euismod tortor, at rhoncus quam nunc id quam. Cras pellentesque nunc et nunc. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce tristique massa at sapien. Morbi tincidunt cursus risus. Nulla facilisi. Vivamus tincidunt nisl sed felis. Duis nunc magna, viverra in, tristique ut, feugiat eget, metus. Aliquam tincidunt volutpat sem. Vivamus lectus felis, accumsan a, bibendum id, porttitor et; lectus.",
"Noel","Smith","password3","0123 45678","5678 76 55 5","noel@example.com","http://www.example.com",0,"telephone",,,
"Matt","Doe","password3","0123 45678","5678 76 55 5","matt@example.com","http://www.example.com",0,,,,
"Aston","Doe","password3","0123 45678","5678 76 55 5","aston@example.com","http://www.example.com",0,"email",,"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis scelerisque, urna sit amet malesuada tincidunt, nisl lacus euismod tortor, at rhoncus quam nunc id quam. Cras pellentesque nunc et nunc. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce tristique massa at sapien. Morbi tincidunt cursus risus. Nulla facilisi. Vivamus tincidunt nisl sed felis. Duis nunc magna, viverra in, tristique ut, feugiat eget, metus. Aliquam tincidunt volutpat sem. Vivamus lectus felis, accumsan a, bibendum id, porttitor et; lectus.",
"Mille","Doe","password3","0123 45678","5678 76 55 5","mille@example.com","http://www.example.com",1,"post",,,
"Ernest","Wilson","password3","0123 45678","5678 76 55 5","ernest@example.com","http://www.example.com",0,"post",,,

View File

@@ -0,0 +1,165 @@
<?php
// Functionality depends on node_import and CCK.
if (module_exists('node_import') && module_exists('content')) {
// Load the required API files.
include_once('./' . drupal_get_path('module', 'node_import') . '/node_import.api.php');
include_once('./' . drupal_get_path('module', 'node_import') . '/node_import.inc');
/**
* Implementation of hook_user_import_form_field_match(). Add supported Content Profile fields into our dropdown list.
*/
function content_profile_user_import_form_field_match() {
$options = array();
$options['content_profile'] = array();
$field_options = array();
$contentprofile_types = content_profile_get_types();
foreach ($contentprofile_types as $type => $data) {
$fields = node_import_fields('node:' . $type, TRUE);
// Give fields a more descriptive title.
foreach (array_keys($fields) as $key) {
if (strstr($key, 'cck:field_')) {
$field_options["$type $key"] = t('Content Profile: (!type) !key ', array('!key' => $fields[$key]['title'], '!type' => $type));
}
}
// skip merge if there are no fields on the content type
if (!empty($field_options)) {
$options['content_profile'] = array_merge($options['content_profile'], $field_options);
}
}
/* We do not support taxonomy yet */
return $options;
}
/**
* Implementation of hook_user_import_form_update_user().
*/
function content_profile_user_import_form_update_user() {
$form['content_profile'] = array('title' => t('Content Profile'), 'description' => t('Affected: fields in Content Profile nodes.'));
return $form;
}
/**
* Implementation of hook_user_import_data().
*/
function content_profile_user_import_data($settings, $update_setting, $column_settings, $module, $field_id, $data, $column_id) {
if ($module != 'content_profile') return;
return trim($data[$column_id]);
}
/**
* Implementation of hook_user_import_after_save().
*/
function content_profile_user_import_after_save($settings, $account, $password, $fields, $updated, $update_setting_per_module) {
if (!is_array($fields['content_profile'])) return;
// check if it's an existing user and if content profile is to be updated
if ($updated && $update_setting_per_module['content_profile'] == UPDATE_NONE) return;
// arrange values by content type
foreach ($fields['content_profile'] as $column_id => $column_data) {
if (!empty($column_data)) {
$keys = explode(' ', $column_id);
$contentprofile[$keys[0]][$keys[1]] = $column_data;
}
}
$contentprofile_types = content_profile_get_types();
// process each $content profile
foreach ($contentprofile_types as $type => $configuration) {
content_profile_user_import_node($type, $contentprofile, $account, $fields, $updated, $update_setting_per_module['content_profile']);
}
return;
}
/**
* callback to create or update a node if appropriate
*/
function content_profile_user_import_node($type, $content_profile, $account, $fields, $updated, $update_setting) {
if (empty($content_profile[$type])) return; // pass only those, which are used
$errors = array();
$title_empty = time();
if ($updated) {
$node = node_load(array('type' => $type, 'uid' => $account->uid));
}
if (empty($node)) {
$node = new stdClass();
$node->type = $type;
$node->status = 1;
$node->title = $title_empty;
}
// Assign the mapped fields to the $node.
foreach ($content_profile[$type] as $column_id => $column_data) {
$field_data = explode(':', $column_id);
$field_name = !empty($field_data[1]) ? $field_data[1] : $column_id;
$field_key = !empty($field_data[2]) ? $field_data[2] : 'value';
$field_value = array(0 => array($field_key => $column_data[0]));
if (!$updated) {
$node->{$field_name} = $field_value;
}
elseif ($updated && $update_setting == UPDATE_ADD) {
$current_content = content_format($field_name, $node->{$field_name}[0], 'default', $node);
if (empty($current_content) && !empty($column_data[0])) {
$node->{$field_name} = $field_value;
}
}
elseif ($updated && $update_setting == UPDATE_REPLACE) {
$node->{$field_name} = $field_value;
}
}
// not actually checking for errors at the moment, but lete's leave this in for when we do
if (empty($errors)) {
$node->uid = $account->uid;
$node->name = $account->name;
// Assign a default title if one has not already been mapped.
if (!isset($node->title) || empty($node->title) || $node->title == $title_empty) {
$node->title = $node->name;
}
$node = node_submit($node);
// make sure author is not changed when submited (hapens if existing node)
$node->uid = $account->uid;
$node->name = $account->name;
node_save($node);
if (!$node->nid) {
drupal_set_message(t('Unknown error on saving the node: %node_data! Check watchdog logs for details.', array('%node_data' => "$node->title ($node->type)")), 'error');
}
}
else {
/**
* @todo report errors
*/
}
}
}
else {
drupal_set_message(t('Please enable %module module!', array('%module' => 'node_import')));
}

View File

@@ -0,0 +1,191 @@
<?php
/**
* Implementation of hook_user_import_form_field_match().
*/
function field_user_import_form_field_match() {
$options = array();
$supported_field_types = field_user_import_supported_fields();
$fields_info = field_info_instances('user', 'user');
foreach ($fields_info as $field_name => $value) {
$field_info = field_info_field($field_name);
$type = $field_info['type'];
if (isset($supported_field_types[$type])) {
$options['field'][$field_name] = $value['label'];
}
else {
drupal_set_message(t('Field %field is not supported', array('%field' => $value['label'])), 'warning');
}
}
return $options;
}
/**
* Implementation of hook_user_import_data().
*/
function field_user_import_data($settings, $update_setting, $column_settings, $module, $field_id, $data, $column_id) {
if ($module != 'field') return;
$value = $data[$column_id];
return $value;
}
/**
* Implementation of hook_user_import_after_save().
*/
function field_user_import_after_save($settings, $account, $password, $fields, $updated, $update_setting_per_module) {
$fields_data = isset($fields['field']) ? $fields['field'] : array();
if (empty($fields_data)) return;
$processors = field_user_import_supported_fields();
$delimiter = $settings['multi_value_delimiter'];
$user_fields = user_load($account->uid);
$processed_fields = array();
foreach ($fields_data as $field_name => $data) {
$field_info = field_info_field($field_name);
$field_type = $field_info['type'];
$processor_function = $processors[$field_type]['save'];
// Deal with multiple values.
$values = explode($delimiter, $data[0]);
// Use callback function to process info for field before saving.
$processed_fields[$field_name] = $processor_function($user_fields, $field_name, $values);
}
if (!empty($processed_fields)) {
user_save($account, $processed_fields);
}
return;
}
function field_user_import_default_field_processor($user_fields, $field_name, $values) {
// @todo deal with multiple values
// @todo deal with language
// @todo deal with updating existing account
$field = $user_fields->$field_name;
for ($i = 0; $i < count($values); $i++) {
if (!empty($values[$i])) {
$field[LANGUAGE_NONE][$i]['value'] = $values[$i];
}
}
return $field;
}
function field_user_import_supported_fields($output = 'all') {
static $supported = array();
if (empty($supported)) {
$supported['text'] = array(
'validate' => 'field_user_import_default_field_validator',
'save' => 'field_user_import_default_field_processor',
);
$supported['list_boolean'] = array(
'validate' => 'field_user_import_default_field_validator',
'save' => 'field_user_import_default_field_processor',
);
$supported['number_decimal'] = array(
'validate' => 'field_user_import_default_field_validator',
'save' => 'field_user_import_default_field_processor',
);
$supported['number_float'] = array(
'validate' => 'field_user_import_default_field_validator',
'save' => 'field_user_import_default_field_processor',
);
$supported['number_integer'] = array(
'validate' => 'field_user_import_default_field_validator',
'save' => 'field_user_import_default_field_processor',
);
$supported['list_float'] = array(
'validate' => 'field_user_import_default_field_validator',
'save' => 'field_user_import_default_field_processor',
);
$supported['list_integer'] = array(
'validate' => 'field_user_import_default_field_validator',
'save' => 'field_user_import_default_field_processor',
);
$supported['list_text'] = array(
'validate' => 'field_user_import_default_field_validator',
'save' => 'field_user_import_default_field_processor',
);
// 'format'? 'safe_value'? - DONE
$supported['text_long'] = array(
'validate' => 'field_user_import_default_field_validator',
'save' => 'field_user_import_default_field_processor',
);
// 'format'? 'safe_value'? 'summary'? 'safe_summary'?
$supported['text_with_summary'] = array(
'validate' => 'field_user_import_default_field_validator',
'save' => 'field_user_import_default_field_processor',
);
$supported['taxonomy_term_reference'] = array(
'validate' => 'field_user_import_default_field_validator',
'save' => 'field_user_import_default_field_processor',
);
/** Unsupported for the moment **/
// $supported['file'] = array(
// 'validate' => 'field_user_import_default_field_validator',
// 'save' => 'field_user_import_default_field_processor',
// );
// $supported['image'] = array(
// 'validate' => 'field_user_import_default_field_validator',
// 'save' => 'field_user_import_default_field_processor',
// );
/** Not core - move to their own .inc files **/
// $supported['datetime'] = array(
// 'validate' => 'field_user_import_default_field_validator',
// 'save' => 'field_user_import_default_field_processor',
// );
//
// $supported['date'] = array(
// 'validate' => 'field_user_import_default_field_validator',
// 'save' => 'field_user_import_default_field_processor',
// );
//
//
// $supported['datestamp'] = array(
// 'validate' => 'field_user_import_default_field_validator',
// 'save' => 'field_user_import_default_field_processor',
// );
// $supported['addressfield'] = array(
// 'validate' => 'field_user_import_default_field_validator',
// 'save' => 'field_user_import_default_field_processor',
// );
// hook to add functions to this array.
// Will call all modules implementing hook_field_user_import_supported_alter
drupal_alter('field_user_import_supported', $supported);
}
return $supported;
}

View File

@@ -0,0 +1,118 @@
<?php
// Functionality depends on User Location.
if (module_exists('location_user')) {
/**
* Implementation of hook_user_import_form_field_match(). Add supported Location fields into our dropdown list.
*/
function location_user_import_form_field_match() {
$options = array();
$options['location'] = location_field_names();
return $options;
}
/**
* Implementation of hook_user_import_form_update_user().
*/
function location_user_import_form_update_user() {
$form['location'] = array(
'title' => t('Location'),
'description' => t('Affected: fields in user Location.'),
);
return $form;
}
/**
* Implementation of hook_user_import_data().
*/
function location_user_import_data($settings, $update_setting, $column_settings, $module, $field_id, $data, $column_id) {
if ($module != 'location') {
return;
}
if (empty($data[$column_id])) {
$defaults = location_locationapi($data, 'defaults');
$data[$column_id] = $defaults[$field_id]['default'];
}
switch ($field_id) {
case 'country':
$country = location_country_name($data[$column_id]);
if ($country != '') {
return trim($data[$column_id]);
}
else {
$countries = location_get_iso3166_list();
if ($country = array_search($data[$column_id], $countries)) {
if ($country !== FALSE) {
return $country;
}
}
}
user_import_errors(t('Invalid country'));
return trim($data[$column_id]);
case 'province':
if (!empty($data['country'])) {
if (!empty($data[$column_id])) {
$provinces = location_get_provinces($data['country']);
$found = FALSE;
$province = strtoupper($data['province']);
foreach ($provinces as $key => $value) {
if ($province == strtoupper($key) || $province == strtoupper($value)) {
$found = TRUE;
break;
}
}
if (!$found) {
user_import_errors(t('Province not found'));
}
return trim($data[$column_id]);
}
}
return trim($data[$column_id]);
default:
return trim($data[$column_id]);
}
}
/**
* Implementation of hook_user_import_after_save().
*/
function location_user_import_after_save($settings, $account, $password, $fields, $updated, $update_setting_per_module) {
if (!is_array($fields['location'])) {
return;
}
// check if it's an existing user and if location is to be updated
if ($updated && $update_setting_per_module['location'] == UPDATE_NONE) {
return;
}
// Arrange values for location array
$location = array();
foreach ($fields['location'] as $column_id => $column_data) {
$location[0][$column_id] = $column_data[0];
}
// Merge defaults in
$dummy = array();
$defaults = location_invoke_locationapi($dummy, 'defaults');
foreach ($defaults as $key => $value) {
if (!isset($location[0][$key])) {
$location[0][$key] = $value['default'];
}
}
location_save_locations($location, array('uid' => $account->uid));
return;
}
}

View File

@@ -0,0 +1,206 @@
<?php
/**
* Implementation of hook_user_import_form_field_match().
*/
function profile_user_import_form_field_match() {
module_load_include('inc', 'user_import', 'user_import.admin');
$fields = _user_import_profile('fid', 'title');
$options['profile'] = $fields;
return $options;
}
/**
* Implementation of hook_user_import_form_update_user().
*/
function profile_user_import_form_update_user() {
$form['profile'] = array('title' => t('Profile'), 'description' => t('Affected: Profile fields.'));
return $form;
}
/**
* Implementation of hook_user_import_data().
*/
function profile_user_import_data($settings, $update_setting, $column_settings, $module, $field_id, $data, $column_id) {
if ($module != 'profile') return;
return trim($data[$column_id]);
}
/**
* Implementation of hook_user_import_after_save().
*/
function profile_user_import_after_save($settings, $account, $password, $fields, $updated, $update_setting_per_module) {
// get all fields
$profile_fields = profile_get_fields();
$data = $old_data = unserialize($account->data);
foreach ($profile_fields as $field) {
profile_user_import_save_profile($field, $account->uid, $fields['profile'][$field->fid][0], $updated, $update_setting_per_module['profile'], $data);
}
// data column in the user table needs to be updated
if ($data != $old_data) {
db_update('users')
->fields(array('data' => serialize($data)))
->condition('uid', $account->uid)
->execute();
}
return;
}
function profile_user_import_save_profile($field, $uid, $value, $updated, $update_setting, &$data) {
// when the profile field is displayed on the registration form an empty value is automatically saved by the Profile module
$exists = db_query_range('SELECT value FROM {profile_values} WHERE fid = :fid AND uid = :uid', 0, 1, array(':fid' => $field->fid, ':uid' => $uid))->fetchField();
user_import_profile_date($value, $field->type);
if ($updated) {
switch ($update_setting) {
case UPDATE_NONE:
return;
case UPDATE_ADD:
if (empty($value) || (!empty($exists) && $exists != '')) return;
case UPDATE_REPLACE:
if (empty($value) && $update_setting == UPDATE_REPLACE) {
db_query("DELETE FROM {profile_values} WHERE fid = :fid AND uid = :uid", array(':fid' => $field->fid, ':uid' => $uid));
unset($data[$field->name]);
return;
}
if ((empty($exists) && $exists != '') || $exists === FALSE) {
$id = db_insert('profile_values')
->fields(array(
'fid' => $field->fid,
'uid' => $uid,
'value' => $value,
))
->execute();
}
else {
$id = db_update('profile_values')
->fields(array(
'value' => $value,
))
->condition('fid', $field->fid)
->condition('uid', $uid)
->execute();
}
$data[$field->name] = $value;
return;
}
}
else {
if (empty($value)) return;
if ((empty($exists) && $exists != '') || $exists === FALSE) {
$id = db_insert('profile_values')
->fields(array('fid' => $field->fid, 'uid' => $uid, 'value' => $value))
->execute();
}
else {
db_update('profile_values')
->fields(array('value' => $value))
->condition('fid', $field->fid)
->condition('uid', $uid)
->limit(1)
->execute();
$data[$field->name] = $value;
}
}
return;
}
/**
*
*/
function profile_get_fields() {
static $fields = array();
// Avoid making more than one database call for profile info.
if (empty($fields)) {
$results = db_query('SELECT * FROM {profile_field}');
foreach ($results as $row) {
$fields[] = $row;
}
}
return $fields;
}
/**
* Convert date into format that Profile module expects:
* a:3:{s:5:"month";s:1:"1";s:3:"day";s:1:"1";s:4:"year";s:4:"1976";}
*/
function user_import_profile_date(&$value, $field_type) {
if ($field_type != "date" || empty($value)) {
return;
}
$date = explode('/', $value);
if (!is_array($date)) {
return;
}
// Get seleceted format.
$date_format = variable_get('user_import_profile_date_format', 'MM/DD/YYYY');
if ($date_format == 'MM/DD/YYYY') {
list($month, $day, $year) = explode('/', $value);
}
else {
if ($date_format == 'DD/MM/YYYY') {
list($day, $month, $year) = explode('/', $value);
}
else {
if ($date_format == 'YYYY/MM/DD') {
list($year, $month, $day) = explode('/', $value);
}
else {
if ($date_format == 'YYYY/DD/MM') {
list($year, $day, $month) = explode('/', $value);
}
}
}
}
// Leading zeros cause a problem so remove them.
if (substr($day, 0, 1) == '0') {
$day = substr($day, 1, 1);
}
if (substr($month, 0, 1) == '0') {
$month = substr($month, 1, 1);
}
$value = serialize(array('month' => $month, 'day' => $day, 'year' => $year));
}

View File

@@ -0,0 +1,103 @@
<?php
/**
* Implementation of hook_user_import_form_fieldsets().
*/
function subscribed_user_import_form_fieldset($import, $collapsed) {
if (module_exists('publication') && module_exists('schedule')) {
$publications = publication_select_publications('enewsletter');
if (empty($publications)) return;
$form['subscribed'] = array(
'#type' => 'fieldset',
'#title' => t('Subscriptions'),
'#collapsible' => TRUE,
'#collapsed' => $collapsed,
'#tree' => TRUE,
);
foreach ($publications as $publication) {
$type = $publication->type;
$form['subscribed'][$type] = array(
'#type' => 'fieldset',
'#title' => check_plain($type),
);
}
reset($publications);
$subscribed = $import['options']['subscribed'];
foreach ($publications as $publication) {
$options = array();
$schedules = schedule_select_schedules($type, $publication->publication_id);
$options[0] = t('No Subscription');
foreach ($schedules as $schedule) {
$options[$schedule['schedule_id']] = $schedule['schedule_title'];
}
$subscription_default = empty($subscribed[$type][$publication->publication_id]) ? 0 : $subscribed[$type][$publication->publication_id][0];
$form['subscribed'][$type][$publication->publication_id][] = array(
'#type' => 'radios',
'#title' => check_plain($publication->title),
'#default_value' => $subscription_default,
'#options' => $options,
'#description' => check_plain($publication->description),
);
}
}
return $form;
}
/**
* Implementation of hook_user_import_form_update_user().
*/
function subscribed_user_import_form_update_user() {
$form['subscribed'] = array('title' => t('Subscribed'), 'description' => t('Affected: subscriptions.'));
return $form;
}
/**
* Implementation of hook_user_import_after_save().
*/
function subscribed_user_import_after_save($settings, $account, $password, $fields, $updated) {
/**
* @todo change to new update architecture
*/
if (!module_exists('publication') || !module_exists('schedule') || !module_exists('identity_hash') || empty($settings['options']['subscribed'])) return;
$subscribed_settings = $settings['options']['subscribed'];
$uid = $account->uid;
if (is_array($subscribed_settings)) {
foreach ($subscribed_settings as $type => $type_subscriptions) {
$subscriptions = $type_subscriptions;
foreach ($type_subscriptions as $publication_id => $schedule) {
if (empty($schedule[0])) unset($subscriptions[$publication_id]);
}
$publications = publication_select_publications_and_terms($type);
if (!empty($publications) && !empty($subscriptions)) {
subscribed_set_subscriptions($type, $uid, $publications, $subscriptions);
subscribed_set_subscriptions_terms($type, $uid, $publications, $subscriptions);
identity_hash_set_hash($uid);
}
}
}
return;
}

View File

@@ -0,0 +1,384 @@
<?php
/**
* @todo move contact options to separate contact.inc
*/
/**
* Implementation of hook_user_import_form_field_match().
*/
function user_user_import_form_field_match() {
$options = array();
$options['user']['email'] = t('Email Address*');
$options['user']['password'] = t('Password');
$options['user']['roles'] = t('Roles');
$options['user']['created'] = t('Account Creation Date');
// $options['user']['username'] = t('Username');
// $options['user']['uid'] = t('UID');
// $options['user']['modified'] = t('Modified');
// $options['user']['picture_uri'] = t('Picture');
// $options['user']['timezone'] = t('Timezone');
// $options['user']['md5_password'] = t('Password MD5');
return $options;
}
/**
* Implementation of hook_user_import_form_fieldsets().
*/
function user_user_import_form_fieldset($import, $collapsed) {
$form = array();
user_user_import_edit_roles_fields($form, $import, $collapsed);
user_user_import_edit_email_fields($form, $import, $collapsed);
return $form;
}
/**
* Implementation of hook_user_import_form_update_user().
*/
function user_user_import_form_update_user() {
$form['roles'] = array('title' => t('Roles'), 'description' => t('Affected: roles assigned to user.'));
$form['password'] = array('title' => t('Password'), 'description' => t('Affected: password.'), 'exclude_add' => TRUE);
$form['contact'] = array('title' => t('Contact'), 'description' => t('Affected: user contact option.'), 'exclude_add' => TRUE);
return $form;
}
/**
* Implementation of hook_user_import_data().
*/
function user_user_import_data($settings, $update_setting, $column_settings, $module, $field_id, $data, $column_id) {
if ($module != 'user') return;
if ($field_id == 'email') {
$value = trim($data[$column_id]);
if (!empty($settings['options']['email_domain'])) {
$value .= $settings['options']['email_domain'];
}
_user_import_validate_email($value, $update_setting);
}
if ($field_id == 'password') {
$value = trim($data[$column_id]);
}
if ($field_id == 'created') {
$value = trim($data[$column_id]);
if (!empty($value) && !is_numeric($value)) {
$parsed = date_parse($value);
$timestamp = mktime(
$parsed['hour'],
$parsed['minute'],
$parsed['second'],
$parsed['month'],
$parsed['day'],
$parsed['year']
);
if (!empty($timestamp) && is_numerric($timestamp)) {
$value = $timestamp;
}
}
}
if ($field_id == 'roles') {
$value = user_user_import_roles_data($data[$column_id], $settings['roles_new']);
}
return $value;
}
/**
* Implementation of hook_user_import_pre_save().
*/
function user_user_import_pre_save($settings, $account, $fields, $errors, $update_setting_per_module) {
$account_add['mail'] = $fields['user']['email'][0];
if (!empty($account['uid'])) {
// update roles
switch ($update_setting_per_module['roles']) {
case UPDATE_ADD:
// include currently assigned roles
foreach ($account['roles'] as $rid => $role_name) {
$account_add['roles'][$rid] = $rid;
}
case UPDATE_REPLACE:
// update roles
if (!isset($account_add['roles'])) {
$account_add['roles'] = array();
}
foreach ($settings['roles'] as $rid => $role_set) {
if (!empty($role_set)) {
$account_add['roles'][$rid] = $rid;
}
}
break;
}
// update password
if ($update_setting_per_module['password'] == UPDATE_REPLACE) {
$account_add['pass'] = (empty($fields['user']['password'][0])) ? user_password() : $fields['user']['password'][0];
}
else {
$account_add['pass'] = "";
}
// update contact
if ($update_setting_per_module['contact'] == UPDATE_REPLACE) {
$account_add['contact'] = $settings['contact'];
}
else {
$account_add['contact'] = isset($account['contact']) ? $account['contact'] : '';
}
}
else {
$account_add['timezone'] = variable_get('date_default_timezone', @date_default_timezone_get());
$account_add['status'] = 1;
$account_add['init'] = $fields['user']['email'][0];
$account_add['pass'] = (empty($fields['user']['password'][0])) ? user_password() : $fields['user']['password'][0];
if (isset($fields['user']['created'][0]) && !empty($fields['user']['created'][0])) {
$account_add['created'] = $fields['user']['created'][0];
}
$account_add['init'] = $fields['user']['email'][0];
if (!empty($settings['options']['activate'])) {
$account_add['access'] = time();
$account_add['login'] = time();
}
// add selected roles
foreach ($settings['roles'] as $rid => $role_set) {
if (!empty($role_set)) $account_add['roles'][$rid] = $rid;
}
}
return $account_add;
}
/**
* Implementation of hook_user_import_after_save().
*/
function user_user_import_after_save($settings, $account, $password, $fields, $updated, $update_setting_per_module) {
/**
* @todo change hook_user_import_after_save() so that all changes to data are returned and saved in one hit
*/
$roles = isset($fields['user']['roles']) ? $fields['user']['roles'] : array();
user_user_import_after_save_role($account, $settings['roles_new'], $account->roles, $roles);
return;
}
function user_user_import_edit_roles_fields(&$form, $import, $collapsed) {
$roles = array();
$roles_data = user_roles();
// remove 'anonymous user' option
while (list ($rid, $role_name) = each($roles_data)) {
if ($role_name != 'anonymous user' && $role_name != 'authenticated user') $roles[$rid] = $role_name;
}
// roles selected
if (!empty($import['roles'])) {
foreach ($import['roles'] as $rid) {
if ($rid != 0) $roles_selected[] = $rid;
}
}
if (empty($roles_selected)) $roles_selected[] = 2;
$form['role_selection'] = array(
'#type' => 'fieldset',
'#title' => t('Role Assign'),
'#weight' => -80,
'#collapsible' => TRUE,
'#collapsed' => $collapsed,
);
$form['role_selection']['roles'] = array(
'#title' => t('Assign Role(s) To All Users'),
'#type' => 'checkboxes',
'#options' => $roles,
'#default_value' => $roles_selected,
'#description' => t("Select which role(s) all imported users should be assigned. The role 'authenticated user' is assigned automatically."),
);
$form['role_selection']['roles_new'] = array(
'#type' => 'checkbox',
'#title' => t('Add New Roles'),
'#default_value' => isset($import['roles_new']) ? $import['roles_new'] : 0,
'#description' => t('Create imported role(s) that are not found and assign it to the user, in addition to any role(s) selected above. Warning: incorrect roles will be created if the incoming data includes typos.'),
);
return;
}
function user_user_import_edit_email_fields(&$form, $import, $collapsed) {
$form['email_message'] = array(
'#type' => 'fieldset',
'#title' => t('Email Message'),
'#description' => t('Welcome message to be sent to imported users. Leave blank to use the default !message. If an existing user account is updated no welcome email will be sent to that user. <strong>Note - if "Activate Accounts" option is enabled !login_url (one time login) will not work.</strong>', array('!message' => l(t('message'), 'admin/people/settings'))),
'#collapsible' => TRUE,
'#collapsed' => $collapsed,
);
$form['email_message']['subject'] = array(
'#type' => 'textfield',
'#title' => t('Message Subject'),
'#default_value' => isset($import['subject']) ? $import['subject'] : '',
'#description' => t('Customize the subject of the welcome e-mail, which is sent to imported members.') . ' ' . t('Available variables are:') . ' !username, !site, !password, !uri, !uri_brief, !mailto, !date, !login_uri, !edit_uri, !login_url.',
'#element_validate' => array('user_import_send_email_subject_validate'),
);
$form['email_message']['message'] = array(
'#type' => 'textarea',
'#title' => t('Message'),
'#default_value' => isset($import['message']) ? $import['message'] : '',
'#description' => t('Customize the body of the welcome e-mail, which is sent to imported members.') . ' ' . t('Available variables are:') . ' !username, !site, !password, !uri, !uri_brief, !mailto, !login_uri, !edit_uri, !login_url.',
'#element_validate' => array('user_import_send_email_message_validate'),
);
$form['email_message']['message_format'] = array(
'#type' => 'radios',
'#title' => t('Email Format'),
'#default_value' => isset($import['message_format']) ? $import['message_format'] : 0,
'#options' => array(t('Plain Text'), t('HTML')),
);
$form['email_message']['message_css'] = array(
'#type' => 'textarea',
'#title' => t('CSS'),
'#default_value' => isset($import['message_css']) ? $import['message_css'] : '',
'#description' => t('Use if sending HTML formated email.'),
);
return;
}
function _user_import_validate_email($email = NULL, $duplicates_allowed = FALSE) {
if (empty($email)) {
user_import_errors(t('no email'));
}
elseif (!valid_email_address($email)) {
user_import_errors(t('invalid email'));
}
// Handle duplicate emails.
elseif (!$duplicates_allowed && _user_import_existing_uid($email)) {
user_import_errors(t('duplicate email'));
}
return;
}
function user_user_import_roles_data($data, $new_roles_allowed) {
$roles = array();
if (empty($data)) return;
$values = explode(',', $data);
// check if any roles are specified that don't already exist
$existing_roles = user_roles();
foreach ($values as $piece) {
$role = trim($piece);
$unrecognised = array();
if (!empty($role)) {
// only add if role is recognized or adding new roles is allowed
if (empty($new_roles_allowed) && !array_search($role, $existing_roles)) {
$unrecognised[] = $role;
}
else {
$roles[] = $role;
}
}
}
if (!empty($unrecognised)) {
user_import_errors(t('The following unrecognised roles were specified:') . implode(',', $unrecognised));
}
return $roles;
}
/**
* Return an existing user ID, if present, for a given email.
*/
function _user_import_existing_uid($email) {
$sql = 'SELECT uid FROM {users} WHERE mail = :mail';
$args = array(':mail' => $email);
$uid = db_query_range($sql, 0, 1, $args)->fetchField();
return $uid;
}
function user_user_import_after_save_role($account, $new_roles_allowed, $account_roles, $roles) {
$existing_roles = user_roles();
// if roles were specified, add to existing roles
$assign_roles = array();
if (is_array($roles) && !empty($roles)) {
foreach ($roles as $role) {
if (!empty($role)) {
$key = array_search($role, $existing_roles);
if (!empty($new_roles_allowed) && empty($key)) {
$key = db_insert('role')
->fields(array(
'name' => $role,
))
->execute();
$existing_roles[$key] = $role;
}
$assign_roles[$key] = $role;
}
}
$need_update = FALSE;
foreach ($assign_roles as $key => $role) {
if (!isset($account_roles[$key])) {
$need_update = TRUE;
$account_roles[$key] = $role;
}
}
if ($need_update) {
user_save($account, array('roles' => $account_roles));
}
}
return;
}

View File

@@ -0,0 +1,431 @@
<?php
/**
* Implementation of hook_user_import_form_fieldset().
* Add fieldsets to an import settings form.
*/
function user_import_user_import_form_fieldset($import, $collapsed) {
$form = array();
_user_import_edit_template_fields($form, $import);
_user_import_edit_settings_fields($form, $import, $collapsed);
_user_import_edit_remove_fields($form, $import);
return $form;
}
/**
* Implementation of hook_user_import_after_save().
*/
function user_import_user_import_after_save($settings, $account, $password, $fields, $updated, $update_setting_per_module) {
if (!empty($settings['send_email']) && !$updated) {
$subscribed = isset($settings['subscribed']) ? $settings['subscribed'] : NULL;
_user_import_send_email($account,
$password,
$fields,
$settings['subject'],
$settings['message'],
$settings['message_format'],
$settings['message_css'],
$subscribed
);
}
}
/**
* Implementation of hook_user_import_imported().
*/
function user_import_user_import_imported($import_id, $settings) {
// Delete file after it's been processed,
//_user_import_file_deletion($settings['filepath'], $settings['filename'], $settings['oldfilename'], FALSE, FALSE);
file_unmanaged_delete($settings['filepath']);
}
// Send email when account is created
function _user_import_send_email($account, $password, $profile, $subject, $body, $format, $css, $subscribed) {
global $base_url;
// All system mails need to specify the module and template key (mirrored from
// hook_mail()) that the message they want to send comes from.
$module = 'user_import';
$key = 'welcome';
// Specify 'to' and 'from' addresses.
$to = $account->mail;
$from = variable_get('site_mail', NULL);
$params = array(
'!username' => $account->name,
'!uid' => $account->uid,
'!site' => variable_get('site_name', 'drupal'),
'!login_url' => user_pass_reset_url($account),
'!password' => $password,
'!uri' => $base_url,
'!uri_brief' => drupal_substr($base_url, drupal_strlen('http://')),
'!mailto' => $account->mail,
'!date' => format_date(time()),
'!login_uri' => url('user', array('absolute' => TRUE)),
'!edit_uri' => url('user/' . $account->uid . '/edit', array('absolute' => TRUE)),
'subject' => $subject,
'body' => $body,
'email_format' => $format,
'css' => $css,
);
_user_import_publication_email($params, $account, $subscribed, $format);
// import info to profile
if (module_exists('profile') && is_array($profile)) {
$profile_name = _user_import_profile('fid', 'name');
foreach ($profile_name as $fid => $field_name) {
$params['!' . $field_name] = $profile[$fid];
}
}
$language = user_preferred_language($account);
// Whether or not to automatically send the mail when drupal_mail() is
// called. This defaults to TRUE, and is normally what you want unless you
// need to do additional processing before drupal_mail_send() is called.
$send = TRUE;
$sent = drupal_mail($module, $key, $to, $language, $params, $from, $send);
return;
}
/**
* Implementation of hook_mail().
*/
function user_import_mail($key, &$message, $params) {
switch ($key) {
case 'welcome':
$message['subject'] = (empty($params['subject'])) ? _user_mail_text('register_admin_created_subject', $message['language'], $params) : strtr($params['subject'], $params);
$body = (empty($params['body'])) ? _user_mail_text('register_admin_created_body', $message['language'], $params) : strtr($params['body'], $params);
if ($params['email_format'] == 1) {
$message['headers']['Content-Type'] = 'text/html; charset=UTF-8';
$body_head = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />';
if (!empty($params['css'])) $body_head .= '<style type="text/css">' . check_plain($params['css']) . '</style>';
$message['body'][] = $body_head . '</head><body>' . $body . '</body></html>';
}
else {
$message['body'][] = $body;
}
break;
}
}
function _user_import_edit_settings_fields(&$form, $import, $collapsed) {
$form['optional'] = array(
'#type' => 'fieldset',
'#title' => t('Options'),
'#weight' => -85,
'#collapsible' => TRUE,
'#collapsed' => $collapsed,
);
$form['optional']['first_line_skip'] = array(
'#type' => 'checkbox',
'#title' => t('Ignore First Line'),
'#default_value' => isset($import['first_line_skip']) ? $import['first_line_skip'] : 0,
'#description' => t('If the first line is the names of the data columns, set to ignore first line.'),
);
/**
* @todo move contact options to a separate contact.inc support file
*/
$form['optional']['contact'] = array(
'#type' => 'checkbox',
'#title' => t('Contact'),
'#default_value' => isset($import['contact']) ? $import['contact'] : 0,
'#description' => t("Set each user's personal contact form to 'allowed'."),
);
$form['optional']['send_email'] = array(
'#type' => 'checkbox',
'#title' => t('Send Email'),
'#default_value' => isset($import['send_email']) ? $import['send_email'] : 0,
'#description' => t('Send email to users when their account is created.'),
);
$form['optional']['username_space'] = array(
'#type' => 'checkbox',
'#title' => t('Username Space'),
'#default_value' => isset($import['username_space']) ? $import['username_space'] : 0,
'#description' => t("Include spaces in usernames, e.g. 'John' + 'Smith' => 'John Smith'."),
);
$form['optional']['activate'] = array(
'#type' => 'checkbox',
'#title' => t('Activate Accounts'),
'#default_value' => isset($import['activate']) ? $import['activate'] : 0,
'#description' => t("User accounts will not be visible to other users until their owner logs in. Select this option to make all imported user accounts visible. <strong>Note - one time login links in welcome emails will no longer work if this option is enabled.</strong>"),
);
$form['optional']['delimiter'] = array(
'#type' => 'textfield',
'#title' => t('File Delimiter'),
'#size' => 4,
'#default_value' => isset($import['delimiter']) ? $import['delimiter'] : ',',
'#description' => t("The column delimiter for the file. Use '/t' for Tab."),
);
$form['optional']['multi_value_delimiter'] = array(
'#type' => 'textfield',
'#title' => t('Multi Value Delimiter'),
'#size' => 4,
'#default_value' => isset($import['multi_value_delimiter']) ? $import['multi_value_delimiter'] : '*||*',
'#description' => t("Character(s) to use to split data so that it can be added to a field set to multiple values, e.g. '||', '*||*'"),
);
$form['optional']['email_domain'] = array(
'#type' => 'textfield',
'#title' => t('Email Domain'),
'#description' => t("Create an email address with the combined contents of Email Address (in Field Match above) and this field. <em><br />For example if Email Address is 'Luthor' and Email Domain is '@lexcorp.com', the account address woud be 'luthor@lexcorp.com'. <br />Note that '@example.com' is recommended for dummy addresses.</em>"),
'#default_value' => isset($import['email_domain']) ? $import['email_domain'] : '',
);
return;
}
function _user_import_edit_template_fields(&$form, $import) {
// settings template update controls
if (empty($import['name'])) {
// new settings template save controls
$form['save'] = array(
'#type' => 'fieldset',
'#title' => t('Save Settings'),
'#description' => t('Save settings for re-use on other imports.'),
'#weight' => 90,
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
$form['save']['name'] = array(
'#type' => 'textfield',
'#title' => t('Settings Name'),
'#size' => 26,
'#maxlength' => 25,
'#description' => t('Name to identify these settings by.'),
);
$auto_imports_enabled = variable_get('user_import_auto_imports_enabled', FALSE);
if (!empty($auto_imports_enabled)) {
$form['save']['auto_import_directory'] = array(
'#type' => 'textfield',
'#title' => t('Auto Import Directory Name'),
'#description' => t('If this is set a directory with this name will be created, into which files can be uploaded and automatically processed, using the settings on this page to create new user accounts.'),
'#default_value' => isset($import['auto_import_directory']) ? $import['auto_import_directory'] : '',
);
}
$form['save'][] = array(
'#type' => 'submit',
'#value' => t('Save'),
'#validate' => array('user_import_template_has_name_validate',
'user_import_template_unique_name_validate',
'user_import_edit_validate',
),
'#submit' => array('user_import_template_new_submit'),
);
}
else {
$form['save'] = array(
'#type' => 'fieldset',
'#title' => t('Saved Settings'),
'#description' => t("If changes have neen made to the settings since they where last saved you can update the saved template, or save them as a new template."),
'#weight' => 90,
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['#current_template'] = $import['name'];
$form['save']['update'] = array(
'#type' => 'fieldset',
'#title' => t('Update'),
'#description' => t("Update '%name' settings template", array('%name' => $import['name'])),
);
$auto_imports_enabled = variable_get('user_import_auto_imports_enabled', FALSE);
if (!empty($auto_imports_enabled)) {
$form['save']['auto_import_directory'] = array(
'#type' => 'textfield',
'#title' => t('Auto Import Directory Name'),
'#description' => t('If this is set a directory with this name will be created, into which files can be uploaded and automatically processed, using the settings on this page to create new user accounts.'),
'#default_value' => isset($import['auto_import_directory']) ? $import['auto_import_directory'] : '',
);
}
$form['save']['update']['submit'] = array(
'#type' => 'submit',
'#value' => t('Update'),
'#validate' => array('user_import_edit_validate'),
'#submit' => array('user_import_template_update_submit'),
);
$form['save']['new'] = array(
'#type' => 'fieldset',
'#title' => t('Create New'),
'#description' => t("Save as new settings template"),
);
$form['save']['new']['name'] = array(
'#type' => 'textfield',
'#title' => t('Save As New'),
'#size' => 30,
'#maxlength' => 25,
'#description' => t('Name to identify these settings by.'),
);
$auto_imports_enabled = variable_get('user_import_auto_imports_enabled', FALSE);
if (!empty($auto_imports_enabled)) {
$form['save']['auto_import_directory'] = array(
'#type' => 'textfield',
'#title' => t('Auto Import Directory Name'),
'#description' => t('If this is set a directory with this name will be created, into which files can be uploaded and automatically processed, using the settings on this page to create new user accounts.'),
'#default_value' => isset($import['auto_import_directory']) ? $import['auto_import_directory'] : '',
);
}
$form['save']['new'][] = array(
'#type' => 'submit',
'#value' => t('Save As New'),
'#validate' => array('user_import_template_has_name_validate', 'user_import_template_unique_name_validate', 'user_import_edit_validate'),
'#submit' => array('user_import_template_new_submit'),
);
}
return;
}
/**
* Validate that a template has a name.
*/
function user_import_template_has_name_validate($form, &$form_state) {
$template_name = trim($form_state['values']['name']);
if (empty($template_name)) form_set_error('name', t('A name needs to be set to save this settings template.'));
}
/**
* Validate that a template has a unique name.
*/
function user_import_template_unique_name_validate($form, &$form_state) {
$template_name = trim($form_state['values']['name']);
$unique_name = db_query('SELECT COUNT(import_id) FROM {user_import} WHERE name = :name', array(':name' => $template_name))->fetchField();
if (!empty($unique_name)) form_set_error('name', t("'!name' is already in use by another settings template.", array('!name' => $template_name)));
}
/**
* Validate that a email subject line has been set if Send Email is enabled.
*/
function user_import_send_email_subject_validate($element, &$form_state) {
if (!empty($form_state['values']['send_email']) && empty($form_state['values']['subject'])) {
form_error($element, t('If Send Email has been enabled then an <strong>email subject</strong> line must set.'));
}
}
/**
* Validate that a email message has been set if Send Email is enabled.
*/
function user_import_send_email_message_validate($element, &$form_state) {
if (!empty($form_state['values']['send_email']) && empty($form_state['values']['message'])) {
form_error($element, t('If Send Email has been enabled then an <strong>email message</strong> must set.'));
}
}
function _user_import_edit_remove_fields(&$form, $import) {
$form['remove'] = array(
'#type' => 'fieldset',
'#title' => t('Use Different CSV File'),
'#description' => t('Remove file to use a different file. All settings on this page will be deleted.'),
'#weight' => -100,
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['remove']['file'] = array(
'#type' => 'item',
'#title' => t('Uploaded file: @filename', array('@filename' => $import['filename'])),
'#value' => $import['filename'],
);
$form['remove']['submit'] = array(
'#type' => 'submit',
'#value' => t('Remove file'),
'#validate' => array('user_import_edit_remove_file_validate'),
);
return;
}
/**
* Delete settings and uploaded file
*/
function user_import_edit_remove_file_validate($form, &$form_state) {
$settings = _user_import_settings_select($form_state['values']['import_id']);
_user_import_settings_deletion($form_state['values']['import_id']);
//_user_import_file_deletion($settings['filepath'], $settings['filename'], $settings['oldfilename'], $settings['options']['ftp']);
file_unmanaged_delete($settings['filepath']);
drupal_goto('admin/people/user_import/add');
}
function _user_import_publication_email(&$variables, $account, $subscribed, $format) {
if (!module_exists('publication') || !module_exists('schedule') || !module_exists('identity_hash')) {
return;
}
$id_hash = identity_hash_select_hash($account->uid);
$variables['!id_hash'] = $id_hash->hash;
while (list($type, $subscriptions) = each($subscribed)) {
while (list($publication_id, $shedule) = each($subscriptions)) {
if (!empty($shedule[0])) {
$publication = publication_select_publications($type, $publication_id);
$update_link = url('subscribed/preferences/' . $publication_id . '/' . $id_hash->hash, array('absolute' => TRUE));
$unsubscribe_link = url('subscribed/delete/' . $publication_id . '/' . $id_hash->hash, array('absolute' => TRUE));
if ($format == 1) {
$variables['!subscribed_links'] .= '<strong>' . $publication->title . '</strong><br />' .
'<a href="' . $update_link . '">' . t('Update Preferences') . '</a> | <a href="' . $unsubscribe_link . '">' . t('Unsubscribe') . '</a><br />';
}
else {
$variables['!subscribed_links'] .= $publication->title . "\n" .
' - ' . t('Update Preferences') . ' ' . $update_link . '\n' .
' - ' . t('Unsubscribe') . ' ' . $unsubscribe_link . '\n';
}
}
}
}
}

View File

@@ -0,0 +1,18 @@
<?php
/**
* @todo add option to not record watchdog messages for each user created
* on large imports user import could add a lot of rows to the watchdog table
*/
/**
* Implementation of hook_user_import_after_save().
*/
function watchdog_user_import_after_save($settings, $account, $password, $fields, $updated) {
if (empty($updated)) {
watchdog('user', 'New user: %name %email.', array('%name' => $account->name, '%email' => '<' . $account->mail . '>'), WATCHDOG_NOTICE, l(t('edit'), 'user/' . $account->uid . '/edit'));
}
return;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,110 @@
<?php
/**
* @file
* Drush integration for the User Import module.
*/
function user_import_drush_help($command) {
switch ($command) {
case 'drush:user-import':
return dt('Queue an import of users from a CSV file');
case 'error:template-not-found':
return dt('Template not found');
case 'error:file-not-found':
return dt('File not found');
case 'error:no-default-template':
return dt('There is no default template configured');
}
}
/**
* Implementation of hook_drush_command().
*
* In this hook, you specify which commands your
* drush module makes available, what it does and
* description.
*
* Notice how this structure closely resembles how
* you define menu hooks.
*
* See `drush topic docs-commands` for a list of recognized keys.
*
* @return
* An associative array describing your command(s).
*/
function user_import_drush_command() {
$commands = array();
$commands['user-import'] = array(
'description' => dt('Queue an import of users'),
'arguments' => array(
'file' => dt('The CSV file with user data'),
'template' => dt('Name of the template to use (optional, if not provided the default template is used)'),
),
'examples' => array(
dt('standard example') => 'drush user-import users.csv',
),
);
return $commands;
}
function drush_user_import($original_file = NULL, $template_name = NULL) {
if (!file_exists($original_file)) {
return drush_set_error('file-not-found');
}
$original_file = realpath($original_file);
if ($template_name) {
$template = db_query("SELECT * FROM {user_import} WHERE name = :name AND setting = 'template'", array(':name' => $template_name))->fetchObject();
if (!$template) {
return drush_set_error('template-not-found');
}
}
else {
$template_id = variable_get('user_import_settings', '0');
if (!$template_id) {
return drush_set_error('no-default-template');
}
$template = db_query("SELECT * FROM {user_import} WHERE import_id = :import_id AND setting = 'template'", array(':import_id' => $template_id))->fetchObject();
if (!$template) {
return drush_set_error('template-not-found');
}
drush_print(dt('Using default settings template "!template"', array('!template' => $template->name)));
}
$template->options = unserialize($template->options);
$template->field_match = unserialize($template->field_match);
$template->roles = unserialize($template->roles);
$file = new stdClass();
$file->filepath = $original_file;
$file->filename = basename($original_file);
$destination = 'private://user_import/processing';
$filepath = file_unmanaged_copy($file->filepath, $destination, FILE_EXISTS_RENAME);
// initialize import from template
$import = new stdClass();
$import->oldfilename = basename($original_file);
$import->filename = $file->filename;
$import->filepath = $filepath;
$import->started = time();
$import->field_match = $template->field_match;
$import->roles = $template->roles;
$import->options = $template->options;
$import->setting = 'import';
$result = drupal_write_record('user_import', $import);
if ($result == SAVED_NEW) {
drush_print(dt('Successfully queued user import. The original CSV file !file has been copied to the Drupal installation and can be removed.', array('!file' => $original_file)));
}
else {
drush_set_error('import_failed', dt('Unable to queue the user import.'));
}
}

View File

@@ -0,0 +1,339 @@
<?php
function _user_import_process($settings) {
// Load supported modules
user_import_load_supported();
$remaining_data = FALSE;
$line_max = variable_get('user_import_line_max', 1000);
$import_max = variable_get('user_import_max', 250);
$field_match = _user_import_unconcatenate_field_match($settings['field_match']);
$update_setting = _user_import_update_user_check($settings['options']['update_user']);
$update_setting_per_module = $settings['options']['update_user'];
$username_data = array();
$username_order = array();
$username_abbreviate = array();
$first_line_skip = 0;
$delimiter = isset($settings['delimiter']) && !empty($settings['delimiter']) ? $settings['delimiter'] : ',';
ini_set('auto_detect_line_endings', TRUE);
$handle = @fopen($settings['filepath'], "r");
// move pointer to where test/import last finished
if ($settings['pointer'] != 0) fseek($handle, $settings['pointer']);
// start count of imports on this cron run
$processed_counter = 0;
while ($data = fgetcsv($handle, $line_max, $delimiter)) {
$errors = user_import_errors(FALSE, TRUE);
// if importing, check we are not over max number of imports per cron
if ($settings['setting'] == 'import' && $processed_counter >= $import_max) {
$remaining_data = TRUE;
break;
}
// don't process empty lines
$line_filled = (count($data) == 1 && drupal_strlen($data[0]) == 0) ? FALSE : TRUE;
if ($line_filled) {
// check if this is first line - if so should we skip?
if (!empty($settings['first_line_skip']) && $settings['processed'] == 0) {
// reset to false on second process
$first_line_skip = ($first_line_skip === 0) ? TRUE : FALSE;
}
if (!$first_line_skip) {
unset($errors, $fields);
reset($field_match);
$password = '';
// Process data cell.
foreach ($field_match as $column_id => $column_settings) {
$type = $column_settings['type'];
$field_id = $column_settings['field_id'];
// Skip if this is a field used as part of a username but
// not otherwise mapped for import.
if ($type != 'username_part') {
$fields[$type][$field_id] = module_invoke_all('user_import_data', $settings, $update_setting, $column_settings, $type, $field_id, $data, $column_id);
}
// Read in data if present for concatenating a user name.
if ($column_settings['username'] > 0) {
$username_data[$column_id] = $data[$column_id];
$username_order[$column_id] = $column_settings['username'];
$username_abbreviate[$column_id] = $column_settings['abbreviate'];
}
}
$errors = user_import_errors();
$account = array();
$existing_account = FALSE;
$updated = FALSE;
// if we update existing users matched by email (and therefore passed validation even if this email already exists)
// look for and use an existing account.
if ($update_setting && !empty($fields['user']['email'][0])) {
$existing_account = user_load_by_mail($fields['user']['email'][0]);
if ($existing_account) $account = (array)$existing_account;
}
// if $account['uid'] is not empty then we can assume the account is being updated
$account_additions = module_invoke_all('user_import_pre_save', $settings, $account, $fields, $errors, $update_setting_per_module);
foreach ($account_additions as $field_name => $value) {
$account[$field_name] = $value;
}
if (empty($errors)) {
if ($settings['setting'] == 'import') {
if ($existing_account) {
$account = user_save($existing_account, $account);
$updated = TRUE;
}
else {
// Only set a user name if we are not updating an existing record.
$account['name'] = _user_import_create_username($username_order, $username_data, $username_abbreviate, $settings['username_space']);
$password = $account['pass'];
$account = user_save('', $account);
}
module_invoke_all('user_import_after_save', $settings, $account, $password, $fields, $updated, $update_setting_per_module);
$processed_counter++;
}
$settings['valid']++;
}
// If first line is skipped it doesn't count as processed.
$settings['processed']++;
}
$settings['pointer'] = ftell($handle);
// save lines that have fatal errors
if (!empty($errors)) {
$account_email = isset($account['email']) ? $account['email'] : '';
_user_import_errors_display_save($settings['import_id'], $fields, $account_email, $errors);
}
}
$settings['setting'] = _user_import_save_progress($settings['setting'], $remaining_data, $settings['pointer'], $settings['processed'], $settings['valid'], $settings['import_id']);
}
// Save progress.
$settings['setting'] = _user_import_save_progress($settings['setting'], $remaining_data, $settings['pointer'], $settings['processed'], $settings['valid'], $settings['import_id'], TRUE);
if ($settings['setting'] == 'imported') {
module_invoke_all('user_import_imported', $settings['import_id'], $settings);
}
fclose($handle);
return $settings;
}
// errors for user being imported
function user_import_errors($error = FALSE, $clear = FALSE) {
static $errors = array();
if ($clear) $errors = array();
if ($error) $errors[] = $error;
return $errors;
}
function _user_import_create_username($order, $data, $abbreviate, $username_space) {
$username = '';
if (is_array($order)) {
asort($order);
//reset($order);
//while (list ($file_column, $sequence) = each ($order)) {
foreach ($order as $file_column => $sequence) {
if (!empty($username) && !empty($username_space)) {
$username .= ' ';
}
if ($abbreviate[$file_column] == 1) {
//$username .= trim(drupal_strtoupper(chr(ord($data[$file_column]))));
$first_character = trim($data[$file_column]);
$first_character = drupal_substr($first_character, 0, 1);
$username .= drupal_strtoupper($first_character);
}
else {
$username .= trim($data[$file_column]);
}
}
}
if (empty($username)) $username = _user_import_random_username();
$username = _user_import_sanitise_username($username);
$username = _user_import_unique_username($username, TRUE);
return $username;
}
/**
* conform to Drupal username rules
*/
function _user_import_sanitise_username($username) {
// username cannot contain an illegal character
$username = preg_replace('/[^\x80-\xF7 [:alnum:]@_.-]/', '', $username);
$username = preg_replace(
'/[\x{80}-\x{A0}' . // Non-printable ISO-8859-1 + NBSP
'\x{AD}' . // Soft-hyphen
'\x{2000}-\x{200F}' . // Various space characters
'\x{2028}-\x{202F}' . // Bidirectional text overrides
'\x{205F}-\x{206F}' . // Various text hinting characters
'\x{FEFF}' . // Byte order mark
'\x{FF01}-\x{FF60}' . // Full-width latin
'\x{FFF9}-\x{FFFD}' . // Replacement characters
'\x{0}]/u',
'', $username);
// username cannot contain multiple spaces in a row
$username = preg_replace('/[ ]+/', ' ', $username);
// username must be less than 56 characters
$username = substr($username, 0, 56);
// username cannot begin or end with a space
$username = trim($username);
return $username;
}
/**
* deal with duplicate usernames
*/
function _user_import_unique_username($username, $start = FALSE) {
static $suffix = 1;
if ($start) $suffix = 1;
if ($suffix < 2) {
$duplicate = db_query_range('SELECT uid from {users} where name = :name', 0, 1, array(':name' => $username))->fetchField();
}
else {
$duplicate = db_query_range('SELECT uid from {users} where name = :name', 0, 1, array(':name' => "$username $suffix"))->fetchField();
}
// loop until name is valid
if (!empty($duplicate)) {
$suffix++;
// If we loop to many times PHP will kill the script,
// for large user bases that might be a problem with popular names.
if ($suffix > 10) {
$suffix = $suffix * mt_rand(10, 99);
}
_user_import_unique_username($username);
}
// add number at end of username if it already exists
$username = ($suffix < 2) ? $username : "$username $suffix";
return $username;
}
// Update settings for existing import
function _user_import_settings_update($pointer, $processed, $valid, $setting, $import_id) {
if (empty($import_id)) return;
db_update('user_import')
->fields(array(
'pointer' => $pointer,
'processed' => $processed,
'valid' => $valid,
'setting' => $setting
))
->condition('import_id', $import_id)
->execute();
}
function _user_import_random_username() {
$username = '';
$vowels = 'aoueiy';
$consonants = 'bcdfghjklmnpqrstvwxz';
$length = 8;
mt_srand((double)microtime() * 10000000);
$next_vowel = 0;
for ($count = 0; $count <= $length; $count++) {
if ($next_vowel) {
$rand = mt_rand(0, 5);
$username .= $vowels{$rand};
$next_vowel = 0;
}
else {
$rand = mt_rand(0, 19);
$username .= $consonants{$rand};
$next_vowel = 1;
}
}
return $username;
}
// check if any updates are to be made
function _user_import_update_user_check($settings) {
foreach ($settings as $setting) {
if ($setting != UPDATE_NONE) return TRUE;
}
return FALSE;
}
function _user_import_errors_display_save($import_id, $data, $email, $errors) {
$data['email'] = $email;
$id = db_insert('user_import_errors')
->fields(array(
'import_id' => $import_id,
'data' => serialize($data),
'errors' => serialize($errors),
))
->execute();
return;
}
/**
* Save progress status and counter of the import.
*/
function _user_import_save_progress($status, $remaining_data, $pointer, $processed, $valid, $import_id, $status_check = FALSE) {
if ($status_check) {
if ($status == 'import' && !$remaining_data) $status = 'imported';
if ($status == 'test') $status = 'tested';
}
_user_import_settings_update($pointer, $processed, $valid, $status, $import_id);
return $status;
}

View File

@@ -0,0 +1,19 @@
name = User Import
description = "Import users into Drupal from a CSV file."
core = 7.x
package = Deployment
files[] = user_import.module
files[] = user_import.install
files[] = user_import.admin.inc
files[] = user_import.import.inc
files[] = user_import.test
; Information added by Drupal.org packaging script on 2014-03-09
version = "7.x-2.2"
core = "7.x"
project = "user_import"
datestamp = "1394331207"

View File

@@ -0,0 +1,263 @@
<?php
/**
* @file
* Import and update users from a comma separated file (csv).
*/
/**
* Implementation of hook_schema().
*/
function user_import_schema() {
$schema['user_import'] = array(
'description' => t("Settings for each import, and import setting templates."),
'fields' => array(
'import_id' => array(
'description' => t("ID key of import or template."),
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
'disp-width' => '10'
),
'name' => array(
'description' => t("Label of import template, only used if this is an import template."),
'type' => 'varchar',
'length' => '25',
'not null' => TRUE,
'default' => ''
),
'auto_import_directory' => array(
'description' => t("Name of directory associated with an import template."),
'type' => 'varchar',
'length' => '255',
'not null' => TRUE,
'default' => ''
),
'filename' => array(
'description' => t("Name of file being used as source of data for import."),
'type' => 'varchar',
'length' => '50',
'not null' => TRUE,
'default' => ''
),
'oldfilename' => array(
'description' => t("Original name of file being used as source of data for import."),
'type' => 'varchar',
'length' => '50',
'not null' => TRUE,
'default' => ''
),
'filepath' => array(
'description' => t("Path to file being used as source of data for import."),
'type' => 'text',
'size' => 'small',
'not null' => TRUE
),
'started' => array(
'description' => t("Datestamp of when import was started."),
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'disp-width' => '11'
),
'pointer' => array(
'description' => t("Pointer to where test/import last finished."),
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'disp-width' => '10'
),
'processed' => array(
'description' => t("Number of users processed by import."),
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'disp-width' => '10'
),
'valid' => array(
'description' => t("Number of users processed without errors."),
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'disp-width' => '10'
),
'field_match' => array(
'description' => t("Settings for how data matches to Drupal fields."),
'type' => 'text',
'size' => 'big',
'not null' => TRUE,
'serialize' => TRUE
),
'roles' => array(
'description' => t("Roles to give imported users."),
'type' => 'text',
'size' => 'big',
'not null' => TRUE,
'serialize' => TRUE
),
'options' => array(
'description' => t("Store of all other options for import. Most of the other settings in this table will be moved into here in future."),
'type' => 'text',
'size' => 'big',
'not null' => TRUE,
'serialize' => TRUE
),
'setting' => array(
'description' => t("Status of import, or whether it is an import template."),
'type' => 'varchar',
'length' => '10',
'not null' => TRUE,
'default' => ''
)
),
'primary key' => array('import_id'),
);
$schema['user_import_errors'] = array(
'description' => t("Record of errors encountered during an import."),
'fields' => array(
'import_id' => array(
'description' => t("ID key of import or template."),
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'disp-width' => '10'
),
'data' => array(
'description' => t("Data (matched to fields) for user that failed to import due to error."),
'type' => 'text',
'size' => 'big',
'not null' => TRUE,
'serialize' => TRUE
),
'errors' => array(
'description' => t("Error(s) encountered for user that failed to import."),
'type' => 'text',
'size' => 'big',
'not null' => TRUE,
'serialize' => TRUE
)
),
'indexes' => array(
'import_id' => array('import_id')
),
);
return $schema;
}
function user_import_update_1() {
$ret = array();
_system_update_utf8(array('user_import', 'user_import_errors'));
return $ret;
}
function user_import_update_2() {
$ret = array();
db_add_column($ret, 'user_import', 'options', 'longtext');
return $ret;
}
function user_import_update_3() {
$ret = array();
db_drop_primary_key($ret, 'user_import');
db_change_field($ret, 'user_import', 'iid', 'import_id', array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'), array('primary key' => array('import_id')));
db_change_field($ret, 'user_import', 'first_line', 'first_line_skip', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'disp-width' => '10'), array('primary key' => array('import_id')));
db_drop_index($ret, 'user_import_errors', 'import_id');
db_change_field($ret, 'user_import_errors', 'iid', 'import_id', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'disp-width' => '10'));
db_add_index($ret, 'user_import_errors', 'import_id', array('import_id'));
return $ret;
}
function user_import_update_4() {
$ret = array();
db_drop_index($ret, 'user_import_errors', 'import_id');
db_change_field($ret, 'user_import_errors', 'error', 'errors', array('type' => 'text', 'size' => 'big', 'not null' => TRUE, 'serialize' => TRUE));
db_add_index($ret, 'user_import_errors', 'import_id', array('import_id'));
return $ret;
}
function user_import_update_5() {
$ret = array();
db_drop_index($ret, 'user_import_errors', 'import_id');
db_change_field($ret, 'user_import_errors', 'errors', 'errors', array('type' => 'text', 'size' => 'big', 'not null' => TRUE, 'serialize' => TRUE));
db_add_index($ret, 'user_import_errors', 'import_id', array('import_id'));
return $ret;
}
function user_import_update_6001() {
// Rebuild schema cache
drupal_get_schema('user_import', TRUE);
return array();
}
/**
* Move settings into the 'options' column.
*/
function user_import_update_6002() {
$ret = array();
$result = db_query("SELECT * FROM {user_import}");
// Update each import.
while ($import = db_fetch_array($result)) {
$options = unserialize($import['options']);
$options['first_line_skip'] = $import['first_line_skip'];
$options['contact'] = $import['contact'];
$options['username_space'] = $import['username_space'];
$options['send_email'] = $import['send_email'];
//Avoid using update_sql() as it has issues with serialized data.
db_query("UPDATE {user_import} SET options = '%s' WHERE import_id = %d", serialize($options), $import['import_id']);
}
$ret[] = update_sql('ALTER TABLE {user_import} DROP COLUMN first_line_skip');
$ret[] = update_sql('ALTER TABLE {user_import} DROP COLUMN contact');
$ret[] = update_sql('ALTER TABLE {user_import} DROP COLUMN username_space');
$ret[] = update_sql('ALTER TABLE {user_import} DROP COLUMN send_email');
return $ret;
}
/**
* Change the Roles column to LOMGTEXT.
*/
function user_import_update_6003() {
$ret = array();
db_change_field($ret, 'user_import', 'roles', 'roles', array('type' => 'text', 'size' => 'big', 'not null' => TRUE, 'serialize' => TRUE));
return $ret;
}
/**
* Add database field to store the name of a directory associated with an import template.
*
**/
function user_import_update_7200(&$sandbox) {
$field = array(
'description' => t("Name of directory associated with an import template."),
'type' => 'varchar',
'length' => '255',
'not null' => TRUE,
'default' => '',
);
db_add_field('user_import', 'auto_import_directory', $field);
}
/**
* Implementation of hook_uninstall().
*/
function user_import_uninstall() {
variable_del('user_import_settings');
variable_del('user_import_max');
variable_del('user_import_line_max');
variable_del('user_export_checked_usernames');
variable_del('user_import_profile_date_format');
}

View File

@@ -0,0 +1,817 @@
<?php
/**
* @file
* Import or update users with data from a comma separated file (csv).
*/
// Update options for existing users
define ('UPDATE_NONE', 0);
define ('UPDATE_REPLACE', 1);
define ('UPDATE_ADD', 2);
/**
* - - - - - - - - HOOKS - - - - - - - -
*/
/**
* Implementation of hook_theme().
*/
function user_import_theme() {
return array(
'user_import_list' => array(
'variables' => array(),
),
'user_import_edit' => array(
'render element' => 'form',
),
'user_import_errors_display' => array(
'variables' => array('settings' => NULL),
),
'user_import_username_errors' => array(
'variables' => array('errors' => NULL),
),
);
}
/**
* Implementation of hook_help().
*/
// function user_import_help($path, $arg) {
// switch ($path) {
// case 'admin/people/user_import':
// return t("Import or update users from a comma separated file (csv). Click 'Import' to start a new import.");
// }
// }
/**
* Implementation of hook_perm().
*/
function user_import_permission() {
return array(
'import users' => array(
'title' => t('Import users'),
'description' => t('Import users.'),
),
);
}
/**
* Implementation of hook_menu().
*/
function user_import_menu() {
$items['admin/people/user_import'] = array(
'title' => 'Import',
'description' => 'Import or update users from a comma separated file (csv).',
'page callback' => 'user_import_list',
'access arguments' => array('import users'),
'type' => MENU_LOCAL_TASK,
'file' => 'user_import.admin.inc',
);
$items['admin/people/user_import/list'] = array(
'title' => 'List Imports',
'access arguments' => array('import users'),
'weight' => -10,
'type' => MENU_DEFAULT_LOCAL_TASK,
'file' => 'user_import.admin.inc',
);
$items['admin/people/user_import/add'] = array(
'title' => 'New Import',
'page callback' => 'user_import_preferences',
'access arguments' => array('import users'),
'weight' => -5,
'type' => MENU_LOCAL_TASK,
'file' => 'user_import.admin.inc',
);
$items['admin/people/user_import/continue'] = array(
'title' => 'Continue',
'page callback' => 'user_import_continue',
'access arguments' => array('import users'),
'type' => MENU_CALLBACK,
'file' => 'user_import.admin.inc',
);
$items['admin/people/user_import/import'] = array(
'title' => 'Import',
'page callback' => 'user_import_import',
'access arguments' => array('import users'),
'type' => MENU_CALLBACK,
'file' => 'user_import.admin.inc',
);
$items['admin/people/user_import/delete'] = array(
'title' => 'Delete Import',
'page callback' => 'user_import_delete',
'access arguments' => array('import users'),
'type' => MENU_CALLBACK,
'file' => 'user_import.admin.inc',
);
$items['admin/people/user_import/configure'] = array(
'title' => 'Configure',
'page callback' => 'drupal_get_form',
'page arguments' => array('user_import_configure_form'),
'access arguments' => array('import users'),
'type' => MENU_LOCAL_TASK,
'file' => 'user_import.admin.inc',
);
$items['user_import/delete'] = array(
'title' => 'Remove Info',
'page callback' => 'user_import_limited_delete',
'type' => MENU_CALLBACK,
'access arguments' => array('limited user import'),
);
$items['user_import/errors'] = array(
'title' => 'Import Errors',
'page callback' => 'user_import_limited_errors',
'type' => MENU_CALLBACK,
'access arguments' => array('limited user import'),
);
return $items;
}
/**
* Implementation of hook_cron().
*/
function user_import_cron() {
module_load_include('inc', 'user_import', 'user_import.import');
// Continue any on-going imports.
user_import_continue_imports();
// Check for new imports.
user_import_trigger_imports();
}
/**
* Continue any on-going imports, durring a cron run.
*
**/
function user_import_continue_imports() {
$imports = _user_import_settings_select();
if ($imports) {
foreach ($imports as $import) {
if ($import['setting'] == 'test' || $import['setting'] == 'import') {
_user_import_process($import);
}
}
}
}
/**
* Trigger imports if new files are found durring a cron run.
*/
function user_import_trigger_imports() {
$auto_imports_enabled = variable_get('user_import_auto_imports_enabled', FALSE);
if (empty($auto_imports_enabled)) {
return;
}
// Load import functions.
module_load_include('inc', 'user_import', 'user_import.admin');
// Get list of templates to check.
$imports = db_query("SELECT * FROM {user_import} WHERE auto_import_directory != '' AND setting = 'template'");
foreach ($imports as $import) {
// Check for file in the uploads directory of this template.
$directory = 'private://user_import/uploads/' . $import->auto_import_directory;
$files = file_scan_directory($directory, '/.*$/');
foreach ($files as $import_file) {
// Move file to processing directory.
$filename_new = $import_file->filename . '-' . rand(1000000, 2000000);
$import_file_new = file_unmanaged_move($import_file->uri, 'private://user_import/processing/' . $filename_new);
// Create import.
// Get template.
$settings = _user_import_settings_select($import->import_id);
$import_id = '';
$name = '';
$pointer = 0;
$processed = 0;
$valid = 0;
$field_match = isset($settings['field_match']) ? serialize($settings['field_match']) : '';
$roles = isset($settings['roles']) ? serialize($settings['roles']) : '';
$options = isset($settings['options']) ? serialize($settings['options']) : '';
$setting = 'import';
$file->filename = $filename_new;
$file->oldfilename = $import_file->filename;
$file->filepath = 'private://user_import/processing/' . $filename_new;
$import_id = user_import_import_set($name, $file, $pointer, $processed, $valid, $field_match, $roles, $options, $setting, $import_id);
$settings = _user_import_settings_select($import_id);
_user_import_process($settings);
}
}
return;
// Get template.
$settings = _user_import_settings_select(2);
foreach ($files as $filename) {
if ($filename == 'sample.txt') {
// Check if it's used for an import already.
$imported = db_query('SELECT import_id FROM {user_import} WHERE filename = :filename', array(':filename' => $filename))->fetchField();
if (!$imported) {
$import_id = '';
$name = '';
$pointer = 0;
$processed = 0;
$valid = 0;
$field_match = isset($settings['field_match']) ? serialize($settings['field_match']) : '';
$roles = isset($settings['roles']) ? serialize($settings['roles']) : '';
$options = isset($settings['options']) ? serialize($settings['options']) : '';
$setting = 'import';
$file->filename = $filename;
$file->oldfilename = $filename;
$file->filepath = drupal_get_path('module', 'user_import') . '/' . $filename;
$import_id = user_import_import_set($name, $file, $pointer, $processed, $valid, $field_match, $roles, $options, $setting, $import_id);
$settings = _user_import_settings_select($import_id);
_user_import_process($settings);
}
}
}
return;
}
// - - - - - - - - FORMS - - - - - - - -
/**
* Saves options on content type configuration form
* @todo check if this is cruft
* @todo check $form['type']
*/
function user_import_content_type_submit($form, &$form_state) {
// user import template for Organic Groups content type
$templates = variable_get('user_import_og_template', array());
$templates[$form['type']] = $form_state['values']['user_import_og'];
variable_set('user_import_og_template', $templates);
}
// - - - - - - - - PAGES - - - - - - - -
function user_import_limited_errors($import_id = NULL, $template_id = NULL) {
if (empty($import_id) || !is_numeric($import_id)) {
drupal_goto('user_import/' . $template_id);
}
$pager_id = 1;
$max = 25;
$import = _user_import_settings_select($import_id);
$output = '';
$total = db_query('SELECT count(data) FROM {user_import_errors} WHERE :import_id = %d', array(':import_id' => $import['import_id']))->fetchField();
if (empty($total)) {
$output .= theme('There were no import errors');
}
else {
$header = array(
array('data' => t('ID'), 'field' => 'import_id', 'sort' => 'desc'),
array('data' => t('Data'), 'field' => 'data'),
array('data' => t('Errors'), 'field' => 'errors')
);
$query = db_select('user_import_errors')
->extend('PagerDefault')
->extend('TableSort');
$query
->condition('import_id', $import['import_id'])
->limit($max)
->orderByHeader($header);
$result = $query->execute();
foreach ($result as $line) {
$file_lines[] = array('data' => unserialize($line->data), 'errors' => unserialize($line->errors));
}
$output .= theme('user_import_errors_display', array('import' => $import, 'file_lines' => $file_lines, 'total' => $total));
$output .= theme('pager', array('max' => $max, 'pager_id' => $pager_id));
}
$output .= l(t('Return'), "user_import/$template_id/$import_id");
return $output;
}
/**
* @param null $import_id
* @param null $template_id
*/
function user_import_limited_delete($import_id = NULL, $template_id = NULL) {
user_import_delete($import_id, "user_import/$template_id");
}
// - - - - - - - - THEMES - - - - - - - -
/**
* @return string
*/
function theme_user_import_list() {
$output = '';
$imports = _user_import_settings_select();
if (!$imports) return ' ';
foreach ($imports as $import) {
// header labels
$import_label = ($import['setting'] == 'tested' || $import['setting'] == 'test') ? t('importable') : t('imported');
$header = array(t('file'), t('started'), t('processed'), $import_label, t('errors'), t('status'));
// info row
$errors = db_query('SELECT COUNT(import_id) FROM {user_import_errors} WHERE import_id = :import_id', array(':import_id' => $import['import_id']))->fetchField();
$errors_link = ($errors == 0) ? '0' : l($errors, 'admin/people/user_import/errors/' . $import['import_id']);
$rows[0] = array(
check_plain($import['oldfilename']),
format_date($import['started'], 'small'),
array("data" => $import['processed'], "align" => 'center'),
array("data" => $import['valid'], "align" => 'center'),
array("data" => $errors_link, "align" => 'center'),
$import['setting'],
);
$output .= theme('table', array('header' => $header, 'rows' => $rows));
// action buttons
$delete_link = l(t('Delete'), 'admin/people/user_import/delete/' . $import['import_id']);
$continue_link = l(t('Continue Processing'), 'admin/people/user_import/continue/' . $import['import_id']);
$import_link = l(t('Import'), 'admin/people/user_import/import/' . $import['import_id']);
$output .= $delete_link;
if ($import['setting'] == 'tested' || $import['setting'] == 'test') $output .= ' | ' . $import_link;
if ($import['setting'] == 'test' || $import['setting'] == 'import') $output .= ' | ' . $continue_link;
}
return $output;
}
function theme_user_import_edit($variables) {
$output = '';
$rows = array();
$form = $variables['form'];
$header = array(t('CSV column'), t('Drupal fields'), t('Username'), t('Abbreviate'));
foreach (element_children($form['field_match']) as $key) {
$rows[] = array(
drupal_render($form['field_match'][$key]['csv']),
drupal_render($form['field_match'][$key]['field_match']),
drupal_render($form['field_match'][$key]['username']),
drupal_render($form['field_match'][$key]['abbreviate']),
);
}
$form['field_match']['#value'] = theme('table', array('header' => $header, 'rows' => $rows));
if (isset($form['remove'])) {
$output .= drupal_render($form['remove']);
}
if (isset($form['options'])) {
$output .= drupal_render($form['options']);
}
if (isset($form['field_match'])) {
$output .= drupal_render($form['field_match']);
}
$output .= drupal_render_children($form);
return $output;
}
function theme_user_import_errors_display($settings) {
$output = '';
$header[0] = t('Email Address');
$data = $settings['file_lines'];
$total = $settings['total'];
$oldfilename = $settings['import']['oldfilename'];
$field_match = $settings['import']['field_match'];
$error_count = 0;
$field_match = _user_import_unconcatenate_field_match($field_match);
foreach ($data as $data_row) {
$row = array();
foreach ($data_row['data'] as $type => $fields) {
if (!empty($fields)) {
foreach ($fields as $field_id => $field_data) {
foreach ($field_match as $column_info) {
if ($column_info['type'] == $type && $column_info['field_id'] == $field_id) {
if (!empty($column_info['username'])) {
$header[$column_info['username']] = t('Name %sort', array('%sort' => $column_info['username']));
$row[$column_info['username']] = array("data" => $field_data[0], "align" => "left");
}
if ($column_info['field_id'] == 'email') {
$row[0] = array("data" => $field_data[0], "align" => "left");
}
}
}
}
}
}
ksort($row);
$row[] = implode('<br />', $data_row['errors']);
$rows[] = $row;
}
$output .= '<p>' . t('<strong>CSV File:</strong> %file', array('%file' => $oldfilename)) . '<br />';
$output .= t('<strong>Errors:</strong> !total', array('!total' => $total)) . '</p>';
$header['errors'] = t('Errors');
// Output of table with the paging
$output .= theme('table',
array(
"header" => $header,
"rows" => $rows,
"attributes" => array(),
"sticky" => FALSE, // Table header will be sticky
"caption" => '',
"colgroups" => array(),
"empty" => t("There are no errors.") // The message to be displayed if table is empty
)
) . theme("pager");
//$output .= theme('table', array('header' => $header, 'rows' => $rows));
return $output;
}
function theme_user_import_username_errors($errors) {
if (empty($errors)) {
$output = '<p><strong>' . t('All usernames are OK.') . '</strong></p>';
}
else {
$header = array(t('User ID'), t('Email'), t('Username'), t('Error'));
$output = theme('table', array('header' => $header, 'errors' => $errors));
}
return $output;
}
// - - - - - - - - MISC - - - - - - - -
function _user_import_settings_save($settings) {
// Database field defaults.
$database_fields = array('import_id' => NULL,
'name' => '',
'auto_import_directory' => '',
'filename' => '',
'oldfilename' => '',
'filepath' => '',
'started' => 0,
'pointer' => 0,
'processed' => 0,
'valid' => 0,
'field_match' => array(),
'roles' => '',
'options' => array(),
'setting' => '',
);
// Form elements we never want to save in the options column.
$form_variables = array('form_id', 'form_token', 'form_build_id', 'cancel', 'import', 'submit', 'op', 0, 'return_path');
$form_variables = array_flip($form_variables);
// Remove settings we don't need in the options column.
$options = array_diff_key($settings, $database_fields);
$options = array_diff_key($options, $form_variables);
// Optimise Email Domain option if it's set.
if (!empty($options['email_domain'])) {
$options['email_domain'] = trim($options['email_domain']);
if (substr($options['email_domain'], 0, 1) != '@') {
$options['email_domain'] = '@'. $options['email_domain'];
}
}
// Set defaults for options.
foreach ($options as $key => $value) {
$settings['options'][$key] = isset($settings[$key]) ? $settings[$key] : '';
}
// Optimise Email Domain option if it's set.
if (!empty($settings['options']['email_domain'])) {
$settings['options']['email_domain'] = trim($settings['options']['email_domain']);
if (substr($settings['options']['email_domain'], 0, 1) != '@') {
$settings['options']['email_domain'] = '@'. $settings['options']['email_domain'];
}
}
// Set defaults for fields.
foreach ($database_fields as $key => $value) {
$settings[$key] = isset($settings[$key]) ? $settings[$key] : $value;
}
// Set default values.
$import_id = isset($settings['import_id']) ? $settings['import_id'] : '';
$name = isset($settings['name']) ? trim($settings['name']) : '';
$pointer = isset($settings['pointer']) ? $settings['pointer'] : 0;
$processed = isset($settings['processed']) ? $settings['processed'] : 0;
$valid = isset($settings['valid']) ? $settings['valid'] : 0;
$field_match = isset($settings['field_match']) ? serialize($settings['field_match']) : '';
$roles = isset($settings['roles']) ? serialize($settings['roles']) : '';
$options = isset($settings['options']) ? serialize($settings['options']) : '';
$setting = isset($settings['setting']) ? $settings['setting'] : '';
// Only set an auto import directory if saving a template.
if (isset($settings['auto_import_directory']) && $settings['setting'] == 'template') {
$auto_import_directory = $settings['auto_import_directory'];
}
else {
$auto_import_directory = '';
}
$file->filename = isset($settings['filename']) ? $settings['filename'] : '';
$file->oldfilename = isset($settings['oldfilename']) ? $settings['oldfilename'] : '';
$file->filepath = isset($settings['filepath']) ? $settings['filepath'] : '';
$settings['import_id'] = user_import_import_set($name, $file, $pointer, $processed, $valid, $field_match, $roles, $options, $setting, $auto_import_directory, $import_id);
return $settings;
}
function user_import_import_set($name = '', $file = '', $pointer = 0, $processed = 0, $valid = 0, $field_match = '', $roles = '', $options = '', $setting = '', $auto_import_directory = '', $import_id = '') {
// Update settings for existing import.
if (!empty($import_id)) {
db_update('user_import')
->fields(array(
'name' => $name,
'auto_import_directory' => $auto_import_directory,
'filename' => $file->filename,
'oldfilename' => $file->oldfilename,
'filepath' => $file->filepath,
'pointer' => $pointer,
'processed' => $processed,
'valid' => $valid,
'field_match' => $field_match,
'roles' => $roles,
'options' => $options,
'setting' => $setting
))
->condition('import_id', $import_id)
->execute();
}
else {
$import_id = db_insert('user_import')
->fields(array(
'name' => $name,
'auto_import_directory' => $auto_import_directory,
'filename' => $file->filename,
'oldfilename' => $file->oldfilename,
'filepath' => $file->filepath,
'started' => time(),
'pointer' => $pointer,
'processed' => $processed,
'valid' => $valid,
'field_match' => $field_match,
'roles' => $roles,
'options' => $options,
'setting' => $setting
))
->execute();
}
return $import_id;
}
/**
* Return either a single import setting, or all template, or all non-template settings.
*/
function _user_import_settings_select($import_id = NULL, $template = FALSE) {
$import = array();
if (!empty($import_id) && !is_numeric($import_id)) return;
if (!empty($import_id)) {
$sql = 'SELECT * FROM {user_import} WHERE import_id = :import_id';
if ($template) $sql .= " AND setting = 'template'";
$import = (array)db_query_range($sql, 0, 1, array(':import_id' => $import_id))->fetchObject();
if (empty($import)) return FALSE;
$import['field_match'] = unserialize($import['field_match']);
$import['roles'] = unserialize($import['roles']);
$import['options'] = unserialize($import['options']);
if (is_array($import['options'])) {
foreach ($import['options'] as $key => $value) {
$import[$key] = $value;
}
}
}
else {
$query = ($template) ? "SELECT * FROM {user_import} WHERE setting = 'template'" : "SELECT * FROM {user_import} WHERE setting <> 'template' ORDER BY started DESC";
$result = db_query($query);
foreach ($result as $row_data) {
$row = (array)$row_data;
$row['field_match'] = unserialize($row['field_match']);
$row['roles'] = unserialize($row['roles']);
$row['options'] = unserialize($row['options']);
foreach ($row['options'] as $key => $value) {
$row[$key] = $value;
}
$import[] = $row;
}
}
return $import;
}
function _user_import_settings_deletion($import_id) {
$sql = 'SELECT auto_import_directory FROM {user_import} WHERE import_id = :import_id';
$auto_import_directory = db_query_range($sql, 0, 1, array(':import_id' => $import_id))->fetchField();
if (!empty($auto_import_directory)) {
$deleted = file_unmanaged_delete_recursive('private://user_import/uploads/' . $auto_import_directory);
if ($deleted) {
watchdog('Usr Import', t("Directory '%directory' has been deleted."), array('%directory' => $auto_import_directory));
}
}
db_delete('user_import')
->condition('import_id', $import_id)
->execute();
db_delete('user_import_errors')
->condition('import_id', $import_id)
->execute();
return;
}
// Used by user_import_og.module
function user_import_profile_load($user) {
$result = db_query('SELECT f.name, f.type, f.fid, v.value FROM {profile_field} f INNER JOIN {profile_values} v ON f.fid = v.fid WHERE uid = %d', $user->uid);
foreach ($result as $field) {
if (empty($profile[$field->fid])) {
$profile[$field->fid] = _profile_field_serialize($field->type) ? unserialize($field->value) : $field->value;
}
}
return $profile;
}
function _user_import_unconcatenate_field_match($settings) {
$settings_updated = array();
foreach ($settings as $column_id => $values) {
if (!empty($values['field_match']) || !empty($values['username'])) {
// If we have a username but no field_match, set a special type.
// This allows us to skip saving the field but still use it in
// concatenating a username value.
if (empty($values['field_match'])) {
$values['type'] = 'username_part';
$values['field_id'] = 'username_part_' . $column_id;
}
else {
$key_parts = explode('-', $values['field_match']);
$values['type'] = array_shift($key_parts);
$values['field_id'] = implode('-', $key_parts);
}
unset($values['field_match']);
$settings_updated[$column_id] = $values;
}
}
return $settings_updated;
}
/**
* Loads the hooks for the supported modules.
*/
function user_import_load_supported() {
static $loaded = FALSE;
if (!$loaded) {
$path = drupal_get_path('module', 'user_import') . '/supported';
$files = drupal_system_listing("/\.inc$/", $path, 'name', 0);
foreach ($files as $module_name => $file) {
if (module_exists($module_name)) {
include_once($file->uri);
}
}
$loaded = TRUE;
}
}
/**
* Implementation of hook_simpletest().
*/
function user_import_simpletest() {
$module_name = 'user_import';
$dir = drupal_get_path('module', $module_name) . '/tests';
$tests = file_scan_directory($dir, '\.test$');
return array_keys($tests);
}
/**
* @param $filepath
* @param $filename
* @param $old_filename
* @param $ftp
* @param bool $message
*/
function _user_import_file_deletion($filepath, $filename, $old_filename, $ftp, $message = TRUE) {
$path_parts = explode(':', $filepath);
if ($path_parts[0] == 'private') {
// Delete files in the private files directory that have been uploaded by sftp/ftp.
file_unmanaged_delete($filepath);
}
else {
// Delete files uploaded through browser.
$file = new stdClass();
$file->uri = $filepath;
$file->filename = $filename;
$file->fid = db_query("SELECT fid FROM {file_managed} WHERE uri = :filepath", array(':filepath' => $filepath))->fetchField();
;
$removed = file_delete($file);
}
if (!$message) return;
if (empty($removed)) {
drupal_set_message(t("File error: file '%old_filename' (%filename) could not be deleted.", array('%old_filename' => $oldfilename, '%filename' => $filename)), 'error');
}
else {
drupal_set_message(t("File '%old_filename' was deleted.", array('%old_filename' => $old_filename)));
}
return;
}

View File

@@ -0,0 +1,586 @@
<?php
/**
* User Import module base test class.
*/
class UserImportWebTestCase extends DrupalWebTestCase {
protected $admin_user;
protected $user_importer;
/**
* Select CSV file (the included example file)
*/
function settingsFileSelect() {
$edit = array('file_ftp' => 1);
$this->drupalPost('admin/people/user_import/add', $edit, t('Next'));
/* Check file was selected */
$this->assertText(t('Use Different CSV File'), '[assert] File was selected');
}
function settingsEmailMatch(&$edit) {
$edit['field_match[5][field_match]'] = 'user-email';
}
function settingsIgnoreFirstLine(&$edit) {
$edit['first_line_skip'] = 1;
}
function checkAccountsExist($list_failures = FALSE) {
$failures_list = '';
$users_email = $this->usersList();
$failed = array();
foreach ($users_email as $mail) {
$user = user_load_by_mail($mail);
if (empty($user)) $failed[] = $mail;
}
if (!empty($failed) && $list_failures) {
$failures_list = t('. Failed accounts: %failures', array('%failures' => implode(', ', $failed)));
}
$this->assertTrue(empty($failed), t('Accounts created for users imported') . $failures_list);
}
/**
* List of users (email addresses) being imported
* To Do - Generate this dynamically, bearing in mind it could be used for stress testing
*/
function usersList() {
return array(
'john@example.com',
'mandy@example.com',
'charles@example.com',
'sarah@example.com',
'sarah_smith@example.com',
'helen@example.com',
'claire@example.com',
'victoria@example.com',
'james@example.com',
'anna@example.com',
'tino@example.com',
'sofia@example.com',
'steve@example.com',
'lucy@example.com',
'angie@example.com',
'carmen@example.com',
'paul@example.com',
'jason@example.com',
'mike@example.com',
'mary@example.com',
'simon@example.com',
'kieran@example.com',
'arthur@example.com',
'gwen@example.com',
'chester@example.com',
'dorothy@example.com',
'cameron@example.com',
'trisha@example.com',
'david@example.com',
'peter@example.com',
'saul@example.com',
'noel@example.com',
'matt@example.com',
'aston@example.com',
'mille@example.com',
'ernest@example.com',
);
}
/**
* Store import ID
* - set on import settings page, retrieve on later tasks
*/
function importID($url = NULL) {
static $import_id = 0;
if (empty($import_id) && !empty($url)) {
$args = explode('/', $url);
$import_id = $args[7];
}
return $import_id;
}
/**
* SimpleTest core method: code run after each and every test method.
*/
function tearDown() {
// delete accounts of users imported
$users_email = $this->usersList();
foreach ($users_email as $mail) {
$account = user_load_by_mail($mail);
if (!empty($account)) user_delete($account->uid);
}
// delete the import
$import_id = $this->importID();
$this->assertTrue(!empty($import_id), t('Import ID: !id', array('!id' => $import_id)));
_user_import_settings_deletion($import_id);
// Always call the tearDown() function from the parent class.
parent::tearDown();
}
}
/**
* User Import module base test class.
*/
class UserImportBasicsTestCase extends UserImportWebTestCase {
public static function getInfo() {
return array(
'name' => 'Import Users (Basics)',
'description' => 'Import users from a CSV file, test basic functions.',
'group' => 'User Import',
);
}
function setUp() {
parent::setUp(array('user_import'));
$this->admin_user = $this->drupalCreateUser(array('administer users', 'access administration pages', 'access overlay'));
$this->user_importer = $this->drupalCreateUser(array('import users'));
}
/**
* User with right permissions creates import (with new settings)
* - test core functions
*/
function testCreateImport() {
// Prepare a user to do testing
$this->drupalLogin($this->user_importer);
// Select CSV file (the included example file)
$this->settingsFileSelect();
// import settings
$this->importID($this->getUrl()); // store import ID for later
$setting_edit = array();
$this->settingsEmailMatch($settings);
$this->settingsIgnoreFirstLine($settings);
$this->drupalPost($this->getUrl(), $settings, 'Import');
// check if users have been imported
$this->checkAccountsExist(TRUE);
}
}
/**
* Test import of user data into Profile module
*/
//class UserImportNodeprofileTestCase extends UserImportWebTestCase {
//
// public static function getInfo() {
// return array(
// 'name' => 'Import Users (Nodeprofile)',
// 'description' => 'Test import of user data into Nodeprofile module.',
// 'group' => 'User Import',
// );
// }
//
// function setUp() {
// parent::setUp('content', 'number', 'optionwidgets', 'text', 'link', 'date_api', 'date', 'node_import', 'content_profile', 'user_import');
// $this->admin_user = $this->drupalCreateUser(array('administer users', 'administer permissions', 'access administration pages', 'administer site configuration', 'administer content types', 'administer taxonomy'));
// $this->user_importer = $this->drupalCreateUser(array('import users'));
// }
//
// /**
// * User with right permissions creates import (with new settings)
// * - test import of user data into Nodeprofile module
// */
// function testCreateImport() {
// $this->drupalLogin($this->admin_user);
// // $this->drupalGet('admin/build/modules');
// // file_put_contents('output.html', $this->drupalGetContent());
//
// $this->nodeprofileConfiguration();
//
// // Prepare a user to do testing
// $this->drupalGet('logout'); // log out first
// $this->drupalLogin($this->user_importer);
//
// // Select CSV file (the included example file)
// $this->settingsFileSelect();
//
// // import settings
// $this->importID($this->getUrl()); // store import ID for later
// $settings = array();
// $this->settingsEmailMatch($settings);
// $this->settingsNodeprofileMatch($settings);
// $this->settingsIgnoreFirstLine($settings);
// $this->drupalPost($this->getUrl(), $settings, 'Import');
//
// // check if users have been imported
// $this->checkNodeprofileExist();
//
// }
//
// /**
// * Configure modules
// */
// function nodeprofileConfiguration() {
//
// // create Identity content type
// $edit = array('name' => 'Identity', 'type' => 'identity', 'title_label' => 'Title', 'body_label' => '', 'node_options[promote]' => 0, 'content_profile_use' => 1);
// $this->drupalPost('admin/content/types/add', $edit, t('Save content type'));
//
// // create First Name field
// $edit = array('_add_new_field[label]' => 'First Name', '_add_new_field[field_name]' => 'first_name', '_add_new_field[type]' => 'text', '_add_new_field[widget_type]' => 'text_textfield');
// $this->drupalPost('admin/content/node-type/identity/fields', $edit, t('Save'));
//
// $edit = array('required' => 1);
// $this->drupalPost('admin/content/node-type/identity/fields/field_first_name', $edit, t('Save field settings'));
//
// // create Last Name field
// $edit = array('_add_new_field[label]' => 'Last Name', '_add_new_field[field_name]' => 'last_name', '_add_new_field[type]' => 'text', '_add_new_field[widget_type]' => 'text_textfield');
// $this->drupalPost('admin/content/node-type/identity/fields', $edit, t('Save'));
//
// $edit = array('required' => 1);
// $this->drupalPost('admin/content/node-type/identity/fields/field_last_name', $edit, t('Save field settings'));
//
// // create Biography content type
// $edit = array('name' => 'Biography', 'type' => 'biography', 'title_label' => 'Title', 'body_label' => '', 'node_options[promote]' => 0, 'content_profile_use' => 1);
// $this->drupalPost('admin/content/types/add', $edit, t('Save content type'));
//
// // create CV field
// $edit = array('_add_new_field[label]' => 'CV', '_add_new_field[field_name]' => 'cv', '_add_new_field[type]' => 'text', '_add_new_field[widget_type]' => 'text_textarea');
// $this->drupalPost('admin/content/node-type/biography/fields', $edit, t('Save'));
//
// $edit = array('required' => 1, 'rows' => 5);
// $this->drupalPost('admin/content/node-type/biography/fields/field_cv', $edit, t('Save field settings'));
//
// // create Blog field (URL)
// $edit = array('_add_new_field[label]' => 'Blog', '_add_new_field[field_name]' => 'blog', '_add_new_field[type]' => 'link', '_add_new_field[widget_type]' => 'link');
// $this->drupalPost('admin/content/node-type/biography/fields', $edit, t('Save'));
//
// // create Birthday field (date)
// $edit = array('_add_new_field[label]' => 'Birthday', '_add_new_field[field_name]' => 'birthday', '_add_new_field[type]' => 'datestamp', '_add_new_field[widget_type]' => 'date_text');
// $this->drupalPost('admin/content/node-type/biography/fields', $edit, t('Save'));
//
// // create Interests Vocabulary
// $edit = array('name' => 'Interests', 'nodes[biography]' => 'biography', 'tags' => 1);
// $this->drupalPost('admin/content/taxonomy/add/vocabulary', $edit, t('Save'));
//
// $vocabularies = taxonomy_get_vocabularies('biography');
//
// foreach ($vocabularies as $vocabulary) {
// $this->vocabulary_id = $vocabulary->vid;
// }
//
// // create Contact Details contact type
// $edit = array('name' => 'Contact Details', 'type' => 'contact_details', 'title_label' => 'Title', 'body_label' => '', 'node_options[promote]' => 0, 'content_profile_use' => 1);
// $this->drupalPost('admin/content/types/add', $edit, t('Save content type'));
//
// // create Can Be Contacted field
// $edit = array('_add_new_field[label]' => 'Contact', '_add_new_field[field_name]' => 'can_be_contacted', '_add_new_field[type]' => 'number_integer', '_add_new_field[widget_type]' => 'optionwidgets_onoff');
// $this->drupalPost('admin/content/node-type/contact-details/fields', $edit, t('Save'));
//
// $edit = array('allowed_values' => "0
// 1|Can be contacted");
// $this->drupalPost('admin/content/node-type/contact-details/fields/field_can_be_contacted', $edit, t('Save field settings'));
//
// // create Contact Preference field
// $edit = array('_add_new_field[label]' => 'Contact Preference', '_add_new_field[field_name]' => 'contact_preference', '_add_new_field[type]' => 'text', '_add_new_field[widget_type]' => 'optionwidgets_select');
// $this->drupalPost('admin/content/node-type/contact-details/fields', $edit, t('Save'));
//
// $edit = array('allowed_values' => 'email|email
// telephone|telephone
// post|post');
// $this->drupalPost('admin/content/node-type/contact-details/fields/field_contact_preference', $edit, t('Save field settings'));
//
// // set access perm for authenticated users to creade profile nodes
// $edit = array('2[create identity content]' => 'create identity content', '2[create biography content]' => 'create biography content', '2[create contact_details content]' => 'create contact_details content');
// $this->drupalPost('admin/people/permissions', $edit, t('Save permissions'));
// }
//
//
// /**
// * Match CSV columns to Profile fields
// */
// function settingsNodeprofileMatch(&$edit) {
// $edit['field_match[0][field_match]'] = 'content_profile-identity cck:field_first_name:value'; // First Name
// $edit['field_match[1][field_match]'] = 'content_profile-identity cck:field_last_name:value'; // Last Name
// $edit['field_match[10][field_match]'] = 'content_profile-biography cck:field_cv:value'; // CV
// $edit['field_match[7][field_match]'] = 'content_profile-contact_details cck:field_can_be_contacted:value'; // Contact Permision
// $edit['field_match[8][field_match]'] = 'content_profile-contact_details cck:field_contact_preference:value'; // Contact Preference
//// $edit['field_match[9][field_match]'] = 'taxonomy-' . $this->vocabulary_id; // Interests
// $edit['field_match[6][field_match]'] = 'content_profile-biography cck:field_blog:url'; // Blog
// $edit['field_match[11][field_match]'] = 'content_profile-biography cck:field_birthday:value'; // Birthday
// }
//
// /**
// * Check data in CSV file matches data in profiles
// */
// function checkNodeprofileExist() {
// $file_path = drupal_get_path('module', 'user_import') . '/sample.txt';
// $handle = @fopen($file_path, "r");
// $row = 0;
//
// while ($csv = fgetcsv($handle, 1000, ',')) {
//
// if ($row > 0) {
//
// $user = user_load_by_mail($csv[5]);
// // test each data cell against nodeprofile field content
// $identity = node_load(array('type' => 'identity', 'uid' => $user->uid), NULL, TRUE);
// $this->drupalGet("node/$identity->nid");
// $this->assertText(check_plain($csv[0]), "[Compare CSV and Profile data] Row: $row Field: First Name");
// $this->assertText(check_plain($csv[1]), "[Compare CSV and Profile data] Row: $row Field: Last Name " . $csv[1]);
//
// $biography = node_load(array('type' => 'biography', 'uid' => $user->uid), NULL, TRUE);
// $this->drupalGet("node/$biography->nid");
// $this->assertText($csv[6], "[Compare CSV and Profile data] Row: $row Field: Blog");
// $this->assertText($csv[10], "[Compare CSV and Profile data] Row: $row Field: CV");
// $birthday = format_date(strtotime($csv[11]), 'custom', 'D, j/m/Y');
// $this->assertText($birthday, "[Compare CSV and Profile data] Row: $row Field: Birthday " . $birthday);
//
//
// $contact_details = node_load(array('type' => 'contact_details', 'uid' => $user->uid), NULL, TRUE);
// $this->drupalGet("node/$contact_details->nid");
//
// if (isset($csv[7]) && !empty($csv[7])) {
// $this->assertText('Can be contacted', "[Compare CSV and Profile data] Row: $row Field: Contact Permission set");
// }
// else {
// $this->assertNoText('Can be contacted', "[Compare CSV and Profile data] Row: $row Field: Contact Permission not set");
// }
//
// $this->assertText($csv[8], "[Compare CSV and Profile data] Row: $row Field: Contact Preference");
//
// //test interests link on profile page
// if (!empty($user->profile_interests)) {
// $interests = explode(',', $user->profile_interests);
// $this->drupalGet('profile/profile_interests/' . $interests[0]);
// $this->assertWantedRaw('<a title="View user profile." href="/' . url('user/' . $user->uid) . '">' . $user->name . '</a>' , '[Freeform List] User is listed on page about item in list');
// }
//
// }
//
// $row++;
// }
//
// }
//
// /**
// * SimpleTest core method: code run after each and every test method.
// */
// function tearDown() {
//
// // delete accounts of users imported
// $users_email = $this->usersList();
//
// foreach ($users_email as $mail) {
// $account = user_load_by_mail($mail);
// // delete node profile nodes
// if (!empty($account)) {
// $identity = node_load(array('type' => 'identity', 'uid' => $account->uid));
// $biography = node_load(array('type' => 'biography', 'uid' => $account->uid));
// $contact_details = node_load(array('type' => 'contact_details', 'uid' => $account->uid));
// node_delete($identity->nid);
// node_delete($biography->nid);
// node_delete($contact_details->nid);
// user_delete(array(), $account->uid);
// }
// }
//
// // delete the import
// $import_id = $this->importID();
// $this->assertTrue(!empty($import_id), t('Import ID: !id', array('!id' => $import_id)));
// _user_import_settings_deletion($import_id);
//
// // delete vocabulary
// taxonomy_del_vocabulary($this->vocabulary_id);
//
// // uninstall modules
// // - tear down disable doesn't seem to do this
// // foreach($this->modules as $module) {
// // if (function_exists($module . '_uninstall')) {
// // $result = call_user_func_array($module . '_uninstall', array());
// // }
// // }
//
// // delete nodeprofile content types
// node_type_delete('dummy'); // (for some reason) the first node_type_delete is completely ignored
// node_type_delete('identity');
// node_type_delete('biography');
// node_type_delete('contact_details');
//
// // Always call the tearDown() function from the parent class.
// parent::tearDown();
// }
//}
/**
* Test import of user data into Profile module
*/
//class UserImportProfileTestCase extends UserImportWebTestCase {
//
//
// public static function getInfo() {
// return array(
// 'name' => 'Import Users (Profile)',
// 'description' => 'Test import of user data into Profile module.',
// 'group' => 'User Import',
// );
// }
//
// function setUp() {
// parent::setUp('user_import', 'profile');
// $this->admin_user = $this->drupalCreateUser(array('administer users', 'access administration pages', 'administer site configuration'));
// $this->user_importer = $this->drupalCreateUser(array('import users'));
// }
//
// /**
// * User with right permissions creates import (with new settings)
// * - test import of user data into Profile module
// */
// function testCreateImport() {
// $this->drupalLogin($this->admin_user);
// $this->profileFieldsCreate();
//
// // Prepare a user to do testing
// $this->drupalGet('logout'); // log out first
// $this->drupalLogin($this->user_importer);
//
// // Select CSV file (the included example file)
// $this->settingsFileSelect();
//
// // import settings
// $this->importID($this->getUrl()); // store import ID for later
//
// $settings = array();
// $this->settingsEmailMatch($settings);
// $this->settingsProfileMatch($settings);
// $this->settingsIgnoreFirstLine($settings);
// $this->drupalPost($this->getUrl(), $settings, 'Import');
//
// // check if users have been imported
// $this->checkProfileExist();
// }
//
// /**
// * create profile fields
// */
// function profileFieldsCreate() {
//
// // Textfield
// $edit = array('category' => 'Name', 'title' => 'First Name', 'name' => 'profile_first_name');
// $this->drupalPost('admin/people/profile/add/textfield', $edit, t('Save field'));
//
// // Textfield
// $edit = array('category' => 'Name', 'title' => 'Last Name', 'name' => 'profile_last_name');
// $this->drupalPost('admin/people/profile/add/textfield', $edit, t('Save field'));
//
// // Textarea
// $edit = array('category' => 'Biography', 'title' => 'CV', 'name' => 'profile_cv');
// $this->drupalPost('admin/people/profile/add/textarea', $edit, t('Save field'));
//
// // Checkbox
// $edit = array('category' => 'Contact Details', 'title' => 'Can Be Contacted', 'name' => 'profile_contact_permission');
// $this->drupalPost('admin/people/profile/add/checkbox', $edit, t('Save field'));
//
// // List
// $edit = array('category' => 'Contact Details', 'title' => 'Contact Preference', 'name' => 'profile_contact_preference', 'options' => 'email,telephone,post');
// $this->drupalPost('admin/people/profile/add/selection', $edit, t('Save field'));
//
// // Freeform List
// $edit = array('category' => 'Biography', 'title' => 'Interests', 'name' => 'profile_interests');
// $this->drupalPost('admin/people/profile/add/list', $edit, t('Save field'));
//
// // URL
// $edit = array('category' => 'Biography', 'title' => 'Blog', 'name' => 'profile_blog');
// $this->drupalPost('admin/people/profile/add/url', $edit, t('Save field'));
//
// // Date
// $edit = array('category' => 'Biography', 'title' => 'Birthday', 'name' => 'profile_birthday');
// $this->drupalPost('admin/people/profile/add/date', $edit, t('Save field'));
// }
//
// /**
// * Match CSV columns to Profile fields
// */
// function settingsProfileMatch(&$edit) {
// $edit['field_match[0][field_match]'] = 'profile-1'; // First Name
// $edit['field_match[1][field_match]'] = 'profile-2'; // Last Name
// $edit['field_match[10][field_match]'] = 'profile-3'; // CV
// $edit['field_match[7][field_match]'] = 'profile-4'; // Contact Permision
// $edit['field_match[8][field_match]'] = 'profile-5'; // Contact Preference
// $edit['field_match[9][field_match]'] = 'profile-6'; // Interests
// $edit['field_match[6][field_match]'] = 'profile-7'; // Blog
// $edit['field_match[11][field_match]'] = 'profile-8'; // Birthday
// }
//
// /**
// * Check data in CSV file matches data in profiles
// */
// function checkProfileExist() {
//
// $file_path = drupal_get_path('module', 'user_import') . '/sample.txt';
// $handle = @fopen($file_path, "r");
// $row = 0;
//
// while ($csv = fgetcsv($handle, 1000, ',')) {
//
// if ($row > 0) {
// $user = user_load_by_mail($csv[5]);
// // test each data cell against Profile field content
// $profile_first_name = isset($user->profile_first_name) ? $user->profile_first_name : '';
// $this->assertEqual($profile_first_name, $csv[0], "[Compare CSV data to Profile data] Row: $row Field: First Name");
//
// $profile_last_name = isset($user->profile_last_name) ? $user->profile_last_name : '';
// $this->assertEqual($profile_last_name, $csv[1], "[Compare CSV data to Profile data] Row: $row Field: Last Name");
//
// $profile_blog = isset($user->profile_blog) ? $user->profile_blog : '';
// $this->assertEqual($profile_blog, $csv[6], "[Compare CSV data to Profile data] Row: $row Field: Blog");
//
// $profile_contact_permission = isset($user->profile_contact_permission) ? $user->profile_contact_permission : '';
// $file_field_value = (!isset($csv[7]) || empty($csv[7])) ? 0 : 1;
// $this->assertEqual($profile_contact_permission, $file_field_value, "[Compare CSV data to Profile data] Row: $row Field: Contact Permission");
//
// $profile_contact_preference = isset($user->profile_contact_preference) ? $user->profile_contact_preference : '';
// $this->assertEqual($profile_contact_preference, $csv[8], "[Compare CSV data to Profile data] Row: $row Field: Contact Preference");
//
// $profile_interests = isset($user->profile_interests) ? $user->profile_interests : '';
// $this->assertEqual($profile_interests, $csv[9], "[Compare CSV data to Profile data] Row: $row Field: Profile Interests");
//
// $profile_cv = isset($user->profile_cv) ? $user->profile_cv : '';
// $this->assertEqual($profile_cv, $csv[10], "[Compare CSV data to Profile data] Row: $row Field: CV");
//
// $profile_birthday = isset($user->profile_birthday) ? implode('/', $user->profile_birthday) : '';
//
// if (isset($user->profile_birthday)) {
// $profile_birthday = $user->profile_birthday['month'] . '/' . $user->profile_birthday['day'] . '/' . $user->profile_birthday['year'];
// }
// else {
// $profile_birthday = '';
// }
//
// $this->assertEqual($profile_birthday, $csv[11], "[Compare CSV data to Profile data] Row: $row Field: Birthday");
// /**
// * @todo test below fails because it gets an access denied message.
// */
// //test interests link on profile page
// // if (!empty($user->profile_interests)) {
// // $interests = explode(',', $user->profile_interests);
// // $this->drupalGet('profile/profile_interests/' . $interests[0]);
// // $this->assertRaw('<a title="View user profile." href="/'. url('user/'. $user->uid) .'">'. $user->name .'</a>', '[Freeform List] User is listed on page about item in list');
// // }
//
// }
//
// $row++;
// }
// }
//
//}