first import
This commit is contained in:
339
sites/all/modules/node_export/LICENSE.txt
Normal file
339
sites/all/modules/node_export/LICENSE.txt
Normal 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.
|
93
sites/all/modules/node_export/README.txt
Normal file
93
sites/all/modules/node_export/README.txt
Normal file
@@ -0,0 +1,93 @@
|
||||
|
||||
Node export README
|
||||
|
||||
CONTENTS OF THIS FILE
|
||||
----------------------
|
||||
|
||||
* Introduction
|
||||
* Installation
|
||||
* Configuration
|
||||
* Usage
|
||||
* Node export features tips
|
||||
|
||||
|
||||
INTRODUCTION
|
||||
------------
|
||||
This module allows users to export nodes and then import it into another
|
||||
Drupal installation, or on the same site.
|
||||
|
||||
This module allows user to export/import nodes if they have the 'export nodes'
|
||||
or 'export own nodes' permission, have node access to view the node and create
|
||||
the node type, and the node type is not omitted in node export's settings. The
|
||||
module does not check access to the filter formats used by the node's fields,
|
||||
please keep this in mind when assigning permissions to user roles.
|
||||
|
||||
Maintainer: Daniel Braksator (http://drupal.org/user/134005)
|
||||
Project page: http://drupal.org/project/node_export.
|
||||
|
||||
Note: this module was originally built upon code from the node_clone module
|
||||
maintained by Peter Wolanin (http://drupal.org/user/49851) at
|
||||
http://drupal.org/project/node_clone which was derived from code posted by
|
||||
Steve Ringwood (http://drupal.org/user/12856) at
|
||||
http://drupal.org/node/73381#comment-137714
|
||||
Features integration, relations, and UUID initially developed by Tushar Mahajan
|
||||
(http://drupal.org/user/398572).
|
||||
Significant improvements, file handling, and extra functionality pioneered by
|
||||
James Andres (http://drupal.org/user/33827).
|
||||
|
||||
|
||||
INSTALLATION
|
||||
------------
|
||||
1. Copy node_export folder to modules directory (usually sites/all/modules).
|
||||
2. At admin/build/modules enable the Node export module in the Node export
|
||||
package.
|
||||
3. Enable any other modules in the Node export package that tickle your fancy.
|
||||
|
||||
For detailed instructions on installing contributed modules see:
|
||||
http://drupal.org/documentation/install/modules-themes/modules-7
|
||||
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
1. Enable permissions at admin/user/permissions.
|
||||
Security Warning: Users with the permission "use PHP to import nodes"
|
||||
will be able to change nodes as they see fit before an import, as well as
|
||||
being able to execute PHP scripts on the server. It is advisable not to
|
||||
give this permission to a typical node author, only the administrator or
|
||||
developer should use this feature. You may even like to turn this module
|
||||
off when it is no longer required.
|
||||
This module does not check access to the filter formats used by the node's
|
||||
fields, please keep this in mind when assigning permissions to user roles.
|
||||
2. Configure module at admin/settings/node_export.
|
||||
|
||||
|
||||
USAGE
|
||||
-----
|
||||
1. To export nodes, either:
|
||||
a) Use the 'Node export' tab on a node page.
|
||||
b) Use the Find content page (admin/content) to filter the nodes you
|
||||
wish to export and then choose 'Node export' under the 'Update options'.
|
||||
c) Use Drush: http://drupal.org/project/drush
|
||||
d) Create a Feature (see tips below) http://drupal.org/project/features
|
||||
e) Create a View of nodes and use the Views Bulk Operations (VBO) module
|
||||
http://drupal.org/project/views_bulk_operations
|
||||
|
||||
2. To import nodes that were exported with Node export, either:
|
||||
a) Use the form at 'Node export: import' under 'Add content'
|
||||
(node/add/node_export).
|
||||
b) Use Drush: http://drupal.org/project/drush
|
||||
c) Using your created Feature.
|
||||
d) For advanced imports if you are familiar with the Feeds module, enable
|
||||
Node export feeds module to use with the Feeds import interface
|
||||
http://drupal.org/project/feeds
|
||||
|
||||
|
||||
NODE EXPORT FEATURES TIPS
|
||||
-------------------------
|
||||
Regarding the Node export features module which integrates with the Features
|
||||
module, any nodes to be used with this must have a UUID (universally unique
|
||||
ID). To export older nodes that don't have UUID make sure you have selected
|
||||
the content type and click on 'create missings uuids' from
|
||||
'admin/settings/uuid' under the fieldset 'Synchronize'. Then you should be
|
||||
able to see more nodes under the feature component, If you don't see the node
|
||||
export component, that means no nodes has been configured with UUID.
|
53
sites/all/modules/node_export/formats/drupal.inc
Normal file
53
sites/all/modules/node_export/formats/drupal.inc
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export Drupal format handler.
|
||||
*
|
||||
* Adds Drupal var export format to Node export.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Export callback.
|
||||
*/
|
||||
function node_export_drupal_export($nodes, $format) {
|
||||
require_once DRUPAL_ROOT . '/includes/utility.inc';
|
||||
return drupal_var_export($nodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Import callback.
|
||||
*/
|
||||
function node_export_drupal_import($code_string) {
|
||||
if (substr(ltrim($code_string), 0, 6) == "array(") {
|
||||
$nodes = eval('return ' . $code_string . ';');
|
||||
if (is_array($nodes)) {
|
||||
return node_export_drupal_decode_objects($nodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively convert arrays back to objects.
|
||||
*
|
||||
* This is only for backwards compatibility with the deprecated node_code format.
|
||||
*/
|
||||
function node_export_drupal_decode_objects($array) {
|
||||
foreach ($array as $k => $v) {
|
||||
if (is_array($v)) {
|
||||
$array[$k] = node_export_drupal_decode_objects($v);
|
||||
}
|
||||
}
|
||||
if (isset($array['#_export_node_encode_object'])) {
|
||||
unset($array['#_export_node_encode_object']);
|
||||
$array = (object)$array;
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for actions.
|
||||
*/
|
||||
function node_export_drupal_action_form($context, &$form_state) {
|
||||
return node_export_action_form($context, $form_state, 'drupal');
|
||||
}
|
345
sites/all/modules/node_export/formats/dsv.inc
Normal file
345
sites/all/modules/node_export/formats/dsv.inc
Normal file
@@ -0,0 +1,345 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export DSV format handler.
|
||||
*
|
||||
* Adds configurable DSV format to Node export.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Settings callback.
|
||||
*/
|
||||
function node_export_dsv_settings($form, $form_state) {
|
||||
$settings['dsv'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('DSV format settings'),
|
||||
'#description' => t(
|
||||
'Select how your DSV output will be formatted - this must be configured the
|
||||
same on both sites. By default this is configured to RFC4180 CSV format
|
||||
where the delimiter is a comma (,), the enclosure is a double-quote ("),
|
||||
and the seperator is CRLF (\r\n). Not all configurations may be possible,
|
||||
use wisely. Enclosure will only be used to escape values that contain any
|
||||
of the configured strings. Additionally single-quotes will be used to
|
||||
escape values that are equivalent to reserved words (NULL, TRUE, FALSE).'
|
||||
),
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => TRUE,
|
||||
);
|
||||
|
||||
$settings['dsv']['node_export_dsv_delimiter'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Value delimiter'),
|
||||
'#size' => 5,
|
||||
'#maxlength' => 255,
|
||||
'#default_value' => variable_get('node_export_dsv_delimiter', ','),
|
||||
'#required' => TRUE,
|
||||
);
|
||||
|
||||
$settings['dsv']['node_export_dsv_enclosure'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Escape enclosure'),
|
||||
'#size' => 5,
|
||||
'#maxlength' => 255,
|
||||
'#default_value' => variable_get('node_export_dsv_enclosure', '"'),
|
||||
'#required' => TRUE,
|
||||
);
|
||||
|
||||
$settings['dsv']['node_export_dsv_seperator'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Record seperator'),
|
||||
'#size' => 5,
|
||||
'#maxlength' => 255,
|
||||
'#default_value' => variable_get('node_export_dsv_seperator', '\r\n'),
|
||||
'#required' => TRUE,
|
||||
);
|
||||
|
||||
$settings['dsv']['node_export_dsv_escape_eol'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Always escape values containing line breaks'),
|
||||
'#default_value' => variable_get('node_export_dsv_escape_eol', 1),
|
||||
'#description' => t('This is to overcome problems where Windows injects CRLF line breaks.'),
|
||||
);
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
function node_export_dsv_string($string) {
|
||||
$replace = array(
|
||||
'\n' => "\n",
|
||||
'\r' => "\r",
|
||||
'\t' => "\t",
|
||||
'\v' => "\v",
|
||||
'\e' => "\e",
|
||||
'\f' => "\f",
|
||||
);
|
||||
return str_replace(array_keys($replace), array_values($replace), $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export callback.
|
||||
*/
|
||||
function node_export_dsv_export($nodes, $format) {
|
||||
$delimiter = node_export_dsv_string(variable_get('node_export_dsv_delimiter', ','));
|
||||
$enclosure = node_export_dsv_string(variable_get('node_export_dsv_enclosure', '"'));
|
||||
$seperator = node_export_dsv_string(variable_get('node_export_dsv_seperator', '\r\n'));
|
||||
$escape_eol = variable_get('node_export_dsv_escape_eol', 1);
|
||||
return node_export_dsv_encode($nodes, $delimiter, $enclosure, $seperator, $escape_eol);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build DSV string.
|
||||
*/
|
||||
function node_export_dsv_encode($nodes, $delimiter, $enclosure, $seperator, $escape_eol) {
|
||||
$encoded_nodes = array();
|
||||
$dsv_lines = array();
|
||||
|
||||
$node_keys = array();
|
||||
foreach (array_keys($nodes) as $node_key) {
|
||||
$new_node_key = 'node_' . $node_key;
|
||||
$node_keys[] = $new_node_key;
|
||||
node_export_dsv_encode_node($encoded_nodes, $new_node_key, $nodes[$node_key]);
|
||||
}
|
||||
|
||||
$dsv_lines['node_export_dsv_header'] = array_keys($encoded_nodes);
|
||||
|
||||
foreach (array_keys($encoded_nodes) as $header_value) {
|
||||
$encoded_nodes[$header_value] = array_merge(array_fill_keys($node_keys, NULL), $encoded_nodes[$header_value]);
|
||||
foreach (array_keys($encoded_nodes[$header_value]) as $encoded_node_key) {
|
||||
$dsv_lines[$encoded_node_key][$header_value] = $encoded_nodes[$header_value][$encoded_node_key];
|
||||
}
|
||||
}
|
||||
|
||||
return node_export_dsv_array_to_dsv($dsv_lines, $delimiter, $enclosure, $seperator, $escape_eol);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a node and update $header and $encoded_nodes accordingly.
|
||||
*/
|
||||
function node_export_dsv_encode_node(&$encoded_nodes, $node_key, $var, $parent = NULL) {
|
||||
|
||||
foreach ($var as $k => &$v) {
|
||||
|
||||
// Get the new header value.
|
||||
$header_value = node_export_dsv_encode_header_value($parent, $var, $k);
|
||||
|
||||
if (is_object($v) || is_array($v)) {
|
||||
// Recurse through the structure.
|
||||
node_export_dsv_encode_node($encoded_nodes, $node_key, $v, $header_value);
|
||||
}
|
||||
else {
|
||||
// Create a safe text version of this value and store it against the header using a safe key.
|
||||
$encoded_nodes[$header_value][$node_key] = node_export_dsv_encode_sanitize_value($v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a value.
|
||||
*/
|
||||
function node_export_dsv_encode_sanitize_value($var) {
|
||||
if (is_numeric($var)) {
|
||||
return $var;
|
||||
}
|
||||
elseif (is_bool($var)) {
|
||||
return ($var ? 'TRUE' : 'FALSE');
|
||||
}
|
||||
elseif (is_null($var)) {
|
||||
return 'NULL';
|
||||
}
|
||||
elseif (is_string($var) && !empty($var)) {
|
||||
// Single-quote strings that could be confused for null or boolean.
|
||||
if (in_array(strtoupper($var), array('TRUE', 'FALSE', 'NULL'))) {
|
||||
$var = "'" . $var . "'";
|
||||
}
|
||||
|
||||
return $var;
|
||||
}
|
||||
else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a value.
|
||||
*/
|
||||
function node_export_dsv_decode_sanitize_value($var) {
|
||||
// Allow numeric, bool, and null values to pass right back as is.
|
||||
if (is_numeric($var) || is_bool($var) || is_null($var)) {
|
||||
return $var;
|
||||
}
|
||||
// Allow the special case strings back as is.
|
||||
elseif (in_array(strtoupper($var), array("'TRUE'", "'FALSE'", "'NULL'"))) {
|
||||
return $var;
|
||||
}
|
||||
// Assume this is a string.
|
||||
return "'" . str_replace("'", "\'", $var) . "'";
|
||||
}
|
||||
|
||||
/**
|
||||
* Create header value from $parents, $var, and $k.
|
||||
*/
|
||||
function node_export_dsv_encode_header_value($parents, $var, $k) {
|
||||
if (is_null($parents)) {
|
||||
// Special case; on the first level do not prefix the key.
|
||||
$header_value = $k;
|
||||
}
|
||||
elseif (is_object($var)) {
|
||||
$header_value = $parents . "->" . $k;
|
||||
}
|
||||
elseif (is_array($var)) {
|
||||
$header_value = $parents . "['" . $k . "']";
|
||||
}
|
||||
return $header_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Import callback.
|
||||
*/
|
||||
function node_export_dsv_import($code_string) {
|
||||
$delimiter = node_export_dsv_string(variable_get('node_export_dsv_delimiter', ','));
|
||||
$enclosure = node_export_dsv_string(variable_get('node_export_dsv_enclosure', '"'));
|
||||
$seperator = node_export_dsv_string(variable_get('node_export_dsv_seperator', '\r\n'));
|
||||
return node_export_dsv_decode($code_string, $delimiter, $enclosure, $seperator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpret a DSV string.
|
||||
*/
|
||||
function node_export_dsv_decode($code_string, $delimiter, $enclosure, $seperator) {
|
||||
// Get array data from DSV.
|
||||
$array = @node_export_dsv_dsv_to_array($code_string, $delimiter, $enclosure, $seperator);
|
||||
|
||||
// If the first two rows are of equal length, we can assume this is a DSV.
|
||||
// Also checks there are a decent number of fields.
|
||||
if (!empty($array[0]) && !empty($array[1]) && count($array[0]) > 10 && count($array[0]) == count($array[1])) {
|
||||
$nodes = array();
|
||||
|
||||
// Assume row 0 is the header, and the rest of the rows are the nodes.
|
||||
$header = array_shift($array);
|
||||
|
||||
// Build the nodes.
|
||||
foreach ($array as &$row) {
|
||||
$node = (object)array();
|
||||
foreach ($row as $key => $item) {
|
||||
$item = node_export_dsv_decode_sanitize_value($item);
|
||||
eval('$node->' . $header[$key] . ' = ' . $item . ';');
|
||||
}
|
||||
$nodes[] = $node;
|
||||
}
|
||||
|
||||
return $nodes;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode DSV.
|
||||
*/
|
||||
function node_export_dsv_array_to_dsv($array, $delimiter, $enclosure, $seperator, $escape_eol) {
|
||||
$lines = array();
|
||||
foreach ($array as $line) {
|
||||
$out_item = array();
|
||||
foreach ($line as $item) {
|
||||
if (stripos($item, $enclosure) !== FALSE) {
|
||||
$item = str_replace($enclosure, $enclosure . $enclosure, $item);
|
||||
}
|
||||
if (
|
||||
(stripos($item, $delimiter) !== FALSE)
|
||||
|| (stripos($item, $enclosure) !== FALSE)
|
||||
|| (stripos($item, $seperator) !== FALSE)
|
||||
|| ($escape_eol && stripos($item, "\n") !== FALSE)
|
||||
) {
|
||||
$item = $enclosure . $item . $enclosure;
|
||||
}
|
||||
$out_item[] = $item;
|
||||
}
|
||||
$lines[] = implode($delimiter, $out_item);
|
||||
}
|
||||
return implode($seperator, $lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode DSV.
|
||||
*/
|
||||
function node_export_dsv_dsv_to_array($string, $delimiter, $enclosure, $seperator) {
|
||||
$lines = array();
|
||||
$out_item = array();
|
||||
$count = strlen($string);
|
||||
$escape = FALSE;
|
||||
$double_escape = FALSE;
|
||||
$position = 0;
|
||||
$i = 0;
|
||||
$seperators = str_split($seperator);
|
||||
|
||||
while ($i < $count) {
|
||||
$c = $string[$i];
|
||||
|
||||
// Determine whether this is an EOL.
|
||||
$is_eol = TRUE;
|
||||
for ($j = 0; $j < count($seperators); $j++) {
|
||||
if (!isset($string[$i + $j]) || $string[$i + $j] != $seperators[$j]) {
|
||||
$is_eol = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($is_eol) {
|
||||
if ($escape) {
|
||||
$out_item[$position] .= $c;
|
||||
}
|
||||
else {
|
||||
$i += count($seperators);
|
||||
$lines[] = $out_item;
|
||||
$out_item = array();
|
||||
$position = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
elseif ($c == $delimiter) {
|
||||
if ($escape) {
|
||||
$out_item[$position] .= $c;
|
||||
}
|
||||
else {
|
||||
if ($string[$i - 1] == $delimiter) {
|
||||
$out_item[$position] .= '';
|
||||
}
|
||||
$position++;
|
||||
$escape = FALSE;
|
||||
$double_escape = FALSE;
|
||||
}
|
||||
}
|
||||
elseif ($c == $enclosure) {
|
||||
if ($double_escape) {
|
||||
$out_item[$position] .= $enclosure;
|
||||
$double_escape = FALSE;
|
||||
}
|
||||
if ($escape) {
|
||||
$escape = FALSE;
|
||||
$double_escape = TRUE;
|
||||
}
|
||||
else {
|
||||
$escape = TRUE;
|
||||
$double_escape = FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($double_escape) {
|
||||
$out_item[$position] .= $enclosure;
|
||||
$double_escape = FALSE;
|
||||
}
|
||||
$out_item[$position] .= $c;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
if (!empty($out_item)) {
|
||||
$lines[] = $out_item;
|
||||
}
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for actions.
|
||||
*/
|
||||
function node_export_dsv_action_form($context, &$form_state) {
|
||||
return node_export_action_form($context, $form_state, 'dsv');
|
||||
}
|
63
sites/all/modules/node_export/formats/json.inc
Normal file
63
sites/all/modules/node_export/formats/json.inc
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export JSON format handler.
|
||||
*
|
||||
* Adds JSON format to Node export.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Export callback.
|
||||
*/
|
||||
function node_export_json_export($nodes, $format) {
|
||||
return drupal_json_encode(node_export_json_encode_objects($nodes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Import callback.
|
||||
*/
|
||||
function node_export_json_import($code_string) {
|
||||
return node_export_json_decode_objects(drupal_json_decode($code_string));
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark objects as being objects.
|
||||
*/
|
||||
function node_export_json_encode_objects($var) {
|
||||
if (is_object($var)) {
|
||||
$var = (array)$var;
|
||||
$var['#node_export_object'] = '1';
|
||||
}
|
||||
if (is_array($var)) {
|
||||
foreach ($var as $key => $value) {
|
||||
$var[$key] = node_export_json_encode_objects($value);
|
||||
}
|
||||
}
|
||||
return $var;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively convert arrays back to objects.
|
||||
*/
|
||||
function node_export_json_decode_objects($array) {
|
||||
if (is_array($array)) {
|
||||
foreach ($array as $k => $v) {
|
||||
if (is_array($v)) {
|
||||
$array[$k] = node_export_json_decode_objects($v);
|
||||
}
|
||||
}
|
||||
if (isset($array['#node_export_object'])) {
|
||||
unset($array['#node_export_object']);
|
||||
$array = (object)$array;
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for actions.
|
||||
*/
|
||||
function node_export_json_action_form($context, &$form_state) {
|
||||
return node_export_action_form($context, $form_state, 'json');
|
||||
}
|
32
sites/all/modules/node_export/formats/serialize.inc
Normal file
32
sites/all/modules/node_export/formats/serialize.inc
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export serialize format handler.
|
||||
*
|
||||
* Adds serialize format to Node export.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Export callback.
|
||||
*/
|
||||
function node_export_serialize_export($nodes, $format) {
|
||||
return 'node_export_serialize::' . htmlspecialchars(serialize($nodes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Import callback.
|
||||
*/
|
||||
function node_export_serialize_import($code_string) {
|
||||
// Check for 'node_export_serialize::' at the start.
|
||||
if (substr(ltrim($code_string), 0, 23) == 'node_export_serialize::') {
|
||||
return unserialize(htmlspecialchars_decode(str_replace('node_export_serialize::', '', $code_string)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for actions.
|
||||
*/
|
||||
function node_export_serialize_action_form($context, &$form_state) {
|
||||
return node_export_action_form($context, $form_state, 'serialize');
|
||||
}
|
232
sites/all/modules/node_export/formats/xml.inc
Normal file
232
sites/all/modules/node_export/formats/xml.inc
Normal file
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export XML format handler.
|
||||
*
|
||||
* Adds XML format to Node export.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Export callback.
|
||||
*/
|
||||
function node_export_xml_export($nodes, $format) {
|
||||
$xml_code = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
|
||||
$xml_code .= "<node_export created=\"" . date('r') . "\">\n";
|
||||
$xml_code .= node_export_xml_encode($nodes);
|
||||
$xml_code .= "</node_export>";
|
||||
return $xml_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Import callback.
|
||||
*/
|
||||
function node_export_xml_import($code_string) {
|
||||
// Check for "<?xml" at the start.
|
||||
if (substr(ltrim($code_string), 0, 5) == "<?xml") {
|
||||
|
||||
// Decode the XML.
|
||||
$xml_class = new NodeExportXmlDecoder();
|
||||
$result = $xml_class->decode($code_string);
|
||||
|
||||
// Convert the nodes into objects.
|
||||
if (!isset($result['success'])) {
|
||||
foreach($result as $k => $v) {
|
||||
$result[$k] = (object)$v;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build XML string recursively.
|
||||
*/
|
||||
function node_export_xml_encode($var, $iteration = 0) {
|
||||
$xml_code = "";
|
||||
$tab = '';
|
||||
for ($i = 0; $i <= $iteration; $i++) {
|
||||
$tab = $tab . " ";
|
||||
}
|
||||
$iteration++;
|
||||
foreach ($var as $key => $value) {
|
||||
$attributes = array();
|
||||
if (is_bool($value)) {
|
||||
$attributes['type'] = 'boolean';
|
||||
}
|
||||
elseif (is_null($value)) {
|
||||
$attributes['type'] = 'NULL';
|
||||
}
|
||||
elseif (is_object($value)) {
|
||||
if ($iteration == 1 && isset($value->nid) && isset($value->type)) {
|
||||
// Assume first-level object with a nid and type is a stdClass node.
|
||||
$key = "node";
|
||||
}
|
||||
else {
|
||||
$attributes['class'] = get_class($value);
|
||||
}
|
||||
$value = (array)$value;
|
||||
}
|
||||
if (is_array($value) && array_values($value) === $value) {
|
||||
$attributes['_numeric_keys'] = "1";
|
||||
}
|
||||
$attr_string = "";
|
||||
foreach ($attributes as $attr_name => $attr_value) {
|
||||
$attr_string .= ' ' . $attr_name . '="' . $attr_value . '"';
|
||||
}
|
||||
|
||||
if (is_numeric($key)) {
|
||||
$key = "n" . $key;
|
||||
}
|
||||
$xml_code .= $tab . "<" . $key . $attr_string . ">";
|
||||
|
||||
if (is_array($value)) {
|
||||
if (!empty($value)) {
|
||||
$xml_code .= "\n";
|
||||
$xml_code .= node_export_xml_encode($value, $iteration);
|
||||
if (!is_numeric($key)) {
|
||||
$xml_code .= $tab;
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif (is_numeric($value)) {
|
||||
$xml_code .= $value;
|
||||
}
|
||||
elseif (is_bool($value)) {
|
||||
$xml_code .= ($value ? 'TRUE' : 'FALSE');
|
||||
}
|
||||
elseif (is_string($value)) {
|
||||
$xml_code .= htmlspecialchars($value);
|
||||
}
|
||||
$xml_code .= "</" . $key . ">\n";
|
||||
}
|
||||
return $xml_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for parsing Node export XML.
|
||||
*/
|
||||
class NodeExportXmlDecoder {
|
||||
var $stack;
|
||||
var $output;
|
||||
|
||||
function decode($code_string) {
|
||||
$parser = xml_parser_create();
|
||||
xml_set_element_handler($parser, array(&$this, 'start_handler'), array(&$this, 'end_handler'));
|
||||
xml_set_character_data_handler($parser, array(&$this, 'data_handler'));
|
||||
$this->stack = array(
|
||||
array(
|
||||
'name' => 'node_export',
|
||||
'attributes' => array(),
|
||||
'children' => array(),
|
||||
'data' => '',
|
||||
)
|
||||
);
|
||||
if (!xml_parse($parser, $code_string)) {
|
||||
$errors[] = "Node export XML import was unsuccessful, error details follow. No nodes imported.";
|
||||
$line = xml_get_current_line_number($parser);
|
||||
$column = xml_get_current_column_number($parser);
|
||||
$error = xml_error_string(xml_get_error_code($parser));
|
||||
$errors[] = "Line " . $line . ", Column " . $column .": ". $error;
|
||||
$lines = explode("\n", $code_string, $line + 1);
|
||||
$errors[] = "<pre>". htmlspecialchars($lines[$line - 1]) ."</pre>";
|
||||
xml_parser_free($parser);
|
||||
return array(
|
||||
'success' => FALSE,
|
||||
'output' => $errors,
|
||||
);
|
||||
}
|
||||
xml_parser_free($parser);
|
||||
|
||||
$tmp = $this->build($this->stack[0]);
|
||||
if (count($tmp) == 1) {
|
||||
$this->output = array_pop($tmp);
|
||||
}
|
||||
else {
|
||||
$this->output = array();
|
||||
}
|
||||
unset($this->stack);
|
||||
return $this->output;
|
||||
}
|
||||
|
||||
function build($stack) {
|
||||
$result = array();
|
||||
|
||||
if (count($stack['children']) > 0) {
|
||||
$keycount = array();
|
||||
foreach ($stack['children'] as $child) {
|
||||
$keycount[] = $child['name'];
|
||||
}
|
||||
if (count(array_unique($keycount)) != count($keycount)) {
|
||||
// Enumerated array.
|
||||
$children = array();
|
||||
foreach ($stack['children'] as $child) {
|
||||
$children[] = $this->build($child);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Associative array.
|
||||
$children = array();
|
||||
foreach ($stack['children'] as $child) {
|
||||
if (!empty($stack['attributes']['_NUMERIC_KEYS'])) {
|
||||
$child['name'] = intval(substr($child['name'], 1));
|
||||
}
|
||||
$children[$child['name']] = $this->build($child);
|
||||
}
|
||||
}
|
||||
$result = array_merge($result, $children);
|
||||
}
|
||||
|
||||
if (count($result) == 0) {
|
||||
// An atomic value.
|
||||
$return = trim($stack['data']);
|
||||
if (isset($stack['attributes']['TYPE'])) {
|
||||
if ($stack['attributes']['TYPE'] == 'boolean') {
|
||||
return (trim($stack['data']) == 'TRUE' ? TRUE : FALSE);
|
||||
}
|
||||
elseif ($stack['attributes']['TYPE'] == 'NULL') {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return htmlspecialchars_decode(trim($stack['data']));
|
||||
}
|
||||
else {
|
||||
// An array or object.
|
||||
if (isset($stack['attributes']['CLASS'])) {
|
||||
$object = new $stack['attributes']['CLASS']();
|
||||
foreach ($result as $k => $v) {
|
||||
$object->$k = $v;
|
||||
}
|
||||
$result = $object;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
function start_handler($parser, $name, $attributes = array()) {
|
||||
$token = array();
|
||||
$token['name'] = strtolower($name);
|
||||
$token['attributes'] = $attributes;
|
||||
$token['data'] = '';
|
||||
$token['children'] = array();
|
||||
$this->stack[] = $token;
|
||||
}
|
||||
|
||||
function end_handler($parser, $name, $attributes = array()) {
|
||||
$token = array_pop($this->stack);
|
||||
$this->stack[count($this->stack) - 1]['children'][] = $token;
|
||||
}
|
||||
|
||||
function data_handler($parser, $data) {
|
||||
$this->stack[count($this->stack) - 1]['data'] .= $data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for actions.
|
||||
*/
|
||||
function node_export_xml_action_form($context, &$form_state) {
|
||||
return node_export_action_form($context, $form_state, 'xml');
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Documents Node export dependency's hooks for api reference.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handle dependencies not already handled.
|
||||
*
|
||||
* Let other modules alter this - for example to only allow some users to
|
||||
* export specific nodes or types.
|
||||
*
|
||||
* @param &$handled
|
||||
* Boolean indicating whether the dependency was handled, only set to TRUE,
|
||||
* never explicitly set it to FALSE. Only run code when it is already FALSE.
|
||||
* @param $node
|
||||
* The node to handle the dependency for.
|
||||
* @param $dependency
|
||||
* The dependency data.
|
||||
*/
|
||||
function hook_node_export_dependency_alter(&$handled, &$node, $dependency) {
|
||||
if (!$handled) {
|
||||
// Attempt to handle the dependency here.
|
||||
// If it's handled successfully set $handled to TRUE.
|
||||
}
|
||||
}
|
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains hook implementations for all relevant core module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency().
|
||||
*/
|
||||
function node_node_export_dependency($entity, $entity_type) {
|
||||
if ($entity_type == 'node') {
|
||||
$dependencies = array();
|
||||
// The node has a 'user' dependency through the 'uid' and
|
||||
// 'revision_uid' properties.
|
||||
node_export_dependency_add($dependencies, $entity, 'user', array('uid', 'revision_uid'));
|
||||
// The node has a 'node' dependency through the 'tnid' property.
|
||||
node_export_dependency_add($dependencies, $entity, 'node', 'tnid');
|
||||
return $dependencies;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency()
|
||||
*/
|
||||
function taxonomy_node_export_dependency($entity, $entity_type) {
|
||||
if ($entity_type == 'taxonomy_term') {
|
||||
$dependencies = array();
|
||||
$terms = taxonomy_get_parents($entity->tid);
|
||||
$delta = 0;
|
||||
foreach ($terms as $tid => $term) {
|
||||
$dependencies[] = array(
|
||||
'type' => 'taxonomy_term',
|
||||
'id' => $tid,
|
||||
'property' => 'parent',
|
||||
'delta' => $delta++,
|
||||
);
|
||||
}
|
||||
return $dependencies;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency().
|
||||
*/
|
||||
function book_node_export_dependency($entity, $entity_type) {
|
||||
if ($entity_type == 'node' && !empty($entity->book)) {
|
||||
$dependencies = array();
|
||||
|
||||
// Book page's root book node.
|
||||
if (!empty($entity->book['bid'])) {
|
||||
$dependencies[] = array(
|
||||
'type' => 'node',
|
||||
'id' => $entity->book['bid'],
|
||||
'property' => array(array('book', 'bid')),
|
||||
);
|
||||
}
|
||||
|
||||
// Book page's immediate parent.
|
||||
if (!empty($entity->book['plid'])) {
|
||||
$parent_nid = db_query(
|
||||
'SELECT nid FROM {book} WHERE mlid = :mlid',
|
||||
array(':mlid' => $entity->book['plid'])
|
||||
)->fetchField();
|
||||
$dependencies[] = array(
|
||||
'type' => 'node',
|
||||
'id' => $parent_nid,
|
||||
'property' => array(array('book', 'plid')),
|
||||
// Recognise the relationship is not done through the entity id key.
|
||||
'relationship' => array(
|
||||
'key' => array('menu', 'mlid'),
|
||||
'value' => $entity->book['plid'],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Book page's immediate children.
|
||||
$flat = book_get_flat_menu($entity->book);
|
||||
$children = array();
|
||||
if ($entity->book['has_children']) {
|
||||
// Walk through the array until we find the current page.
|
||||
do {
|
||||
$link = array_shift($flat);
|
||||
} while ($link && ($link['mlid'] != $entity->book['mlid']));
|
||||
// Continue through the array and collect the links whose parent is this page.
|
||||
while (($link = array_shift($flat)) && $link['plid'] == $entity->book['mlid']) {
|
||||
$matches = array();
|
||||
if (preg_match('/^node\/([\d]+)$/', $link['href'], $matches)) {
|
||||
$dependencies[] = array(
|
||||
'type' => 'node',
|
||||
'id' => $matches[1],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $dependencies;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency().
|
||||
*/
|
||||
function og_node_export_dependency($entity, $entity_type) {
|
||||
if ($entity_type == 'node') {
|
||||
$dependencies = array();
|
||||
|
||||
if (!empty($entity->og_groups)) {
|
||||
foreach (array_keys($entity->og_groups) as $delta) {
|
||||
entity_dependency_add($dependencies, $entity, 'node', array(array('og_groups', $delta)));
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($entity->og_parent->nid)) {
|
||||
entity_dependency_add($dependencies, $entity, 'node', array(array('og_parent', 'nid')));
|
||||
}
|
||||
|
||||
if (!empty($dependencies)) {
|
||||
return $dependencies;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency().
|
||||
*/
|
||||
function field_node_export_dependency($entity, $entity_type) {
|
||||
$dependencies = array();
|
||||
list(,, $bundle_name) = entity_extract_ids($entity_type, $entity);
|
||||
$instances = field_info_instances($entity_type, $bundle_name);
|
||||
|
||||
foreach ($instances as $field_name => $instance) {
|
||||
$field = field_info_field($field_name);
|
||||
foreach ($entity->{$field_name} as $langcode => $items) {
|
||||
$field_dependencies = module_invoke($field['module'], 'node_export_dependency_field', $entity_type, $entity, $field, $instance, $langcode, $items);
|
||||
|
||||
// Let other modules alter dependencies for this field.
|
||||
drupal_alter('node_export_dependency_field', $field_dependencies, $entity_type, $entity, $field, $instance, $langcode, $items);
|
||||
|
||||
if (!empty($field_dependencies)) {
|
||||
foreach ($field_dependencies as &$field_dependency) {
|
||||
if (empty($field_dependency['module'])) {
|
||||
$field_dependency['module'] = $field['module'];
|
||||
}
|
||||
if (empty($field_dependency['field_name'])) {
|
||||
$field_dependency['field_name'] = $field_name;
|
||||
}
|
||||
if (empty($field_dependency['langcode'])) {
|
||||
$field_dependency['langcode'] = $langcode;
|
||||
}
|
||||
}
|
||||
$dependencies = array_merge_recursive($dependencies, $field_dependencies);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency_field().
|
||||
*/
|
||||
function taxonomy_node_export_dependency_field($entity_type, $entity, $field, $instance, $langcode, $items) {
|
||||
// No need to check for the field type here, since this hook is only called
|
||||
// for the owner of this field. Taxonomy module only owns one field.
|
||||
$dependencies = array();
|
||||
node_export_dependency_add($dependencies, $items, 'taxonomy_term', 'tid');
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency_field().
|
||||
*/
|
||||
function file_node_export_dependency_field($entity_type, $entity, $field, $instance, $langcode, $items) {
|
||||
$dependencies = array();
|
||||
node_export_dependency_add($dependencies, $items, 'file', 'fid');
|
||||
node_export_dependency_add($dependencies, $items, 'user', 'uid');
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency_field().
|
||||
*/
|
||||
function image_node_export_dependency_field($entity_type, $entity, $field, $instance, $langcode, $items) {
|
||||
return file_node_export_dependency_field($entity_type, $entity, $field, $instance, $langcode, $items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency_field().
|
||||
*/
|
||||
function node_reference_node_export_dependency_field($entity_type, $entity, $field, $instance, $langcode, $items) {
|
||||
$dependencies = array();
|
||||
node_export_dependency_add($dependencies, $items, 'node', 'nid');
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency_field().
|
||||
*/
|
||||
function user_reference_node_export_dependency_field($entity_type, $entity, $field, $instance, $langcode, $items) {
|
||||
$dependencies = array();
|
||||
node_export_dependency_add($dependencies, $items, 'user', 'uid');
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency_field().
|
||||
*/
|
||||
function entityreference_node_export_dependency_field($entity_type, $entity, $field, $instance, $langcode, $items) {
|
||||
$dependencies = array();
|
||||
node_export_dependency_add($dependencies, $items, $field['settings']['target_type'], 'target_id');
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency_field().
|
||||
*/
|
||||
function field_collection_node_export_dependency_field($entity_type, $entity, $field, $instance, $langcode, $items) {
|
||||
$dependencies = array();
|
||||
node_export_dependency_add($dependencies, $items, 'field_collection_item', 'value');
|
||||
return $dependencies;
|
||||
}
|
||||
|
@@ -0,0 +1,12 @@
|
||||
name = Node export dependency (experimental)
|
||||
description = Helps maintain relationships to dependent entities. Intended to make Node export relation obsolete.
|
||||
dependencies[] = node_export
|
||||
dependencies[] = uuid
|
||||
core = 7.x
|
||||
package = "Node export"
|
||||
; Information added by drupal.org packaging script on 2012-08-20
|
||||
version = "7.x-3.0"
|
||||
core = "7.x"
|
||||
project = "node_export"
|
||||
datestamp = "1345435979"
|
||||
|
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export dependency install file.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_uninstall().
|
||||
*/
|
||||
function node_export_dependency_uninstall() {
|
||||
variable_del('node_export_dependency');
|
||||
variable_del('node_export_dependency_lock');
|
||||
variable_del('node_export_dependency_disable_modules');
|
||||
variable_del('node_export_dependency_attach_nodes');
|
||||
variable_del('node_export_dependency_abort');
|
||||
variable_del('node_export_dependency_existing');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_requirements().
|
||||
*/
|
||||
function node_export_dependency_requirements($phase) {
|
||||
$requirements = array();
|
||||
if ($phase == 'install') {
|
||||
// Ensure translations don't break at install time
|
||||
$t = get_t();
|
||||
|
||||
if (module_exists('node_export_relation')) {
|
||||
$requirements['node_export_relation'] = array(
|
||||
'title' => 'Node export relation',
|
||||
'description' => $t(
|
||||
'Node export dependency cannot be installed when Node export relation is in use.'
|
||||
),
|
||||
'severity' => REQUIREMENT_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $requirements;
|
||||
}
|
@@ -0,0 +1,411 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export dependency module.
|
||||
*
|
||||
* Helps maintain relationships to dependent entities.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Callback for node reference settings form.
|
||||
*/
|
||||
function node_export_dependency_form_node_export_settings_alter(&$form, &$form_state, $form_id) {
|
||||
// @todo: remove the node_export_dependency.core.inc file if solved: [#1590312]
|
||||
module_load_include('inc', 'node_export_dependency', 'node_export_dependency.core');
|
||||
|
||||
$form['node_export_dependency'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Dependencies'),
|
||||
);
|
||||
|
||||
$modules_options = array();
|
||||
$modules = module_implements('node_export_dependency');
|
||||
foreach ($modules as $module) {
|
||||
if ($module != 'field') {
|
||||
$module_info = system_get_info('module', $module);
|
||||
$modules_options[$module] = $module_info['name'];
|
||||
}
|
||||
}
|
||||
$modules = module_implements('node_export_dependency_field');
|
||||
foreach ($modules as $module) {
|
||||
$module_info = system_get_info('module', $module);
|
||||
$modules_options[$module] = t('Field') . ': ' . $module_info['name'];
|
||||
}
|
||||
|
||||
natcasesort($modules_options);
|
||||
|
||||
$form['node_export_dependency']['node_export_dependency_disable_modules'] = array(
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => t('Disable dependencies by module'),
|
||||
'#default_value' => variable_get('node_export_dependency_disable_modules', array()),
|
||||
'#options' => $modules_options,
|
||||
'#description' => t('Choose modules for which to disable dependencies.'),
|
||||
);
|
||||
|
||||
$form['node_export_dependency']['node_export_dependency_attach_nodes'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Attach dependent nodes to export automatically.'),
|
||||
'#default_value' => variable_get('node_export_dependency_attach_nodes', 1),
|
||||
);
|
||||
|
||||
$form['node_export_dependency']['node_export_dependency_abort'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Abort the export when a dependent node cannot be exported.'),
|
||||
'#default_value' => variable_get('node_export_dependency_abort', 0),
|
||||
'#description' => t('Applies when attaching dependent nodes.'),
|
||||
);
|
||||
|
||||
$form['node_export_dependency']['node_export_dependency_existing'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Maintain dependency to original node.'),
|
||||
'#default_value' => variable_get('node_export_dependency_existing', 1),
|
||||
'#description' => t('Applies when <em>Create a new node</em> imports a duplicate dependent node.') . '<strong>' . t('Disabling this is not yet supported.') . '</strong>',
|
||||
'#disabled' => TRUE,
|
||||
);
|
||||
|
||||
$disabled_modules = variable_get('node_export_dependency_disable_modules', array());
|
||||
foreach (element_children($form['publishing']) as $type) {
|
||||
if (empty($disabled_modules['node'])) {
|
||||
$form['publishing'][$type]['node_export_reset_author_' . $type]['#disabled'] = TRUE;
|
||||
$form['publishing'][$type]['node_export_reset_author_' . $type]['#description'] .= ' <strong>' . t('Disabled by <em>Node export dependency</em> because <em>Node module</em> dependencies are enabled.') . '</strong>';
|
||||
$form['publishing'][$type]['node_export_reset_author_' . $type]['#default_value'] = FALSE;
|
||||
variable_set('node_export_reset_author_' . $type, FALSE);
|
||||
}
|
||||
if (empty($disabled_modules['book'])) {
|
||||
$form['publishing'][$type]['node_export_reset_book_mlid_' . $type]['#disabled'] = TRUE;
|
||||
$form['publishing'][$type]['node_export_reset_book_mlid_' . $type]['#description'] .= ' <strong>' . t('Disabled by <em>Node export dependency</em> because <em>Book module</em> dependencies are enabled.') . '</strong>';
|
||||
$form['publishing'][$type]['node_export_reset_book_mlid_' . $type]['#default_value'] = FALSE;
|
||||
variable_set('node_export_reset_book_mlid_' . $type, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_alter().
|
||||
*/
|
||||
function node_export_dependency_node_export_alter(&$nodes, $format) {
|
||||
// Keyed nodes are important for preventing duplicate nodes.
|
||||
$keyed_nodes = array();
|
||||
foreach ($nodes as $node) {
|
||||
$keyed_nodes[$node->nid] = $node;
|
||||
}
|
||||
foreach (array_keys($keyed_nodes) as $nid) {
|
||||
node_export_dependency_load_dependencies($keyed_nodes, $nid);
|
||||
}
|
||||
$nodes = array_values($keyed_nodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively load dependencies.
|
||||
*/
|
||||
function node_export_dependency_load_dependencies(&$nodes, $nid) {
|
||||
$node = &$nodes[$nid];
|
||||
$dependencies = node_export_dependency_get_dependencies('node', $node);
|
||||
foreach ($dependencies as $dep_key => &$dependency) {
|
||||
$disabled_modules = variable_get('node_export_dependency_disable_modules', array());
|
||||
if (!empty($disabled_modules[$dependency['module']])) {
|
||||
unset($dependencies[$dep_key]);
|
||||
continue;
|
||||
}
|
||||
$uuid = node_export_dependency_get_uuid($dependency['type'], $dependency['id']);
|
||||
$dependency['uuid'] = $uuid;
|
||||
if ($dependency['type'] == 'node' && variable_get('node_export_dependency_attach_nodes', 1)) {
|
||||
// It the node doesn't exist in keyed nodes, add it.
|
||||
if (!isset($nodes[$dependency['id']])) {
|
||||
$new_node = node_load($dependency['id']);
|
||||
if (node_export_access_export($new_node)) {
|
||||
$new_node = node_export_prepare_node($new_node);
|
||||
$nodes[$new_node->nid] = $new_node;
|
||||
// Recursively load dependent nodes.
|
||||
node_export_dependency_load_dependencies($nodes, $new_node->nid);
|
||||
}
|
||||
elseif (variable_get('node_export_dependency_abort', 0)) {
|
||||
// Set this node to FALSE to trigger an error in node export.
|
||||
// Do not use $new_node in this code in case there is a problem with it.
|
||||
$nodes[$dependency['id']] = FALSE;
|
||||
// Add a warning to watchdog.
|
||||
watchdog('node_export_dependency', 'No access to export node dependency %nid', array('%nid' => $dependency['id']), WATCHDOG_WARNING);
|
||||
drupal_set_message(t('No access to export node dependency %nid', array('%nid' => $dependency['id'])), 'error', FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($dependencies)) {
|
||||
$node->node_export_dependency = $dependencies;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_import_alter().
|
||||
*/
|
||||
function node_export_dependency_node_export_import_alter($nodes, $format) {
|
||||
$node_export_dependency = variable_get('node_export_dependency', array());
|
||||
|
||||
foreach ($nodes as $node) {
|
||||
if (isset($node->node_export_dependency)) {
|
||||
foreach ($node->node_export_dependency as $dep_key => $dependency) {
|
||||
// Try to handle this dependency now, and unset if successfull.
|
||||
// Only do this now if maintaining dependency to original node, because
|
||||
// if that setting is turned off, doing this at this stage will break
|
||||
// things.
|
||||
if (
|
||||
variable_get('node_export_dependency_existing', 1) &&
|
||||
node_export_dependency_handle_dependency($node, $dependency)
|
||||
) {
|
||||
unset($node->node_export_dependency[$dep_key]);
|
||||
}
|
||||
else {
|
||||
// Couldn't handle, store for later.
|
||||
$node_export_dependency[$node->uuid][] = $dependency;
|
||||
// Set the property to 0 to prevent database errors.
|
||||
node_export_dependency_set_property($node, $dependency, 0);
|
||||
}
|
||||
}
|
||||
unset($node->node_export_dependency);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($node_export_dependency)) {
|
||||
variable_set('node_export_dependency', $node_export_dependency);
|
||||
}
|
||||
else {
|
||||
variable_del('node_export_dependency');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to process outstanding dependencies.
|
||||
*
|
||||
* This should only be called when the parent node to fix is already saved.
|
||||
*
|
||||
* @param $iterations
|
||||
* How many iterations to run.
|
||||
* @param $seconds
|
||||
* How long to lock others from processing (will release upon completion).
|
||||
*/
|
||||
function node_export_dependency_process_outstanding_dependencies($iterations, $seconds = 240) {
|
||||
if (REQUEST_TIME - variable_get('node_export_dependency_lock', REQUEST_TIME) >= 0) {
|
||||
variable_set('node_export_dependency_lock', REQUEST_TIME + $seconds);
|
||||
$node_export_dependency = variable_get('node_export_dependency', array());
|
||||
|
||||
// Iterate $node_export_dependency and try to handle any others.
|
||||
$node_export_dependency_keys = array_keys($node_export_dependency);
|
||||
// Shuffle so we don't get 'stuck' on a bunch of unsolvable cases.
|
||||
shuffle($node_export_dependency_keys);
|
||||
for ($count = 0; $count < $iterations; $count++) {
|
||||
$node_uuid = next($node_export_dependency_keys);
|
||||
if ($node_uuid === FALSE && empty($node_export_dependency_keys)) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
$node_uuid = reset($node_export_dependency_keys);
|
||||
}
|
||||
$dependencies = &$node_export_dependency[$node_uuid];
|
||||
foreach ($dependencies as $dep_key => &$dependency) {
|
||||
$nids = entity_get_id_by_uuid('node', array($node_uuid));
|
||||
$node = node_load($nids[$node_uuid]);
|
||||
if (!empty($node)) {
|
||||
// Try to handle this dependency now, and unset if successfull.
|
||||
if (node_export_dependency_handle_dependency($node, $dependency)) {
|
||||
unset($dependencies[$dep_key]);
|
||||
node_save($node);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($node_export_dependency[$node_uuid])) {
|
||||
unset($node_export_dependency[$node_uuid]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($node_export_dependency)) {
|
||||
variable_set('node_export_dependency', $node_export_dependency);
|
||||
}
|
||||
else {
|
||||
variable_del('node_export_dependency');
|
||||
}
|
||||
variable_del('node_export_dependency_lock');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_cron().
|
||||
*/
|
||||
function node_export_dependency_cron() {
|
||||
node_export_dependency_process_outstanding_dependencies(50);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_init().
|
||||
*/
|
||||
function node_export_dependency_init() {
|
||||
$node_export_dependency = variable_get('node_export_dependency', array());
|
||||
if (!empty($node_export_dependency)) {
|
||||
node_export_dependency_process_outstanding_dependencies(10);
|
||||
if (count($node_export_dependency) > 20) {
|
||||
drupal_set_message(
|
||||
t(
|
||||
'There are %num outstanding Node export dependencies, please complete the imports and run cron as soon as possible.',
|
||||
array('%num' => count($node_export_dependency))
|
||||
),
|
||||
'warning'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to handle a dependency.
|
||||
*
|
||||
* @return
|
||||
* TRUE or FALSE whether the dependency was handled.
|
||||
*/
|
||||
function node_export_dependency_handle_dependency(&$node, $dependency) {
|
||||
$handled = FALSE;
|
||||
$disabled_modules = variable_get('node_export_dependency_disable_modules', array());
|
||||
if (!empty($disabled_modules[$dependency['module']])) {
|
||||
// We're not handling it, so it is 'handled'.
|
||||
return TRUE;
|
||||
}
|
||||
if (!isset($dependency['relationship'])) {
|
||||
// Entity id.
|
||||
$entity_ids = entity_get_id_by_uuid($dependency['type'], array($dependency['uuid']));
|
||||
$entity_id = $entity_ids ? reset($entity_ids) : FALSE;
|
||||
if ($entity_id) {
|
||||
node_export_dependency_set_property($node, $dependency, $entity_id);
|
||||
}
|
||||
$handled = TRUE;
|
||||
}
|
||||
|
||||
drupal_alter('node_export_dependency', $handled, $node, $dependency);
|
||||
|
||||
return $handled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency_alter().
|
||||
*/
|
||||
function node_export_dependency_node_export_dependency_alter(&$handled, &$node, $dependency) {
|
||||
|
||||
// @todo special fixing up for Book and OG nodes and other special cases?
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a property according to $dependency for the property location and $new_value
|
||||
* for the new value.
|
||||
*/
|
||||
function node_export_dependency_set_property(&$entity, $dependency, $new_value) {
|
||||
if (isset($dependency['field_name'])) {
|
||||
// This is a field.
|
||||
$entity->{$dependency['field_name']}[$dependency['langcode']]
|
||||
[$dependency['delta']][$dependency['property']] = $new_value;
|
||||
}
|
||||
else {
|
||||
// Some other property.
|
||||
if (isset($dependency['property'])) {
|
||||
$property_path = $dependency['property'];
|
||||
if (!is_array($property_path)) {
|
||||
$property_path = array($property_path);
|
||||
}
|
||||
$value = &$entity;
|
||||
foreach ($property_path as $p) {
|
||||
if (is_object($value) && isset($value->{$p})) {
|
||||
$value = &$value->{$p};
|
||||
}
|
||||
elseif (is_array($value) && isset($value[$p])) {
|
||||
$value = &$value[$p];
|
||||
}
|
||||
}
|
||||
$value = $new_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to add entity dependencies to a dependency array.
|
||||
*
|
||||
* We never treat user UID 0 or 1 as dependencies. Those are low level user
|
||||
* accounts ("anonymous" and "root") that already exists in most systems.
|
||||
*
|
||||
* @param $dependencies
|
||||
* The dependency array.
|
||||
* @param $objects
|
||||
* Array of objects that should be checked for dependencies in $properties.
|
||||
* @param $entity_type
|
||||
* The type of entity that $properties will add dependency on.
|
||||
* @param $properties
|
||||
* An array of properties that adds dependencies to $objects. All properties
|
||||
* must only point to one entity type at the time. A property can be a key
|
||||
* on the object, or an array of parent keys to identify the property.
|
||||
* @todo remove if this is solved [#1590312]
|
||||
*/
|
||||
function node_export_dependency_add(&$dependencies, $objects, $entity_type, $properties) {
|
||||
if (!is_array($objects)) {
|
||||
$objects = array($objects);
|
||||
}
|
||||
if (!is_array($properties)) {
|
||||
$properties = array($properties);
|
||||
}
|
||||
|
||||
foreach ($objects as $delta => $object) {
|
||||
foreach ($properties as $property) {
|
||||
$property_path = $property;
|
||||
if (!is_array($property_path)) {
|
||||
$property_path = array($property_path);
|
||||
}
|
||||
$value = $object;
|
||||
foreach ($property_path as $p) {
|
||||
if (is_object($value) && isset($value->{$p})) {
|
||||
$value = $value->{$p};
|
||||
}
|
||||
elseif (is_array($value) && isset($value[$p])) {
|
||||
$value = $value[$p];
|
||||
}
|
||||
}
|
||||
if (!empty($value) && $value != $object && !($entity_type == 'user' && (int)$value == 1)) {
|
||||
$dependencies[] = array(
|
||||
'type' => $entity_type,
|
||||
'id' => $value,
|
||||
'delta' => $delta,
|
||||
'property' => $property,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get UUID based on entity id.
|
||||
*/
|
||||
function node_export_dependency_get_uuid($entity_type, $id) {
|
||||
$entity_info = entity_get_info($entity_type);
|
||||
$id_key = $entity_info['entity keys']['id'];
|
||||
return uuid_get_uuid($entity_type, $id_key, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get dependencies of an entity.
|
||||
*
|
||||
* @todo rewrite if this is solved [#1590312]
|
||||
*/
|
||||
function node_export_dependency_get_dependencies($entity_type, $entity) {
|
||||
// @todo: remove the node_export_dependency.core.inc file if solved: [#1590312]
|
||||
module_load_include('inc', 'node_export_dependency', 'node_export_dependency.core');
|
||||
$all_dependencies = array();
|
||||
foreach (module_implements('node_export_dependency') as $module) {
|
||||
$dependencies = module_invoke($module, 'node_export_dependency', $entity, $entity_type);
|
||||
if (isset($dependencies) && is_array($dependencies)) {
|
||||
foreach ($dependencies as &$dependency) {
|
||||
if (empty($dependency['module'])) {
|
||||
$dependency['module'] = $module;
|
||||
}
|
||||
}
|
||||
$all_dependencies = array_merge_recursive($all_dependencies, $dependencies);
|
||||
}
|
||||
}
|
||||
return $all_dependencies;
|
||||
}
|
||||
|
@@ -0,0 +1,13 @@
|
||||
name = Node export features
|
||||
description = Adds Features support to Node export, so you can put your exports into Features modules.
|
||||
dependencies[] = node_export
|
||||
dependencies[] = uuid
|
||||
dependencies[] = features
|
||||
core = 7.x
|
||||
package = "Node export"
|
||||
; Information added by drupal.org packaging script on 2012-08-20
|
||||
version = "7.x-3.0"
|
||||
core = "7.x"
|
||||
project = "node_export"
|
||||
datestamp = "1345435979"
|
||||
|
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implements hook_features_api().
|
||||
*/
|
||||
function node_export_features_features_api() {
|
||||
$features = array();
|
||||
$features['node_export_features'] = array(
|
||||
'name' => t('Node export'),
|
||||
'feature_source' => TRUE,
|
||||
'default_hook' => 'node_export_features_default',
|
||||
'default_file' => FEATURES_DEFAULTS_INCLUDED,
|
||||
);
|
||||
return $features;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_export_options().
|
||||
*/
|
||||
function node_export_features_features_export_options() {
|
||||
$options = array();
|
||||
|
||||
$query = db_select('node', 'n')
|
||||
->fields('n', array('nid', 'title', 'type'))
|
||||
->orderBy('type')
|
||||
->orderBy('title')
|
||||
->range(0, 250)
|
||||
->addTag('node_export_features');
|
||||
|
||||
$result = $query->execute();
|
||||
|
||||
foreach ($result as $row) {
|
||||
$uuid = uuid_get_uuid('node', 'nid', $row->nid);
|
||||
if (empty($uuid)) {
|
||||
drupal_set_message(
|
||||
t('Some nodes are <strong>not</strong> available for export' .
|
||||
' because of missing UUIDs. Ensure UUIDs are being generated for' .
|
||||
' all content types and click the <em>Create missing UUIDs</em>' .
|
||||
' button on the <a href="!url">UUID settings page</a> to help' .
|
||||
' resolve this issue.',
|
||||
array('!url' => url('admin/settings/uuid'))
|
||||
),
|
||||
'warning',
|
||||
FALSE
|
||||
);
|
||||
}
|
||||
else {
|
||||
$options[$uuid] = t('@type: @title', array(
|
||||
'@type' => node_type_get_name($row->type),
|
||||
'@title' => $row->title,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if (count($options) == 250) {
|
||||
drupal_set_message(
|
||||
t('Due to limitations in Features only the first 250 nodes are available.'
|
||||
. ' The query is tagged <em>node_export_features</em> if you want to'
|
||||
. ' alter it.'),
|
||||
'warning'
|
||||
);
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_export().
|
||||
*/
|
||||
function node_export_features_features_export($data, &$export, $module_name = '') {
|
||||
$pipe = array();
|
||||
|
||||
$export['dependencies']['module'] = 'node_export_features';
|
||||
|
||||
foreach ($data as $uuid) {
|
||||
$query = db_select('node', 'n')
|
||||
->fields('n', array('type'))
|
||||
->condition('n.uuid', $uuid);
|
||||
$type = $query->execute()->fetchField();
|
||||
|
||||
$export['features']['node_export_features'][$uuid] = $uuid;
|
||||
$pipe['node'][$type] = $type;
|
||||
}
|
||||
|
||||
return $pipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_export_render().
|
||||
*/
|
||||
function node_export_features_features_export_render($module, $data, $export = NULL) {
|
||||
$nids = entity_get_id_by_uuid('node', $data);
|
||||
$result = node_export($nids);
|
||||
if ($result['success']) {
|
||||
$node_export['code_string'] = $result['output'];
|
||||
$node_export_code = ' $node_export = ' . features_var_export($node_export) . ';';
|
||||
}
|
||||
else {
|
||||
foreach ($result['output'] as $error) {
|
||||
$node_export_code = ' // ' . $error . PHP_EOL;
|
||||
}
|
||||
$node_export_code .= ' $node_export = array();';
|
||||
}
|
||||
$node_export_code .= PHP_EOL . ' return $node_export;';
|
||||
return array('node_export_features_default' => $node_export_code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_revert().
|
||||
*/
|
||||
function node_export_features_features_revert($module = NULL) {
|
||||
node_export_features_features_rebuild($module);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_rebuild().
|
||||
*/
|
||||
function node_export_features_features_rebuild($module) {
|
||||
$node_export = features_get_default('node_export_features', $module);
|
||||
if (!empty($node_export)) {
|
||||
$result = node_export_import($node_export['code_string']);
|
||||
if (!$result['success']) {
|
||||
foreach ($result['output'] as $error) {
|
||||
drupal_set_message($error, 'error');
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach ($result['output'] as $status) {
|
||||
drupal_set_message($status);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Class definition of FeedsNodeExportParser.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Parses a given file as a node export file.
|
||||
*/
|
||||
class FeedsNodeExportParser extends FeedsParser {
|
||||
public $format = NULL;
|
||||
|
||||
/**
|
||||
* Implements FeedsParser::parse().
|
||||
*/
|
||||
public function parse(FeedsSource $source, FeedsFetcherResult $fetcher_result) {
|
||||
|
||||
if (!($source->importer->processor instanceOf FeedsNodeExportProcessor)) {
|
||||
drupal_set_message(
|
||||
t('Node export parser must be used with Node export processor. No nodes imported.'),
|
||||
'error'
|
||||
);
|
||||
return new FeedsParserResult(array());
|
||||
}
|
||||
|
||||
// Get the node export code.
|
||||
$code_string = $fetcher_result->getRaw();
|
||||
|
||||
// @todo: Do we need this stuff?
|
||||
//$source_config = $source->getConfigFor($this);
|
||||
//$state = $source->state(FEEDS_PARSE);
|
||||
|
||||
// Execute node_export_import() but don't have it save the nodes.
|
||||
$result = node_export_import($code_string, 't', FALSE);
|
||||
|
||||
// Handle failure.
|
||||
if (!$result['success']) {
|
||||
foreach ($result['output'] as $error) {
|
||||
// @todo: Is this what we should do with output messages?
|
||||
drupal_set_message($error, 'error');
|
||||
}
|
||||
// @todo: Is this the right thing to return for a failure?
|
||||
return new FeedsParserResult(array());
|
||||
}
|
||||
|
||||
|
||||
foreach ($result['output'] as $status) {
|
||||
// @todo: Is this what we should do with output messages?
|
||||
drupal_set_message($status);
|
||||
}
|
||||
|
||||
// Feeds needs the nodes to be arrays.
|
||||
// @todo: Should we try to get node_export_import() to return arrays in the
|
||||
// first place? Or perhaps have the processor accept objects?
|
||||
foreach ($result['nodes'] as $node) {
|
||||
$items[] = (array)$node;
|
||||
}
|
||||
|
||||
// Store the format that was used.
|
||||
$this->format = $result['format'];
|
||||
|
||||
/*
|
||||
|
||||
// Node export doesn't support batchy stuffs atm.
|
||||
|
||||
|
||||
// Determine section to parse, parse.
|
||||
$start = $state->pointer ? $state->pointer : $parser->lastLinePos();
|
||||
$limit = $source->importer->getLimit();
|
||||
$rows = $this->parseItems($parser, $iterator, $start, $limit);
|
||||
|
||||
// Report progress.
|
||||
$state->total = filesize($fetcher_result->getFilePath());
|
||||
$state->pointer = $parser->lastLinePos();
|
||||
$progress = $parser->lastLinePos() ? $parser->lastLinePos() : $state->total;
|
||||
$state->progress($state->total, $progress);
|
||||
*/
|
||||
|
||||
// Create a result object and return it.
|
||||
return new FeedsParserResult($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override parent::getMappingSources().
|
||||
*/
|
||||
public function getMappingSources() {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override parent::getSourceElement() to use only lower keys.
|
||||
*/
|
||||
public function getSourceElement(FeedsSource $source, FeedsParserResult $result, $element_key) {
|
||||
return parent::getSourceElement($source, $result, drupal_strtolower($element_key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Define defaults.
|
||||
*/
|
||||
public function sourceDefaults() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Source form.
|
||||
*
|
||||
* Show mapping configuration as a guidance for import form users.
|
||||
*/
|
||||
public function sourceForm($source_config) {
|
||||
$form = array();
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define default configuration.
|
||||
*/
|
||||
public function configDefaults() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build configuration form.
|
||||
*/
|
||||
public function configForm(&$form_state) {
|
||||
$form = array();
|
||||
$form['info'] = array(
|
||||
'#prefix' => '<p>',
|
||||
'#markup' => t(
|
||||
'This parser uses settings from <a href="!config">node export</a>.',
|
||||
array('!config' => url('admin/config/content/node_export'))
|
||||
),
|
||||
'#suffix' => '</p>',
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function getTemplate() {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Class definition of FeedsNodeExportProcessor.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates nodes from feed items.
|
||||
*/
|
||||
class FeedsNodeExportProcessor extends FeedsNodeProcessor {
|
||||
public $new_nodes = array();
|
||||
|
||||
/**
|
||||
* Process the result of the parsing stage.
|
||||
*
|
||||
* @param FeedsSource $source
|
||||
* Source information about this import.
|
||||
* @param FeedsParserResult $parser_result
|
||||
* The result of the parsing stage.
|
||||
*/
|
||||
public function process(FeedsSource $source, FeedsParserResult $parser_result) {
|
||||
|
||||
if (!($source->importer->parser instanceOf FeedsNodeExportParser)) {
|
||||
drupal_set_message(
|
||||
t('Node export processor must be used with Node export parser. No nodes imported.'),
|
||||
'error',
|
||||
FALSE
|
||||
);
|
||||
return new FeedsParserResult(array());
|
||||
}
|
||||
|
||||
parent::process($source, $parser_result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new node in memory and returns it.
|
||||
*/
|
||||
/*
|
||||
|
||||
@todo: Should we override this function?
|
||||
|
||||
protected function newEntity(FeedsSource $source) {
|
||||
$node = new stdClass();
|
||||
$node->type = $this->config['content_type'];
|
||||
$node->changed = REQUEST_TIME;
|
||||
$node->created = REQUEST_TIME;
|
||||
$node->language = LANGUAGE_NONE;
|
||||
node_object_prepare($node);
|
||||
// Populate properties that are set by node_object_prepare().
|
||||
$node->log = 'Created by FeedsNodeProcessor';
|
||||
$node->uid = $this->config['author'];
|
||||
return $node;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Loads an existing node.
|
||||
*
|
||||
* If the update existing method is not FEEDS_UPDATE_EXISTING, only the node
|
||||
* table will be loaded, foregoing the node_load API for better performance.
|
||||
*/
|
||||
/*
|
||||
|
||||
@todo: Should we override this function?
|
||||
|
||||
protected function entityLoad(FeedsSource $source, $nid) {
|
||||
if ($this->config['update_existing'] == FEEDS_UPDATE_EXISTING) {
|
||||
$node = node_load($nid, NULL, TRUE);
|
||||
}
|
||||
else {
|
||||
// We're replacing the existing node. Only save the absolutely necessary.
|
||||
$node = db_query("SELECT created, nid, vid, type FROM {node} WHERE nid = :nid", array(':nid' => $nid))->fetchObject();
|
||||
$node->uid = $this->config['author'];
|
||||
}
|
||||
node_object_prepare($node);
|
||||
// Populate properties that are set by node_object_prepare().
|
||||
if ($this->config['update_existing'] == FEEDS_UPDATE_EXISTING) {
|
||||
$node->log = 'Updated by FeedsNodeProcessor';
|
||||
}
|
||||
else {
|
||||
$node->log = 'Replaced by FeedsNodeProcessor';
|
||||
}
|
||||
return $node;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Save a node.
|
||||
*
|
||||
* This code is similar to some code in node_export_import()
|
||||
* which gets executed for each node when the $save param is TRUE.
|
||||
*
|
||||
* @todo: should we check to make sure FeedsNodeExportParser was used?
|
||||
*/
|
||||
public function entitySave($entity) {
|
||||
$node = &$entity;
|
||||
node_export_save($node);
|
||||
$this->new_nodes[$node->nid] = $node;
|
||||
// @todo: Is this what we should do with output messages?
|
||||
drupal_set_message(t("Imported node !nid: !node", array('!nid' => $node->nid, '!node' => l($node->title, 'node/' . $node->nid))));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
name = "Node export feeds"
|
||||
description = "Node export feeds importer. This is a more advanced importer than the one built into node export, but tricky to use."
|
||||
core = "7.x"
|
||||
package = "Node export"
|
||||
dependencies[] = "feeds"
|
||||
dependencies[] = "node_export"
|
||||
files[] = FeedsNodeExportParser.inc
|
||||
files[] = FeedsNodeExportProcessor.inc
|
||||
; Information added by drupal.org packaging script on 2012-08-20
|
||||
version = "7.x-3.0"
|
||||
core = "7.x"
|
||||
project = "node_export"
|
||||
datestamp = "1345435979"
|
||||
|
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Node export feeds importer.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of hook_ctools_plugin_api().
|
||||
*/
|
||||
function node_export_feeds_ctools_plugin_api($module = '', $api = '') {
|
||||
if ($module == 'feeds' && in_array($api, array('feeds_importer_default', 'plugins'))) {
|
||||
return array('version' => 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_feeds_plugins().
|
||||
*/
|
||||
function node_export_feeds_feeds_plugins() {
|
||||
$info = array();
|
||||
$info['FeedsNodeExportParser'] = array(
|
||||
'name' => 'Node export parser',
|
||||
'description' => 'Parse a node export.',
|
||||
'help' => 'Parses the output from the node export module.',
|
||||
'handler' => array(
|
||||
'parent' => 'FeedsParser',
|
||||
'class' => 'FeedsNodeExportParser',
|
||||
'file' => 'FeedsNodeExportParser.inc',
|
||||
'path' => drupal_get_path('module', 'node_export_feeds'),
|
||||
),
|
||||
);
|
||||
$info['FeedsNodeExportProcessor'] = array(
|
||||
'name' => 'Node Export Processor',
|
||||
'description' => 'Process a node export.',
|
||||
'help' => 'Processes the output from the node export module.',
|
||||
'handler' => array(
|
||||
'parent' => 'FeedsNodeProcessor',
|
||||
'class' => 'FeedsNodeExportProcessor',
|
||||
'file' => 'FeedsNodeExportProcessor.inc',
|
||||
'path' => drupal_get_path('module', 'node_export_feeds'),
|
||||
),
|
||||
);
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_feeds_importer_default().
|
||||
*/
|
||||
function node_export_feeds_feeds_importer_default() {
|
||||
$export = array();
|
||||
|
||||
// Commented out properties seem to be unsupported targets in feeds?
|
||||
$mappings_keys = array(
|
||||
//'vid',
|
||||
'uid',
|
||||
'title',
|
||||
//'log',
|
||||
'status',
|
||||
'comment',
|
||||
'promote',
|
||||
'sticky',
|
||||
//'vuuid',
|
||||
'nid',
|
||||
//'type',
|
||||
'language',
|
||||
'created',
|
||||
//'changed',
|
||||
//'tnid',
|
||||
//'translate',
|
||||
//'uuid',
|
||||
//'revision_timestamp',
|
||||
//'revision_uid',
|
||||
'body',
|
||||
//'rdf_mapping',
|
||||
//'cid',
|
||||
//'last_comment_timestamp',
|
||||
//'last_comment_name',
|
||||
//'last_comment_uid',
|
||||
//'comment_count',
|
||||
//'name',
|
||||
//'picture',
|
||||
//'data',
|
||||
//'path',
|
||||
//'menu',
|
||||
//'node_export_drupal_version',
|
||||
);
|
||||
$mappings = array();
|
||||
foreach ($mappings_keys as $mappings_key) {
|
||||
$mappings[] = array(
|
||||
'source' => $mappings_key,
|
||||
'target' => $mappings_key,
|
||||
'unique' => FALSE,
|
||||
);
|
||||
}
|
||||
$mappings[] = array(
|
||||
'source' => 'uuid',
|
||||
'target' => 'guid',
|
||||
'unique' => 1,
|
||||
);
|
||||
|
||||
$feeds_importer = new stdClass;
|
||||
$feeds_importer->disabled = FALSE;
|
||||
$feeds_importer->api_version = 1;
|
||||
$feeds_importer->id = 'node_export';
|
||||
$feeds_importer->config = array(
|
||||
'name' => 'Node export import',
|
||||
'description' => 'Import nodes from node export.',
|
||||
'fetcher' => array(
|
||||
'plugin_key' => 'FeedsFileFetcher',
|
||||
'config' => array(
|
||||
'allowed_extensions' => 'export txt csv tsv xml opml',
|
||||
'direct' => FALSE,
|
||||
),
|
||||
),
|
||||
'parser' => array(
|
||||
'plugin_key' => 'FeedsNodeExportParser',
|
||||
'config' => array(),
|
||||
),
|
||||
'processor' => array(
|
||||
'plugin_key' => 'FeedsNodeExportProcessor',
|
||||
'config' => array(
|
||||
'content_type' => 'article',
|
||||
'update_existing' => 1,
|
||||
'expire' => '-1',
|
||||
'mappings' => $mappings,
|
||||
'input_format' => 'plain_text',
|
||||
'author' => 0,
|
||||
),
|
||||
),
|
||||
'content_type' => '',
|
||||
'update' => 0,
|
||||
'import_period' => '-1',
|
||||
'expire_period' => 3600,
|
||||
'import_on_create' => 1,
|
||||
);
|
||||
$export['node_export'] = $feeds_importer;
|
||||
|
||||
return $export;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_feeds_after_import().
|
||||
*/
|
||||
function node_export_feeds_feeds_after_import($source) {
|
||||
if ($source->importer->processor instanceOf FeedsNodeExportProcessor && !empty($source->importer->processor->new_nodes)) {
|
||||
// This code is similar to some code in node_export_import()
|
||||
// which gets executed for all nodes when the $save param is TRUE.
|
||||
$save = TRUE;
|
||||
drupal_alter('node_export_after_import', $source->importer->processor->new_nodes, $source->importer->parser->format, $save);
|
||||
// @todo: Is this what we should do with output messages?
|
||||
drupal_set_message(("Some values may have been reset depending on Node export's configuration."));
|
||||
|
||||
// Clear the page and block caches.
|
||||
cache_clear_all();
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
name = Node export relation (deprecated)
|
||||
description = Helps maintain relationships. Supports node references, taxonomy, and organic groups.
|
||||
dependencies[] = node_export
|
||||
dependencies[] = uuid
|
||||
core = 7.x
|
||||
package = "Node export"
|
||||
; Information added by drupal.org packaging script on 2012-08-20
|
||||
version = "7.x-3.0"
|
||||
core = "7.x"
|
||||
project = "node_export"
|
||||
datestamp = "1345435979"
|
||||
|
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export relation install file.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_uninstall().
|
||||
*/
|
||||
function node_export_relation_uninstall() {
|
||||
// Node reference.
|
||||
variable_del('node_export_node_reference_auto_inc');
|
||||
variable_del('node_export_node_reference_skip');
|
||||
|
||||
// Organic groups.
|
||||
variable_del('node_export_og_auto_inc');
|
||||
variable_del('node_export_og_skip');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_requirements().
|
||||
*/
|
||||
function node_export_relation_requirements($phase) {
|
||||
$requirements = array();
|
||||
|
||||
// Ensure translations don't break at install time
|
||||
$t = get_t();
|
||||
|
||||
if (module_exists('node_export_dependency')) {
|
||||
$requirements['node_export_dependency'] = array(
|
||||
'title' => 'Node export dependency',
|
||||
'description' => $t(
|
||||
'Node export relation is deprecated in favour of Node export dependency. You cannot use both.'
|
||||
),
|
||||
'severity' => REQUIREMENT_ERROR,
|
||||
);
|
||||
}
|
||||
|
||||
return $requirements;
|
||||
}
|
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export relation module.
|
||||
*
|
||||
* Helps maintain relationships between nodes during node export operations.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Callback for node reference settings form.
|
||||
*/
|
||||
function node_export_relation_form_node_export_settings_alter(&$form, &$form_state, $form_id) {
|
||||
if (module_exists('node_reference')) {
|
||||
module_load_include('inc', 'node_export_relation', 'node_export_relation.node_reference');
|
||||
node_export_relation_settings_form_node_reference($form, $form_state, $form_id);
|
||||
}
|
||||
/*
|
||||
// None of the settings are supported yet.
|
||||
|
||||
if (module_exists('og')) {
|
||||
module_load_include('inc', 'node_export_relation', 'node_export_relation.og');
|
||||
node_export_relation_settings_form_og($form, $form_state, $form_id);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_alter().
|
||||
*/
|
||||
function node_export_relation_node_export_alter(&$nodes, $format) {
|
||||
|
||||
if (module_exists('node_reference')) {
|
||||
module_load_include('inc', 'node_export_relation', 'node_export_relation.node_reference');
|
||||
if (variable_get('node_export_node_reference_auto_inc', TRUE)) {
|
||||
$keyed_nodes = array();
|
||||
foreach ($nodes as $node) {
|
||||
$keyed_nodes[$node->nid] = $node;
|
||||
}
|
||||
// Keyed nodes are important for preventing same node loaded again via references.
|
||||
foreach (array_keys($keyed_nodes) as $nid) {
|
||||
node_export_relation_node_reference_load($keyed_nodes, $nid);
|
||||
}
|
||||
$nodes = array_values($keyed_nodes);
|
||||
}
|
||||
}
|
||||
|
||||
if (module_exists('og')) {
|
||||
module_load_include('inc', 'node_export_relation', 'node_export_relation.og');
|
||||
// Go through nodes and set UUIDs for their groups.
|
||||
node_export_relation_og_set_group_uuids($nodes);
|
||||
}
|
||||
|
||||
if (module_exists('taxonomy')) {
|
||||
module_load_include('inc', 'node_export_relation', 'node_export_relation.taxonomy');
|
||||
foreach ($nodes as $node) {
|
||||
node_export_relation_taxonomy_build_term_reference($node);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_import_alter().
|
||||
*/
|
||||
function node_export_relation_node_export_import_alter(&$nodes, $format) {
|
||||
|
||||
if (module_exists('node_reference')) {
|
||||
module_load_include('inc', 'node_export_relation', 'node_export_relation.node_reference');
|
||||
foreach ($nodes as $node) {
|
||||
node_export_relation_node_reference_map($node->nid, $node->uuid);
|
||||
}
|
||||
}
|
||||
|
||||
if (module_exists('og')) {
|
||||
module_load_include('inc', 'node_export_relation', 'node_export_relation.og');
|
||||
// Now go through the groupes and switch back the UUIDS to actual ids.
|
||||
node_export_relation_og_set_group_nids($nodes);
|
||||
}
|
||||
|
||||
if (module_exists('taxonomy')) {
|
||||
module_load_include('inc', 'node_export_relation', 'node_export_relation.taxonomy');
|
||||
foreach ($nodes as $node) {
|
||||
node_export_relation_taxonomy_restore_term_reference($node);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_after_import_alter().
|
||||
*/
|
||||
function node_export_relation_node_export_after_import_alter(&$nodes, $format) {
|
||||
|
||||
if (module_exists('node_reference')) {
|
||||
module_load_include('inc', 'node_export_relation', 'node_export_relation.node_reference');
|
||||
// Now that all nodes are imported/updated we can restore the node referenced from UUIDS
|
||||
// NOTE: This is done because if the node referenced node is new, they we have
|
||||
// to wait for node to be saved.
|
||||
node_export_relation_node_reference_update($nodes);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export relation node reference include.
|
||||
*
|
||||
* Helps maintain node reference relationships between nodes during node export operations.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_form_FORM_ID_alter().
|
||||
*/
|
||||
function node_export_relation_settings_form_node_reference(&$form, &$form_state, $form_id) {
|
||||
$form['node_reference'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Node references'),
|
||||
);
|
||||
|
||||
// Not supported yet.
|
||||
$form['node_reference']['node_export_node_reference_auto_inc'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Automatically include referenced nodes in exports'),
|
||||
'#default' => variable_get('node_export_node_reference_auto_inc', TRUE),
|
||||
);
|
||||
|
||||
$form['node_reference']['node_export_node_reference_skip'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Skip referenced nodes that cannot be exported'),
|
||||
'#default' => variable_get('node_export_node_reference_skip', TRUE),
|
||||
'#description' => t('If this is disabled, node exports will fail if a referenced node cannot be exported, for example if the user performing the export does not have access.'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update node references after import.
|
||||
*/
|
||||
function node_export_relation_node_reference_update($nodes) {
|
||||
foreach ($nodes as $node) {
|
||||
$uuid[$node->uuid] = $node->nid;
|
||||
}
|
||||
foreach ($nodes as $node) {
|
||||
$node_reference_fields = node_export_relation_node_reference_fields($node->type);
|
||||
if (!empty($node_reference_fields)) {
|
||||
foreach ($node_reference_fields as $node_reference_field) {
|
||||
$items = field_get_items('node', $node, $node_reference_field);
|
||||
$langcode = field_language('node', $node, $node_reference_field);
|
||||
if (!empty($items)) {
|
||||
foreach ($items as $key => &$node_reference) {
|
||||
if (!empty($node_reference['nid'])) {
|
||||
$node_uuid = node_export_relation_node_reference_map($node_reference['nid']);
|
||||
$node->{$node_reference_field}[$langcode][$key] = array('nid' => $uuid[$node_uuid]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node_save($node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively load node references.
|
||||
*/
|
||||
function node_export_relation_node_reference_load(&$nodes, $nid) {
|
||||
// Alias for easy referencing.
|
||||
$node = &$nodes[$nid];
|
||||
|
||||
// Get list of node reference fields for this node
|
||||
$node_reference_fields = node_export_relation_node_reference_fields($node->type);
|
||||
if (!empty($node_reference_fields)) {
|
||||
foreach ($node_reference_fields as $node_reference_field) {
|
||||
$items = field_get_items('node', $node, $node_reference_field);
|
||||
if (!empty($items)) {
|
||||
foreach ($items as &$node_reference) {
|
||||
if (!empty($node_reference['nid'])) {
|
||||
// Load the referenced nodes only if its not already loaded
|
||||
// This will save if from infinite loop of back references
|
||||
if (!isset($nodes[$node_reference['nid']])) {
|
||||
$new_node = node_load($node_reference['nid']);
|
||||
if (node_export_access_export($new_node)) {
|
||||
$new_node = node_export_prepare_node($new_node);
|
||||
$nodes[$new_node->nid] = $new_node;
|
||||
// Recursively load references of new nodes
|
||||
node_export_relation_node_reference_load($nodes, $new_node->nid);
|
||||
}
|
||||
elseif (!variable_get('node_export_node_reference_skip', TRUE)) {
|
||||
// Set this node to FALSE to trigger an error in node export.
|
||||
// Do not use $new_node in this code in case there is a problem with it.
|
||||
$nodes[$node_reference['nid']] = FALSE;
|
||||
// Add a warning to watchdog.
|
||||
watchdog('node_export_relation', 'No access to export node reference %nid', array('%nid' => $node_reference['nid']), WATCHDOG_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Statically cache old node ids for mapping.
|
||||
*/
|
||||
function node_export_relation_node_reference_map($id, $uuid = NULL, $type = 'node') {
|
||||
static $map;
|
||||
if (isset($uuid)) {
|
||||
$map[$type][$id] = $uuid;
|
||||
}
|
||||
else {
|
||||
return $map[$type][$id];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array listing the names of all node reference fields.
|
||||
*
|
||||
* @return
|
||||
* Array of all created node reference fields.
|
||||
*/
|
||||
function node_export_relation_node_reference_fields($content_type_name) {
|
||||
// cache result
|
||||
static $node_reference_fields = array();
|
||||
|
||||
if (empty($node_reference_fields[$content_type_name])) {
|
||||
$fields = field_info_instances('node', $content_type_name);
|
||||
if (!empty($fields)) {
|
||||
foreach ($fields as $field) {
|
||||
|
||||
if (isset($field['widget']['module']) && $field['widget']['module'] == 'node_reference' && !empty($field['field_name'])) {
|
||||
$node_reference_fields[$content_type_name][$field['field_name']] = $field['field_name'];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists($content_type_name, $node_reference_fields)) {
|
||||
return $node_reference_fields[$content_type_name];
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export relation OG include.
|
||||
*
|
||||
* Helps maintain organic groups relationships between nodes during node export operations.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Callback for OG settings form.
|
||||
*/
|
||||
function node_export_relation_settings_form_og(&$form, &$form_state) {
|
||||
$form['og'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Organic groups'),
|
||||
);
|
||||
$form['og']['node_export_og_auto_inc'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Automatically OG related related nodes in exports'),
|
||||
'#default' => variable_get('node_export_og_auto_inc', TRUE),
|
||||
);
|
||||
$form['og']['node_export_og_skip'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Skip related OG nodes that cannot be exported'),
|
||||
'#default' => variable_get('node_export_og_skip', TRUE),
|
||||
'#description' => t('If this is disabled, node exports will fail if a related OG node cannot be exported, for example if the user performing the export does not have access.'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Go through group nids and put group UUIDs in their place.
|
||||
*/
|
||||
function node_export_relation_og_set_group_uuids(&$nodes) {
|
||||
foreach ($nodes as &$node) {
|
||||
if (!empty($node->og_groups)) {
|
||||
foreach ($node->og_groups as $key => $group_nid) {
|
||||
$group_uuid = uuid_get_uuid('node', 'nid', $group_nid);
|
||||
// Create uuid if it doesn't exists
|
||||
if (empty($group_uuid)) {
|
||||
$group_uuid = uuid_set_uuid('node', 'nid', $group_nid);
|
||||
}
|
||||
|
||||
$node->og_groups[$group_uuid] = $group_uuid;
|
||||
unset($node->og_groups[$key]);
|
||||
// Modify og_groups_both as well (gid => title).
|
||||
$group_title = $node->og_groups_both[$group_nid];
|
||||
$node->og_groups_both[$group_uuid] = $group_title;
|
||||
unset($node->og_groups_both[$group_nid]);
|
||||
}
|
||||
}
|
||||
|
||||
// Support for og_subgroups.
|
||||
if (!empty($node->og_parent)) {
|
||||
$group_uuid = uuid_get_uuid('node', 'nid', $node->og_parent->nid);
|
||||
// Create uuid if it doesn't exists
|
||||
if (empty($group_uuid)) {
|
||||
$group_uuid = uuid_set_uuid('node', 'nid', $node->og_parent->nid);
|
||||
}
|
||||
$node->og_parent = $group_uuid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Go through group UUIDs and put group nids in their place.
|
||||
*/
|
||||
function node_export_relation_og_set_group_nids(&$nodes) {
|
||||
foreach ($nodes as &$node) {
|
||||
if (!empty($node->og_groups)) {
|
||||
foreach ($node->og_groups as $key => $group_uuid) {
|
||||
// If this is really a UUID, find the matching nid.
|
||||
if (uuid_is_valid($group_uuid)) {
|
||||
$group_nids = entity_get_id_by_uuid(array($group_uuid));
|
||||
$group_nid = $group_nids[$group_uuid];
|
||||
$node->og_groups[$group_nid] = $group_nid;
|
||||
unset($node->og_groups[$key]);
|
||||
|
||||
// Modify og_groups_both as well (gid => title).
|
||||
$group_title = $node->og_groups_both[$group_uuid];
|
||||
$node->og_groups_both[$group_nid] = $group_title;
|
||||
unset($node->og_groups_both[$group_uuid]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Support for og_subgroups.
|
||||
if (!empty($node->og_parent) && is_string($node->og_parent)) {
|
||||
// Create uuid if it doesn't exists
|
||||
if (uuid_is_valid($node->og_parent)) {
|
||||
$group_nids = entity_get_id_by_uuid(array($group_uuid));
|
||||
$node->og_parent = $group_nids[$group_uuid];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export relation OG include.
|
||||
*
|
||||
* Helps maintain organic groups relationships between nodes during node export operations.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Add taxonomy term reference UUID.
|
||||
*/
|
||||
function node_export_relation_taxonomy_build_term_reference($node) {
|
||||
$reference_fields = node_export_relation_taxonomy_term_reference_fields($node);
|
||||
// Iterate through the class properties
|
||||
foreach ($reference_fields as $field => $val) {
|
||||
// There may be multiple languages
|
||||
foreach ($val as $lang => $values) {
|
||||
// Multi-value fields
|
||||
foreach ($values as $pos => $value) {
|
||||
$term = taxonomy_term_load($value['tid']);
|
||||
$new_field = $node->$field;
|
||||
$new_field[$lang][$pos]['uuid'] = $term->uuid;
|
||||
$node->$field = $new_field;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the tid based on the term UUID.
|
||||
*/
|
||||
function node_export_relation_taxonomy_restore_term_reference($node) {
|
||||
$reference_fields = node_export_relation_taxonomy_term_reference_fields($node);
|
||||
// Iterate through the class properties
|
||||
foreach ($reference_fields as $field => $val) {
|
||||
// There may be multiple languages
|
||||
foreach ($val as $lang => $values) {
|
||||
// Multi-value fields
|
||||
foreach ($values as $pos => $value) {
|
||||
if (isset($value['uuid'])) {
|
||||
// @TODO load_by_uuid
|
||||
$tid = db_select('taxonomy_term_data', 'ttd')
|
||||
->fields('ttd', array('tid'))
|
||||
->condition('ttd.uuid', $value['uuid'])
|
||||
->execute()
|
||||
->fetchField();
|
||||
if ($tid) {
|
||||
$new_field[$lang][$pos]['tid'] = $tid;
|
||||
$node->$field = $new_field;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the term reference fields for a node.
|
||||
*/
|
||||
function node_export_relation_taxonomy_term_reference_fields($node) {
|
||||
$reference_fields = array();
|
||||
$instances = field_info_instances('node', $node->type);
|
||||
if (!empty($instances)) {
|
||||
foreach ($instances as $instance) {
|
||||
$field = field_info_field($instance['field_name']);
|
||||
if (isset($field['type']) && $field['type'] == 'taxonomy_term_reference') {
|
||||
$field_name = $instance['field_name'];
|
||||
$reference_fields[$field_name] = $node->$field_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $reference_fields;
|
||||
}
|
220
sites/all/modules/node_export/node_export.api.php
Normal file
220
sites/all/modules/node_export/node_export.api.php
Normal file
@@ -0,0 +1,220 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Documents Node export's hooks for api reference.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Override export access on a node.
|
||||
*
|
||||
* Let other modules alter this - for example to only allow some users to
|
||||
* export specific nodes or types.
|
||||
*
|
||||
* @param &$access
|
||||
* Boolean access value for current user.
|
||||
* @param $node
|
||||
* The node to determine access for.
|
||||
*/
|
||||
function hook_node_export_access_export_alter(&$access, $node) {
|
||||
// no example code
|
||||
}
|
||||
|
||||
/**
|
||||
* Override import access on a node.
|
||||
*
|
||||
* Let other modules alter this - for example to only allow some users to
|
||||
* import specific nodes or types.
|
||||
*
|
||||
* @param &$access
|
||||
* Boolean access value for current user.
|
||||
* @param $node
|
||||
* The node to determine access for.
|
||||
*/
|
||||
function hook_node_export_access_import_alter(&$access, $node) {
|
||||
// no example code
|
||||
}
|
||||
|
||||
/**
|
||||
* Override one line of the export code output.
|
||||
*
|
||||
* @param &$out
|
||||
* The line of output.
|
||||
* @param $tab
|
||||
* The $tab variable from node_export_node_encode().
|
||||
* @param $key
|
||||
* The $key variable from node_export_node_encode().
|
||||
* @param $value
|
||||
* The $value variable from node_export_node_encode().
|
||||
* @param $iteration
|
||||
* The $iteration variable from node_export_node_encode().
|
||||
*/
|
||||
function hook_node_export_node_encode_line_alter(&$out, $tab, $key, $value, $iteration) {
|
||||
// Start with something like this, and work on it:
|
||||
$out = $tab . " '" . $key . "' => " . node_export_node_encode($value, $iteration) . ",\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Manipulate a node on export.
|
||||
*
|
||||
* @param &$node
|
||||
* The node to alter.
|
||||
* @param $original_node
|
||||
* The unaltered node.
|
||||
*/
|
||||
function hook_node_export_node_alter(&$node, $original_node) {
|
||||
// no example code
|
||||
}
|
||||
|
||||
/**
|
||||
* Manipulate a node on import.
|
||||
*
|
||||
* @param &$node
|
||||
* The node to alter.
|
||||
* @param $original_node
|
||||
* The unaltered node.
|
||||
* @param $save
|
||||
* Whether the node will be saved by node_export_import().
|
||||
*/
|
||||
function hook_node_export_node_import_alter(&$node, $original_node, $save) {
|
||||
// no example code
|
||||
}
|
||||
|
||||
/**
|
||||
* Manipulate node array before export.
|
||||
*
|
||||
* The purpose of this is to allow a module to check nodes in the array for
|
||||
* two or more nodes that must retain a relationship, and to add/remove other
|
||||
* data to the array to assist with maintaining dependencies, relationships,
|
||||
* references, and additional data required by the nodes.
|
||||
*
|
||||
* @param &$nodes
|
||||
* The array of nodes to alter.
|
||||
* @param $format
|
||||
* The format of node code being used.
|
||||
*/
|
||||
function hook_node_export_alter(&$nodes, $format) {
|
||||
// no example code
|
||||
}
|
||||
|
||||
/**
|
||||
* Manipulate node array before import.
|
||||
*
|
||||
* The purpose of this is to allow a module to check nodes in the array for
|
||||
* two or more nodes that must retain a relationship, and to add/remove other
|
||||
* data to the array to assist with maintaining dependencies, relationships,
|
||||
* references, and additional data required by the nodes.
|
||||
*
|
||||
* @param &$nodes
|
||||
* The array of nodes to alter.
|
||||
* @param $format
|
||||
* The format of node code being used.
|
||||
* @param $save
|
||||
* Whether the nodes will be saved by node_export_import().
|
||||
*/
|
||||
function hook_node_export_import_alter(&$nodes, $format, $save) {
|
||||
// no example code
|
||||
}
|
||||
|
||||
/**
|
||||
* Manipulate node array after import.
|
||||
*
|
||||
* The purpose of this is to allow a module to check nodes in the array for
|
||||
* two or more nodes that must retain a relationship, and to add/remove other
|
||||
* data to the array to assist with maintaining dependencies, relationships,
|
||||
* references, and additional data required by the nodes.
|
||||
*
|
||||
* @param &$nodes
|
||||
* The array of nodes to alter - IMPORTANT: keyed by node id.
|
||||
* @param $format
|
||||
* The format of node code being used.
|
||||
* @param $save
|
||||
* Whether the nodes were saved by node_export_import().
|
||||
*/
|
||||
function hook_node_export_after_import_alter(&$nodes, $format, $save) {
|
||||
// no example code
|
||||
}
|
||||
|
||||
/**
|
||||
* Manipulate the code string before import.
|
||||
*
|
||||
* @param &$code_string
|
||||
* The export code.
|
||||
*/
|
||||
function hook_node_export_decode_alter(&$code_string) {
|
||||
// no example code
|
||||
}
|
||||
|
||||
/**
|
||||
* Manipulate the code string upon export.
|
||||
*
|
||||
* @param &$code_string
|
||||
* The Node export code. Leave as FALSE for no change.
|
||||
* @param $nodes
|
||||
* The node.
|
||||
* @param $format
|
||||
* A string indicating what the export format is, and whether to do anything.
|
||||
*/
|
||||
function hook_node_export_encode_alter(&$code_string, $nodes, $format) {
|
||||
// no example code
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a format handler.
|
||||
*
|
||||
* @return
|
||||
* An array keyed by format names containing an array with keys:
|
||||
* #title - the translated display name of the format
|
||||
* #module - the module that implements it.
|
||||
* #description - the translated description, please include links to docs that
|
||||
* give more info about the format.
|
||||
* #file - if a file is to be included for callbacks to work, give full path
|
||||
* here. This is optional.
|
||||
* #mime - to override the default text/plain mime type for the downloaded
|
||||
* file set this to the desired mime type string. This is optional.
|
||||
* #settings_callback - the function name of the settings callback, this is a
|
||||
* function that takes two params $form and $form_state, and returns an
|
||||
* array of form elements to append to the $form['basic'] area. The form
|
||||
* uses system_settings_form() so values will be automatically saved into
|
||||
* variables, but be sure your module deletes these variables upon
|
||||
* uninstall. This is optional.
|
||||
* #export_callback - the function name of the export callback, this is a
|
||||
* function that takes two params $nodes and $format, where $nodes is an array
|
||||
* of nodes and $format is the name of the format (in case same function used
|
||||
* for multiple formats).
|
||||
* #import_callback - the function name of the import callback, this is a
|
||||
* function that takes one parameter $code_string, and will be called of all
|
||||
* formats when an import is being performed, and should return:
|
||||
* The array of nodes, or nothing if code_string not handled by this
|
||||
* function.
|
||||
* If there is a problem with the supplied code return an array like so:
|
||||
* array(
|
||||
* 'success' => FALSE,
|
||||
* 'output' => array("error msg 1", "error msg 2", etc...),
|
||||
* )
|
||||
* Note: Do not use the t() function on error msgs, and don't mix the error
|
||||
* message with dynamic variables/content, at least not in the first message
|
||||
* so it can be translated properly and used as the main message. See the
|
||||
* XML implementation for malformed XML imports for an example that combines
|
||||
* information for the user followed by generated errors from PHP.
|
||||
*/
|
||||
function hook_node_export_format_handlers() {
|
||||
return array(
|
||||
// Note: format_short_name should NOT contain the string 'node_export'.
|
||||
// Example from DSV format.
|
||||
'dsv' => array(
|
||||
'#title' => t('DSV'),
|
||||
'#module' => 'node_export',
|
||||
'#file' => drupal_get_path('module', 'node_export') . '/formats/dsv.inc',
|
||||
'#description' => t(
|
||||
'Configurable <a href="!dsv">Delimiter-separated values</a> code. Export and import sites must be configured the same.',
|
||||
array(
|
||||
'!dsv' => 'http://en.wikipedia.org/wiki/Delimiter-separated_values'
|
||||
)
|
||||
),
|
||||
'#settings_callback' => 'node_export_dsv_settings',
|
||||
'#export_callback' => 'node_export_dsv_export',
|
||||
'#import_callback' => 'node_export_dsv_import',
|
||||
),
|
||||
);
|
||||
}
|
297
sites/all/modules/node_export/node_export.drush.inc
Normal file
297
sites/all/modules/node_export/node_export.drush.inc
Normal file
@@ -0,0 +1,297 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Drush support for node_export.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_drush_command().
|
||||
*/
|
||||
function node_export_drush_command() {
|
||||
$items = array();
|
||||
|
||||
$items['node-export-export'] = array(
|
||||
'callback' => 'drupal_node_export_callback_export',
|
||||
'description' => "Export nodes using Node export.",
|
||||
'arguments' => array(
|
||||
'nids' => "A list of space-separated node IDs to export.",
|
||||
),
|
||||
'options' => array(
|
||||
'file' => "The filename of the output file. If supplied, the node code will be exported to that file, otherwise it will export to stdout.",
|
||||
'format' => "If supplied, node code will be output using a particular export format, if available. (e.g. serialize)",
|
||||
'status' => "Filter for 'status'; A boolean value (0 or 1) indicating whether the node is published (visible to non-administrators).",
|
||||
'promote' => "Filter for 'promote'; A boolean value (0 or 1) indicating whether the node should be displayed on the front page.",
|
||||
'sticky' => "Filter for 'sticky'; A boolean value (0 or 1) indicating whether the node should be displayed at the top of lists in which it appears.",
|
||||
'translate' => "Filter for 'translate'; A boolean value (0 or 1) indicating whether the node translation needs to be updated.",
|
||||
'language' => "Filter for 'language'; The language code (e.g. de or en-US) of this node.",
|
||||
'type' => "Filter for 'type'; The machine-readable name (e.g. story or page) of the type of this node.",
|
||||
'sql' => "Filter by SQL (EXPERIMENTAL); An SQL query string that returns nids (e.g. \"SELECT nid FROM nodes WHERE nid < 10\").",
|
||||
'code' => "Filter by PHP code (EXPERIMENTAL); PHP code that prints or returns, an array or CSV string of nids (e.g. \"custom_get_my_nids();\"). Don't include PHP tags.",
|
||||
),
|
||||
'examples' => array(
|
||||
'drush node-export-export 45 46 47 --file=filename' =>
|
||||
"export nodes with node IDs 45, 46, and 47 to the file with the supplied filename.",
|
||||
'drush node-export-export --type=story,page --file=filename' =>
|
||||
"export nodes of type story and page to the file with the supplied filename.",
|
||||
),
|
||||
);
|
||||
$items['node-export-import'] = array(
|
||||
'callback' => 'drush_node_export_callback_import',
|
||||
'description' => "Import nodes previously exported with Node export.",
|
||||
'options' => array(
|
||||
'uid' => "User ID of user to save nodes as. If not given will use the user with an ID of 1. You may specify 0 for the Anonymous user.",
|
||||
'file' => "The filename of the input file. If supplied, the node code will be imported from that file, otherwise it will import to stdin.",
|
||||
),
|
||||
'examples' => array(
|
||||
'drush node-export-import --file=filename' =>
|
||||
'Import nodes from the file with the given filename.',
|
||||
'drush node-export-import --uid=2 --file=filename' =>
|
||||
"Import nodes from the file with the given filename. The author of the nodes will be set to the user that has the user ID of 2.",
|
||||
),
|
||||
);
|
||||
|
||||
// Add aliases for usability.
|
||||
node_export_drush_command_add_alias($items, 'node-export-export', 'node-export');
|
||||
node_export_drush_command_add_alias($items, 'node-export-export', 'ne-export');
|
||||
node_export_drush_command_add_alias($items, 'node-export-import', 'ne-import');
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* A function to help alias commands as other commands.
|
||||
*/
|
||||
function node_export_drush_command_add_alias(&$items, $command, $alias) {
|
||||
// Create a property on the command for adding aliases, if not there.
|
||||
if (!isset($items[$command]['node_export command aliases'])) {
|
||||
$items[$command]['node_export command aliases'] = array();
|
||||
}
|
||||
// Record the alias into that property.
|
||||
$items[$command]['node_export command aliases'][] = $alias;
|
||||
// Create the alias as a new command.
|
||||
$items[$alias] = $items[$command];
|
||||
// Indicate what this new command is an alias for.
|
||||
$items[$alias]['node_export alias for'] = $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_drush_help().
|
||||
*
|
||||
* This function is called whenever a drush user calls
|
||||
* 'drush help <name-of-your-command>'
|
||||
*
|
||||
* @param
|
||||
* A string with the help section (prepend with 'drush:')
|
||||
*
|
||||
* @return
|
||||
* A string with the help text for your command.
|
||||
*/
|
||||
function node_export_drush_help($section) {
|
||||
// This is to prevent duplication of information from hook_drush_command().
|
||||
$commands = node_export_drush_command();
|
||||
foreach ($commands as $command => $command_info) {
|
||||
if ($section == 'drush:' . $command) {
|
||||
$out = $command_info['description'];
|
||||
if (isset($command_info['node_export alias for'])) {
|
||||
$output .= "\nThis command is an alias for ";
|
||||
$output .= $command_info['node_export alias for'] . ".";
|
||||
}
|
||||
if (isset($command_info['node_export command aliases'])) {
|
||||
if (count($command_info['node_export command aliases']) == 1) {
|
||||
$output .= "\nThis command can be called by it's alias; ";
|
||||
$output .= $command_info['node_export command aliases'] . ".";
|
||||
}
|
||||
else {
|
||||
$last_alias = array_pop($command_info['node_export command aliases']);
|
||||
$output .= "\nThis command can be called by it's aliases; ";
|
||||
$output .= implode(", ", $command_info['node_export command aliases']);
|
||||
$output .= ", or " . $last_alias . ".";
|
||||
}
|
||||
}
|
||||
$out .= "\n\nArguments:";
|
||||
if (isset($command_info['arguments'])) {
|
||||
foreach ($command_info['arguments'] as $k => $v) {
|
||||
$out .= "\n " . $k . " : " . $v;
|
||||
}
|
||||
}
|
||||
$out .= "\n\nOptions:";
|
||||
if (isset($command_info['options'])) {
|
||||
foreach ($command_info['options'] as $k => $v) {
|
||||
$out .= "\n " . $k . " : " . $v;
|
||||
}
|
||||
}
|
||||
$out .= "\n\nExamples:";
|
||||
if (isset($command_info['examples'])) {
|
||||
foreach ($command_info['examples'] as $k => $v) {
|
||||
$out .= "\n \'" . $k . "\' : " . $v;
|
||||
}
|
||||
}
|
||||
return dt($out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Drush command callback.
|
||||
*
|
||||
* export nodes.
|
||||
*/
|
||||
function drupal_node_export_callback_export() {
|
||||
|
||||
// Set up an array of nid_filters.
|
||||
$nid_filters = array();
|
||||
|
||||
// The base nids.
|
||||
$args = array_filter(func_get_args(), 'is_numeric');
|
||||
if ($args) {
|
||||
$nid_filters['base'] = $args;
|
||||
}
|
||||
|
||||
// Filter for values in the node table (except for nids).
|
||||
$filters = array(
|
||||
'status',
|
||||
'promote',
|
||||
'sticky',
|
||||
'translate',
|
||||
'language',
|
||||
'type',
|
||||
);
|
||||
|
||||
$query = db_select('node', 'n')->fields('n', array('nid'));
|
||||
$execute = FALSE;
|
||||
foreach ($filters as $filter) {
|
||||
$filter_option = drush_get_option($filter);
|
||||
if ($filter_option) {
|
||||
$query->condition($filter, explode(',', $filter_option), 'IN');
|
||||
// Only execute if conditions are set.
|
||||
$execute = TRUE;
|
||||
}
|
||||
}
|
||||
if ($execute) {
|
||||
$result = $query->execute();
|
||||
foreach ($result as $row) {
|
||||
$nid_filters['filters'][] = $row->nid;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle SQL option.
|
||||
$sql = drush_get_option('sql');
|
||||
if ($sql) {
|
||||
$result = db_query($sql);
|
||||
foreach ($result as $row) {
|
||||
$nid_filters['sql'][] = $row->nid;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle PHP option.
|
||||
$code = drush_get_option('code');
|
||||
if ($code) {
|
||||
ob_start();
|
||||
print eval("?><?php " . $code . " ?>");
|
||||
$result = ob_get_contents();
|
||||
ob_end_clean();
|
||||
if (is_array($result)) {
|
||||
$nid_filters['code'] = $result;
|
||||
}
|
||||
else {
|
||||
$nid_filters['code'] = explode(
|
||||
",",
|
||||
str_replace(array("\n", "\r", "\t", " "), '', $result)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($nid_filters) > 1) {
|
||||
// Compute the intersect of all $nid_filters if there are more than one.
|
||||
$nids = call_user_func_array('array_intersect', $nid_filters);
|
||||
}
|
||||
elseif (count($nid_filters) == 1) {
|
||||
// Use the only filter if there is only one.
|
||||
$nids = reset($nid_filters);
|
||||
}
|
||||
else {
|
||||
// Is there are no filters at all, do a query to get all nids.
|
||||
$result = db_select('node', 'n')->fields('n', array('nid'))->execute();
|
||||
$nids = array();
|
||||
foreach ($result as $row) {
|
||||
$nids[] = $row->nid;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle format option.
|
||||
$format = drush_get_option('format');
|
||||
|
||||
if (empty($nids)) {
|
||||
drush_set_error('DRUSH_NOT_COMPLETED', "No nodes found.");
|
||||
}
|
||||
|
||||
$result = node_export($nids, $format, 'dt');
|
||||
|
||||
if ($result['success']) {
|
||||
$filename = drush_get_option('file');
|
||||
|
||||
if ($filename) {
|
||||
// Output data to file. Note this only takes a flat filename for the current directory.
|
||||
// If file exists, ask for whether to overwrite.
|
||||
if (file_exists($filename)) {
|
||||
if (!drush_confirm(dt("File $filename exists. Do you really want to overwrite?"))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Write the file.
|
||||
file_put_contents($filename, $result['output']);
|
||||
}
|
||||
else {
|
||||
// stdout.
|
||||
drush_print_r($result['output']);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
// We have received an error message.
|
||||
drush_set_error('DRUSH_NOT_COMPLETED', strip_tags(implode("\n", $result['output'])));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Drush command callback.
|
||||
*
|
||||
* Import nodes from data.
|
||||
*/
|
||||
function drush_node_export_callback_import() {
|
||||
// Switch to site maintenance account or the specified user so imported nodes are not anonymous.
|
||||
$uid = drush_get_option('uid');
|
||||
// Test on NULL so uid may be given as 0.
|
||||
if (is_null($uid)) {
|
||||
$uid = 1;
|
||||
}
|
||||
// User 0 is already loaded.
|
||||
if ($uid != 0) {
|
||||
global $user;
|
||||
$user = user_load($uid);
|
||||
}
|
||||
|
||||
$filename = drush_get_option('file');
|
||||
|
||||
if ($filename) {
|
||||
$node_code = file_get_contents($filename, "r");
|
||||
}
|
||||
else {
|
||||
$node_code = file_get_contents("php://stdin", "r");
|
||||
}
|
||||
|
||||
if (!empty($node_code)) {
|
||||
$result = node_export_import($node_code, 'dt');
|
||||
if (!$result['success']) {
|
||||
// We have received an error message.
|
||||
drush_set_error('DRUSH_NOT_COMPLETED', strip_tags(implode("\n", $result['output'])));
|
||||
}
|
||||
else {
|
||||
drush_print(strip_tags(implode("\n", $result['output'])));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
90
sites/all/modules/node_export/node_export.formats.inc
Normal file
90
sites/all/modules/node_export/node_export.formats.inc
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export formats file.
|
||||
*
|
||||
* Implements the default node export format handlers.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_format_handlers().
|
||||
*/
|
||||
function node_export_node_export_format_handlers() {
|
||||
return array(
|
||||
'json' => array(
|
||||
'#title' => t('JSON'),
|
||||
'#module' => 'node_export',
|
||||
'#file' => drupal_get_path('module', 'node_export') . '/formats/json.inc',
|
||||
'#description' => t(
|
||||
'<a href="!json">JavaScript Object Notation</a> code.',
|
||||
array(
|
||||
'!json' => 'http://en.wikipedia.org/wiki/JSON'
|
||||
)
|
||||
),
|
||||
'#mime' => 'application/json',
|
||||
'#export_callback' => 'node_export_json_export',
|
||||
'#import_callback' => 'node_export_json_import',
|
||||
),
|
||||
|
||||
'drupal' => array(
|
||||
'#title' => t('Drupal var export'),
|
||||
'#module' => 'node_export',
|
||||
'#file' => drupal_get_path('module', 'node_export') . '/formats/drupal.inc',
|
||||
'#description' => t(
|
||||
'<a href="!drupal">Drupal var export</a> code.',
|
||||
array(
|
||||
'!drupal' => 'http://api.drupal.org/api/drupal/includes!utility.inc/function/drupal_var_export/7'
|
||||
)
|
||||
),
|
||||
'#export_callback' => 'node_export_drupal_export',
|
||||
'#import_callback' => 'node_export_drupal_import',
|
||||
),
|
||||
|
||||
'serialize' => array(
|
||||
'#title' => t('Serialize'),
|
||||
'#module' => 'node_export',
|
||||
'#file' => drupal_get_path('module', 'node_export') . '/formats/serialize.inc',
|
||||
'#description' => t(
|
||||
'Very robust, though not human readable, representation through <a href="!wiki">Serialization</a> using the PHP <a href="!php">serialize</a> function.',
|
||||
array(
|
||||
'!wiki' => 'http://tools.ietf.org/html/rfc4180',
|
||||
'!php' => 'http://en.wikipedia.org/wiki/Comma-separated_values'
|
||||
)
|
||||
),
|
||||
'#export_callback' => 'node_export_serialize_export',
|
||||
'#import_callback' => 'node_export_serialize_import',
|
||||
),
|
||||
|
||||
'xml' => array(
|
||||
'#title' => t('XML'),
|
||||
'#module' => 'node_export',
|
||||
'#file' => drupal_get_path('module', 'node_export') . '/formats/xml.inc',
|
||||
'#description' => t(
|
||||
'<a href="!xml">XML 1.0</a> representation which is good for machine-readability and human-readability.',
|
||||
array(
|
||||
'!xml' => 'http://en.wikipedia.org/wiki/XML',
|
||||
)
|
||||
),
|
||||
'#mime' => 'application/xml',
|
||||
'#export_callback' => 'node_export_xml_export',
|
||||
'#import_callback' => 'node_export_xml_import',
|
||||
),
|
||||
|
||||
'dsv' => array(
|
||||
'#title' => t('DSV'),
|
||||
'#module' => 'node_export',
|
||||
'#file' => drupal_get_path('module', 'node_export') . '/formats/dsv.inc',
|
||||
'#description' => t(
|
||||
'Configurable <a href="!dsv">Delimiter-separated values</a> code. Export and import sites must be configured the same.',
|
||||
array(
|
||||
'!dsv' => 'http://en.wikipedia.org/wiki/Delimiter-separated_values'
|
||||
)
|
||||
),
|
||||
'#settings_callback' => 'node_export_dsv_settings',
|
||||
'#export_callback' => 'node_export_dsv_export',
|
||||
'#import_callback' => 'node_export_dsv_import',
|
||||
),
|
||||
|
||||
);
|
||||
}
|
13
sites/all/modules/node_export/node_export.info
Normal file
13
sites/all/modules/node_export/node_export.info
Normal file
@@ -0,0 +1,13 @@
|
||||
name = Node export
|
||||
description = "Allows users to export content and then import into another Drupal installation."
|
||||
dependencies[] = uuid
|
||||
core = 7.x
|
||||
package = "Node export"
|
||||
configure = admin/config/content/node_export
|
||||
files[]=views/views_handler_field_node_link_export.inc
|
||||
; Information added by drupal.org packaging script on 2012-08-20
|
||||
version = "7.x-3.0"
|
||||
core = "7.x"
|
||||
project = "node_export"
|
||||
datestamp = "1345435979"
|
||||
|
135
sites/all/modules/node_export/node_export.install
Normal file
135
sites/all/modules/node_export/node_export.install
Normal file
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export install file.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_uninstall().
|
||||
*/
|
||||
function node_export_uninstall() {
|
||||
variable_del('node_export_format');
|
||||
variable_del('node_export_code');
|
||||
variable_del('node_export_filename');
|
||||
variable_del('node_export_file_list');
|
||||
variable_del('node_export_existing');
|
||||
$types = node_type_get_names();
|
||||
foreach ($types as $type => $name) {
|
||||
variable_del('node_export_reset_status_' . $type);
|
||||
variable_del('node_export_reset_promote_' . $type);
|
||||
variable_del('node_export_reset_sticky_' . $type);
|
||||
variable_del('node_export_reset_author_' . $type);
|
||||
variable_del('node_export_reset_created_' . $type);
|
||||
variable_del('node_export_reset_menu_' . $type);
|
||||
variable_del('node_export_reset_revision_timestamp_' . $type);
|
||||
variable_del('node_export_reset_last_comment_timestamp_' . $type);
|
||||
variable_del('node_export_reset_path_' . $type);
|
||||
variable_del('node_export_reset_book_mlid_' . $type);
|
||||
}
|
||||
// File field functionality.
|
||||
variable_del('node_export_file_types');
|
||||
variable_del('node_export_file_mode');
|
||||
variable_del('node_export_file_assets_path');
|
||||
variable_del('node_export_file_supported_fields');
|
||||
// DSV format.
|
||||
variable_del('node_export_dsv_delimiter');
|
||||
variable_del('node_export_dsv_enclosure');
|
||||
variable_del('node_export_dsv_seperator');
|
||||
variable_del('node_export_dsv_escape_eol');
|
||||
|
||||
// Old vars.
|
||||
variable_del('node_export_reset_' . $type);
|
||||
variable_del('node_export_nodes_without_confirm');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Warn user about changed permissions and configuration.
|
||||
*/
|
||||
function node_export_update_7300() {
|
||||
drupal_set_message(
|
||||
t(
|
||||
"Node export <a href=\"!perms\">permissions</a> and <a href=\"!config\">configuration</a> "
|
||||
. "have changed, please take this opportunity to review these options to "
|
||||
. "ensure the correct behavior and security of the module. The import "
|
||||
. "form is now located under <a href=\"!add\">Create content</a>.",
|
||||
array(
|
||||
'!perms' => url('admin/people/permissions'),
|
||||
'!config' => url('admin/settings/node_export'),
|
||||
'!add' => url('node/add'),
|
||||
)
|
||||
),
|
||||
'warning'
|
||||
);
|
||||
drupal_set_message(
|
||||
t(
|
||||
"Node export no longer checks whether users have access to use the "
|
||||
. "filter formats of the fields in the node. Please keep this in mind "
|
||||
. "when deciding which user roles will get the 'export nodes' "
|
||||
. "permission."
|
||||
),
|
||||
'warning'
|
||||
);
|
||||
return 'Note: Please update Node export permissions and configuration.';
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine Node export file module directly into Node export.
|
||||
*/
|
||||
function node_export_update_7301() {
|
||||
// Upgraders with node_export_file should have the module disabled.
|
||||
if (module_exists('node_export_file')) {
|
||||
drupal_set_message('<em>Node export file</em> is deprecated. Please delete the ' . drupal_get_path('module', 'node_export_file') . ' directory from the Drupal installation.', 'warning');
|
||||
module_disable(array('node_export_file'), FALSE);
|
||||
}
|
||||
return 'Node export file removed, functionality moved to Node export.';
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove old variables.
|
||||
*/
|
||||
function node_export_update_7302() {
|
||||
// Old variables.
|
||||
variable_del('node_export_method');
|
||||
variable_del('node_export_bulk_code');
|
||||
variable_del('node_export_bulk_filename');
|
||||
variable_del('node_export_omitted');
|
||||
return 'Removed old variables.';
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine Node export format modules directly into Node export.
|
||||
*/
|
||||
function node_export_update_7303() {
|
||||
// Upgraders with format modules should have the modules disabled.
|
||||
if (module_exists('node_export_node_code')) {
|
||||
drupal_set_message('<em>Node export node code</em> is deprecated. Please delete the ' . drupal_get_path('module', 'node_export_node_code') . ' directory from the Drupal installation.', 'warning');
|
||||
module_disable(array('node_export_node_code'), FALSE);
|
||||
}
|
||||
if (module_exists('node_export_drupal')) {
|
||||
drupal_set_message('<em>Node export drupal</em> is deprecated. Please delete the ' . drupal_get_path('module', 'node_export_drupal') . ' directory from the Drupal installation.', 'warning');
|
||||
module_disable(array('node_export_drupal'), FALSE);
|
||||
}
|
||||
if (module_exists('node_export_dsv')) {
|
||||
drupal_set_message('<em>Node export DSV</em> is deprecated. Please delete the ' . drupal_get_path('module', 'node_export_dsv') . ' directory from the Drupal installation.', 'warning');
|
||||
module_disable(array('node_export_dsv'), FALSE);
|
||||
}
|
||||
if (module_exists('node_export_csv')) {
|
||||
drupal_set_message('<em>Node export CSV</em> is deprecated. Please delete the ' . drupal_get_path('module', 'node_export_csv') . ' directory from the Drupal installation.', 'warning');
|
||||
module_disable(array('node_export_csv'), FALSE);
|
||||
}
|
||||
if (module_exists('node_export_json')) {
|
||||
drupal_set_message('<em>Node export JSON</em> is deprecated. Please delete the ' . drupal_get_path('module', 'node_export_json') . ' directory from the Drupal installation.', 'warning');
|
||||
module_disable(array('node_export_json'), FALSE);
|
||||
}
|
||||
if (module_exists('node_export_serialize')) {
|
||||
drupal_set_message('<em>Node export serialize</em> is deprecated. Please delete the ' . drupal_get_path('module', 'node_export_serialize') . ' directory from the Drupal installation.', 'warning');
|
||||
module_disable(array('node_export_serialize'), FALSE);
|
||||
}
|
||||
if (module_exists('node_export_xml')) {
|
||||
drupal_set_message('<em>Node export XML</em> is deprecated. Please delete the ' . drupal_get_path('module', 'node_export_xml') . ' directory from the Drupal installation.', 'warning');
|
||||
module_disable(array('node_export_xml'), FALSE);
|
||||
}
|
||||
return 'Node export format modules removed, functionality moved to Node export.';
|
||||
}
|
1294
sites/all/modules/node_export/node_export.module
Normal file
1294
sites/all/modules/node_export/node_export.module
Normal file
File diff suppressed because it is too large
Load Diff
580
sites/all/modules/node_export/node_export.pages.inc
Normal file
580
sites/all/modules/node_export/node_export.pages.inc
Normal file
@@ -0,0 +1,580 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export pages file.
|
||||
*
|
||||
* Functions for page/form interfaces.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles the bits of the form that are specific to the token module.
|
||||
*/
|
||||
function node_export_settings_token_bits(&$form, $key) {
|
||||
if (module_exists('token')) {
|
||||
$form[$key . '_token_help'] = array(
|
||||
'#title' => t('Replacement patterns'),
|
||||
'#type' => 'fieldset',
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => TRUE,
|
||||
);
|
||||
$form[$key . '_token_help']['help'] = array(
|
||||
'#theme' => 'token_tree',
|
||||
'#token_types' => array('node_export_filename'),
|
||||
);
|
||||
}
|
||||
else {
|
||||
$form[$key]['#description'] = t(
|
||||
'Get the <a href="@token">token</a> module for more options.',
|
||||
array('@token' => url('http://www.drupal.org/project/token'))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Menu callback to configure module settings.
|
||||
*/
|
||||
function node_export_settings($form, &$form_state) {
|
||||
$types = node_type_get_names();
|
||||
|
||||
menu_rebuild();
|
||||
|
||||
$form['basic'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('General settings'),
|
||||
);
|
||||
|
||||
$format_handlers = node_export_format_handlers();
|
||||
$format_options = array();
|
||||
foreach ($format_handlers as $format_handler => $format) {
|
||||
$display = $format['#title'];
|
||||
if (!empty($format['#description'])) {
|
||||
$display .= '<div><small>';
|
||||
$display .= $format['#description'];
|
||||
$display .= '</small></div>';
|
||||
}
|
||||
$format_options[$format_handler] = $display;
|
||||
|
||||
$format_settings = array();
|
||||
if (!empty($format['#settings_callback'])) {
|
||||
if (!empty($format['#file']) && is_file($format['#file'])) {
|
||||
require_once $format['#file'];
|
||||
}
|
||||
$format_form = call_user_func($format['#settings_callback'], $form, $form_state);
|
||||
$format_settings = $format_settings + $format_form;
|
||||
}
|
||||
|
||||
}
|
||||
$selected_formats = variable_get('node_export_format', array('drupal'));
|
||||
if (!count(array_filter($selected_formats))) {
|
||||
$selected_formats = array('drupal');
|
||||
}
|
||||
if (count($format_options) > 1) {
|
||||
$form['basic']['node_export_format'] = array(
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => t('Format to use when exporting a node'),
|
||||
'#default_value' => $selected_formats,
|
||||
'#options' => $format_options,
|
||||
'#description' => t("If you select multiple formats, they will all be available to the user. If you select none, or the format handler is not found, it will use the default 'Drupal var export'. This does not affect imports, the required import format will be used automatically."),
|
||||
);
|
||||
}
|
||||
else {
|
||||
$format = key($format_options);
|
||||
$form['basic']['node_export_format'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => array($format => $format),
|
||||
);
|
||||
}
|
||||
|
||||
$form['basic'][] = $format_settings;
|
||||
|
||||
$form['basic']['node_export_code'] = array(
|
||||
'#type' => 'radios',
|
||||
'#title' => t('Node export code delivery'),
|
||||
'#options' => array(
|
||||
'all' => t('All of the below options on a page'),
|
||||
'copy' => t('Textarea filled with export code'),
|
||||
'file' => t('Text file download'),
|
||||
),
|
||||
'#default_value' => variable_get('node_export_code', 'all'),
|
||||
);
|
||||
|
||||
$form['basic']['filename'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Filename settings'),
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => TRUE,
|
||||
);
|
||||
|
||||
$form['basic']['filename']['node_export_filename'] = array(
|
||||
'#type' => 'textarea',
|
||||
'#title' => t('Filename pattern'),
|
||||
'#default_value' => variable_get('node_export_filename', 'node-export[node_export_filename:nid-list]([node_export_filename:node-count]-nodes).[node_export_filename:timestamp].[node_export_filename:format]'),
|
||||
'#rows' => 1,
|
||||
'#wysiwyg' => FALSE,
|
||||
);
|
||||
node_export_settings_token_bits($form['basic']['filename'], 'node_export_filename');
|
||||
|
||||
$form['basic']['filename']['node_export_file_list'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Node ID list max'),
|
||||
'#default_value' => variable_get('node_export_file_list', 10),
|
||||
'#size' => 6,
|
||||
'#maxlength' => 30,
|
||||
'#description' => t('If there are more than this many nodes, the [node_export_filename:nid-list] token for the filename will not be built. This is to prevent very long filenames.'),
|
||||
);
|
||||
|
||||
$form['basic']['node_export_existing'] = array(
|
||||
'#type' => 'radios',
|
||||
'#title' => t('When importing a node that already exists'),
|
||||
'#options' => array(
|
||||
'new' => t('Create a new node'),
|
||||
'revision' => t('Create a new revision of the existing node'),
|
||||
'skip' => t('Skip the node'),
|
||||
),
|
||||
'#description' => t('UUIDs are used to uniquely identify nodes.'),
|
||||
'#default_value' => variable_get('node_export_existing', 'new'),
|
||||
);
|
||||
|
||||
$form['publishing'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Reset values on import'),
|
||||
);
|
||||
|
||||
foreach ($types as $type => $name) {
|
||||
$form['publishing'][$type] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => $name,
|
||||
'#description' => t('Reset these values when importing nodes of type @s.', array('@s' => $name)),
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => TRUE,
|
||||
);
|
||||
$form['publishing'][$type]['node_export_reset_status_' . $type] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Published'),
|
||||
'#default_value' => variable_get('node_export_reset_status_' . $type, FALSE),
|
||||
'#description' => t('Set to unpublished'),
|
||||
);
|
||||
$form['publishing'][$type]['node_export_reset_promote_' . $type] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Promoted to front page'),
|
||||
'#default_value' => variable_get('node_export_reset_promote_' . $type, FALSE),
|
||||
'#description' => t('Set to not promoted'),
|
||||
);
|
||||
$form['publishing'][$type]['node_export_reset_sticky_' . $type] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Sticky at top of lists'),
|
||||
'#default_value' => variable_get('node_export_reset_sticky_' . $type, FALSE),
|
||||
'#description' => t('Set to not sticky'),
|
||||
);
|
||||
$form['publishing'][$type]['node_export_reset_author_' . $type] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Author (will set to user performing the import)'),
|
||||
'#default_value' => variable_get('node_export_reset_author_' . $type, TRUE),
|
||||
'#description' => t('Recommended since User IDs could be different on import site and the wrong user may gain permission to edit the node.'),
|
||||
);
|
||||
$form['publishing'][$type]['node_export_reset_created_' . $type] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Created time (<em>Authored on</em> date/time)'),
|
||||
'#default_value' => variable_get('node_export_reset_created_' . $type, TRUE),
|
||||
);
|
||||
$form['publishing'][$type]['node_export_reset_changed_' . $type] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Changed time (<em>Last updated</em> date/time)'),
|
||||
'#default_value' => variable_get('node_export_reset_changed_' . $type, TRUE),
|
||||
);
|
||||
$form['publishing'][$type]['node_export_reset_revision_timestamp_'. $type] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Revision changed time'),
|
||||
'#default_value' => variable_get('node_export_reset_revision_timestamp_'. $type, TRUE),
|
||||
);
|
||||
$form['publishing'][$type]['node_export_reset_last_comment_timestamp_'. $type] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Last comment time (date/time the last comment was made)'),
|
||||
'#default_value' => variable_get('node_export_reset_last_comment_timestamp_'. $type, TRUE),
|
||||
);
|
||||
$form['publishing'][$type]['node_export_reset_menu_' . $type] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Menu link'),
|
||||
'#default_value' => variable_get('node_export_reset_menu_' . $type, TRUE),
|
||||
);
|
||||
$form['publishing'][$type]['node_export_reset_path_' . $type] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('URL path'),
|
||||
'#default_value' => variable_get('node_export_reset_path_' . $type, TRUE),
|
||||
);
|
||||
$form['publishing'][$type]['node_export_reset_book_mlid_' . $type] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Book menu link'),
|
||||
'#default_value' => variable_get('node_export_reset_book_mlid_' . $type, TRUE),
|
||||
'#description' => t('Prevents Book node imports causing errors.'),
|
||||
);
|
||||
}
|
||||
|
||||
$form['file'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('File fields'),
|
||||
);
|
||||
|
||||
$types = node_type_get_names();
|
||||
$form['file']['node_export_file_types'] = array(
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => t('Files exported for content types'),
|
||||
'#default_value' => variable_get('node_export_file_types', array()),
|
||||
'#options' => $types,
|
||||
'#description' => t('Which content types should export file fields?'),
|
||||
);
|
||||
|
||||
$textarea_delivery = $form['basic']['node_export_code']['#default_value'];
|
||||
|
||||
$mode_message_display = ($textarea_delivery != 'file');
|
||||
|
||||
$form['file']['node_export_file_mode'] = array(
|
||||
'#type' => 'radios',
|
||||
'#title' => t('File export mode'),
|
||||
'#default_value' => variable_get('node_export_file_mode', 'inline'),
|
||||
'#options' => array(
|
||||
'inline' => t('Inline Base64'),
|
||||
'local' => t('Local file export'),
|
||||
'remote' => t('Remote file export, URL')
|
||||
),
|
||||
'#description' => t('Should file exports be inline inside the export code, a local path to the file, or a URL? Inline Base64 is the easiest option to use but can sometimes exceed PHP post limits, local and remote modes are more useful for power users. <em>NOTE: Remote mode only works with a public files directory.</em>'),
|
||||
);
|
||||
|
||||
$form['file']['node_export_file_assets_path'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Local file field assets path'),
|
||||
'#size' => 60,
|
||||
'#maxlength' => 255,
|
||||
'#default_value' => variable_get('node_export_file_assets_path', ''),
|
||||
'#description' => t(
|
||||
'Optionally, copy files to this path when the node is exported.
|
||||
The primary advantage of this is to divert exported files into a
|
||||
safe location so they can be committed to source control (eg: SVN,
|
||||
CVS, Git). <em>Tip: For install profile developers, setting this
|
||||
path to <code>profiles/my_profile/node_export_assets</code> may be
|
||||
useful.</em>'
|
||||
),
|
||||
'#required' => FALSE,
|
||||
'#states' => array(
|
||||
'visible' => array(
|
||||
':input[name=node_export_file_mode]' => array('value' => 'local'),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$form['file']['node_export_file_supported_fields'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Supported file field types'),
|
||||
'#default_value' => variable_get('node_export_file_supported_fields', 'file, image'),
|
||||
'#maxlength' => 512,
|
||||
'#description' => t('Comma seperated list of file field types to detect for export/import.'),
|
||||
);
|
||||
|
||||
return system_settings_form($form);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export GUI function.
|
||||
*
|
||||
* @param $nodes
|
||||
* A node, an array of nodes, or an array of nids.
|
||||
* @param $format
|
||||
* The node export format.
|
||||
* @param $delivery
|
||||
* The code delivery format, if NULL will use settings.
|
||||
* @return
|
||||
* The node export form or nothing if calling function to serve file.
|
||||
*/
|
||||
function node_export_gui($nodes = NULL, $format = NULL, $delivery = NULL) {
|
||||
// Get the $code_string.
|
||||
if ($nodes) {
|
||||
// $nodes passed in, get the code_string.
|
||||
$result = node_export($nodes, $format);
|
||||
if ($result['success']) {
|
||||
$code_string = $result['output'];
|
||||
}
|
||||
else {
|
||||
foreach ($result['output'] as $output) {
|
||||
drupal_set_message($output, 'error');
|
||||
}
|
||||
return;
|
||||
}
|
||||
$nids = node_export_nodes_to_nids($nodes);
|
||||
$format = $result['format'];
|
||||
}
|
||||
elseif (!empty($_SESSION['node_export'])) {
|
||||
// Nids and code string supplied from session.
|
||||
$session_data = array_shift($_SESSION['node_export']);
|
||||
$code_string = $session_data['code_string'];
|
||||
$nids = $session_data['nids'];
|
||||
$format = $session_data['format'];
|
||||
}
|
||||
|
||||
$delivery = $delivery ? $delivery : variable_get('node_export_code', 'all');
|
||||
if ($delivery != 'file') {
|
||||
if (is_object($nodes)) {
|
||||
// Single node, output straight away.
|
||||
drupal_set_title(t('Node export of !title', array('!title' => $nodes->title)));
|
||||
return drupal_get_form('node_export_form', $nids, $code_string, $format);
|
||||
}
|
||||
elseif ($nodes) {
|
||||
// Node operation, add to session and redirect.
|
||||
$_SESSION['node_export'][] = array(
|
||||
'code_string' => $code_string,
|
||||
'nids' => $nids,
|
||||
'format' => $format,
|
||||
);
|
||||
drupal_goto('admin/content/node_export');
|
||||
}
|
||||
elseif (!$nodes) {
|
||||
// No $nodes passed, but $code_string came from session.
|
||||
return drupal_get_form('node_export_form', $nids, $code_string, $format);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Get file.
|
||||
node_export_get_file($nids, $code_string, $format);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a node, nodes, or nids into an array of nids.
|
||||
*/
|
||||
function node_export_nodes_to_nids($nodes) {
|
||||
if (is_object($nodes)) {
|
||||
$nids = array($nodes->nid);
|
||||
}
|
||||
else {
|
||||
$nids = array();
|
||||
foreach ($nodes as $node) {
|
||||
if (is_object($node)) {
|
||||
$nids[] = $node->nid;
|
||||
}
|
||||
elseif (is_numeric($node)) {
|
||||
$nids[] = $node;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $nids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export form.
|
||||
*
|
||||
* @param $form
|
||||
* The form array.
|
||||
* @param $form_state
|
||||
* The form state.
|
||||
* @param $nids
|
||||
* An array of node ids that are being exported.
|
||||
* @param $code_string
|
||||
* The Node export code.
|
||||
* @param $format
|
||||
* The Node export format.
|
||||
*
|
||||
* @return
|
||||
* The built form array.
|
||||
*/
|
||||
function node_export_form($form, &$form_state, $nids, $code_string, $format) {
|
||||
$form = array();
|
||||
if (variable_get('node_export_code', 'all') == 'all') {
|
||||
$form['nids'] = array(
|
||||
'#type' => 'hidden',
|
||||
'#value' => $nids,
|
||||
);
|
||||
$form['format'] = array(
|
||||
'#type' => 'hidden',
|
||||
'#value' => $format,
|
||||
);
|
||||
$form['download_file'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Download file'),
|
||||
);
|
||||
}
|
||||
$form['export'] = array(
|
||||
'#type' => 'textarea',
|
||||
'#title' => t('Node export code'),
|
||||
'#default_value' => $code_string,
|
||||
'#rows' => 30,
|
||||
'#description' => t('Copy this code and then on the site you want to import to, go to the <em>Node export: import</em> link under <em>Add content</em>, and paste it in there.'),
|
||||
'#attributes' => array(
|
||||
'wrap' => 'off',
|
||||
),
|
||||
'#wysiwyg' => FALSE,
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export form submit function.
|
||||
*
|
||||
* File download was requested.
|
||||
*/
|
||||
function node_export_form_submit($form, &$form_state) {
|
||||
// Get file.
|
||||
$nids = $form_state['values']['nids'];
|
||||
$code_string = $form_state['values']['export'];
|
||||
$format = $form_state['values']['format'];
|
||||
node_export_get_file($nids, $code_string, $format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate text file.
|
||||
*
|
||||
* @param $nids
|
||||
* An array of node ids.
|
||||
* @param $code_string
|
||||
* The text output.
|
||||
* @param $format
|
||||
* The format used.
|
||||
*/
|
||||
function node_export_get_file($nids, $code_string, $format = NULL) {
|
||||
$filename_data = array();
|
||||
$filename_data['node-count'] = count($nids);
|
||||
$filename_data['timestamp'] = REQUEST_TIME;
|
||||
$filename_data['format'] = $format ? $format : 'export';
|
||||
|
||||
// Add a list of nids
|
||||
if (count($nids) <= variable_get('node_export_file_list', 10)) {
|
||||
$filename_data['nid-list'] = '[' . implode(',', $nids) . ']';
|
||||
}
|
||||
$name = variable_get('node_export_filename', 'node-export[node_export_filename:nid-list]([node_export_filename:node-count]-nodes).[node_export_filename:timestamp].[node_export_filename:format]');
|
||||
$data = array('node_export_filename' => (object)$filename_data);
|
||||
$name = token_replace($name, $data);
|
||||
|
||||
$formats = node_export_format_handlers();
|
||||
$format_data = $formats[$format];
|
||||
$mime = !empty($format_data['#mime']) ? $format_data['#mime'] : 'text/plain';
|
||||
|
||||
header('Content-type: ' . $mime);
|
||||
header('Content-Disposition: attachment; filename="' . $name . '"');
|
||||
print($code_string);
|
||||
// Clean exit.
|
||||
module_invoke_all('exit');
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Import Form.
|
||||
*
|
||||
* @param $form
|
||||
* The form array.
|
||||
* @param $form_state
|
||||
* The form state.
|
||||
*
|
||||
* @return
|
||||
* The built form array.
|
||||
*/
|
||||
function node_export_import_form($form, &$form_state) {
|
||||
|
||||
// Initialise to prevent notices
|
||||
$values = array(
|
||||
'file' => FALSE,
|
||||
'code' => FALSE,
|
||||
);
|
||||
|
||||
$form = array();
|
||||
$form['#attributes'] = array(
|
||||
'enctype' => "multipart/form-data",
|
||||
);
|
||||
$form['#prefix'] = "<p>";
|
||||
$form['#prefix'] .= t('You may import content by pasting or uploading the code exported from Node export.') . " ";
|
||||
$form['#prefix'] .= t("Some values may be reset during imports depending on Node export's configuration.");
|
||||
$form['#prefix'] .= "</p>";
|
||||
|
||||
$form['upload'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Upload file'),
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => !$values['file'],
|
||||
);
|
||||
$form['upload']['file'] = array(
|
||||
'#type' => 'file',
|
||||
'#description' => t('To clear this field, <a href="!reset">reset the form</a>.', array('!reset' => url($_GET['q'])))
|
||||
);
|
||||
$form['paste'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Paste code'),
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => !$values['code'],
|
||||
);
|
||||
$form['paste']['code'] = array(
|
||||
'#type' => 'textarea',
|
||||
'#default_value' => '',
|
||||
'#rows' => 30,
|
||||
'#description' => t('Paste the code of a node export here.'),
|
||||
'#wysiwyg' => FALSE,
|
||||
);
|
||||
|
||||
$form['actions'] = array('#type' => 'actions');
|
||||
$form['actions']['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Import'),
|
||||
);
|
||||
$form['actions']['reset'] = array(
|
||||
'#markup' => l(t('Reset the form'), $_GET['q']),
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate function for import form.
|
||||
*/
|
||||
function node_export_import_form_validate($form, &$form_state) {
|
||||
if (
|
||||
$form_state['clicked_button']['#id'] == 'edit-submit' &&
|
||||
!$_FILES['files']['name']['file'] &&
|
||||
!$form_state['values']['code']
|
||||
) {
|
||||
drupal_set_message(t('Please upload a file or paste code to import.'), 'error');
|
||||
form_set_error('', NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit function for import form.
|
||||
*
|
||||
* @todo: is there a way to get the contents of the file without using
|
||||
* file_save_upload()?
|
||||
*/
|
||||
function node_export_import_form_submit($form, &$form_state) {
|
||||
if ($_FILES['files']['name']['file']) {
|
||||
$original = $_FILES['files']['name']['file'];
|
||||
$save = file_save_upload('file', array('file_validate_extensions' => array()));
|
||||
if (!$save) {
|
||||
drupal_set_message(t('Error: Node export could not save file.'), 'error');
|
||||
}
|
||||
else {
|
||||
$save->original = $original;
|
||||
form_set_value($form['upload']['file'], serialize($save), $form_state);
|
||||
}
|
||||
}
|
||||
|
||||
if ($form_state['values']['file']) {
|
||||
$file = unserialize($form_state['values']['file']);
|
||||
if (file_exists($file->uri)) {
|
||||
$code_string = file_get_contents($file->uri);
|
||||
unlink($file->uri);
|
||||
}
|
||||
file_delete($file);
|
||||
}
|
||||
elseif ($form_state['values']['code']) {
|
||||
$code_string = trim($form_state['values']['code']);
|
||||
}
|
||||
|
||||
if (isset($code_string)) {
|
||||
$result = node_export_import($code_string);
|
||||
// Output the status or error messages.
|
||||
foreach ($result['output'] as $output) {
|
||||
drupal_set_message($output, ($result['success'] ? 'status' : 'error'));
|
||||
}
|
||||
// We need to send this user somewhere, and we know they have permission
|
||||
// for this page:
|
||||
drupal_goto('node/add/node_export');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
75
sites/all/modules/node_export/node_export.tokens.inc
Normal file
75
sites/all/modules/node_export/node_export.tokens.inc
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export tokens file.
|
||||
*
|
||||
* Token group file.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_tokens().
|
||||
*/
|
||||
function node_export_tokens($type, $tokens, $data = array(), $options = array()) {
|
||||
$replacements = array();
|
||||
if ($type == 'node_export_filename' && !empty($data['node_export_filename'])) {
|
||||
$object = (array)$data['node_export_filename'];
|
||||
|
||||
foreach ($tokens as $name => $original) {
|
||||
switch ($name) {
|
||||
// Simple key values on the node.
|
||||
case 'nid-list':
|
||||
$replacements[$original] = $object['nid-list'];
|
||||
break;
|
||||
|
||||
case 'node-count':
|
||||
$replacements[$original] = $object['node-count'];
|
||||
break;
|
||||
|
||||
case 'timestamp':
|
||||
$replacements[$original] = $object['timestamp'];
|
||||
break;
|
||||
|
||||
case 'format':
|
||||
$replacements[$original] = $object['format'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $replacements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_token_info().
|
||||
*/
|
||||
function node_export_token_info() {
|
||||
return array(
|
||||
'types' => array(
|
||||
'node_export_filename' => array(
|
||||
'name' => t('Node export filename'),
|
||||
'description' => t('Tokens related to the Node export filename.'),
|
||||
'needs-data' => 'node_export_filename',
|
||||
),
|
||||
),
|
||||
'tokens' => array(
|
||||
'node_export_filename' => array(
|
||||
'nid-list' => array(
|
||||
'name' => t("Node ID list"),
|
||||
'description' => t("Comma seperated list of Node IDs in square brackets (if available)."),
|
||||
),
|
||||
'node-count' => array(
|
||||
'name' => t("Node count"),
|
||||
'description' => t("The number of nodes exported."),
|
||||
),
|
||||
'timestamp' => array(
|
||||
'name' => t("Timestamp"),
|
||||
'description' => t("The timestamp when the file was generated."),
|
||||
),
|
||||
'format' => array(
|
||||
'name' => t("Format"),
|
||||
'description' => t("The format used to export."),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
36
sites/all/modules/node_export/views/node_export.views.inc
Normal file
36
sites/all/modules/node_export/views/node_export.views.inc
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export views include.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of hook_views_handlers().
|
||||
*/
|
||||
function node_export_views_handlers() {
|
||||
return array(
|
||||
'info' => array(
|
||||
'path' => drupal_get_path('module', 'node_export') . '/views',
|
||||
),
|
||||
'handlers' => array(
|
||||
'views_handler_field_node_link_export' => array(
|
||||
'parent' => 'views_handler_field_node_link',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_views_data_alter().
|
||||
*/
|
||||
function node_export_views_data_alter(&$views_data) {
|
||||
$views_data['node']['export_node'] = array(
|
||||
'field' => array(
|
||||
'title' => t('Node export link'),
|
||||
'help' => t('Provide a link to export the node with Node export.'),
|
||||
'handler' => 'views_handler_field_node_link_export',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export views field handler.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Field handler to present a export node link.
|
||||
*
|
||||
* Closely modeled after views/modules/node/views_handler_field_node_link_edit.inc
|
||||
*/
|
||||
class views_handler_field_node_link_export extends views_handler_field_node_link {
|
||||
function construct() {
|
||||
parent::construct();
|
||||
$this->additional_fields['uid'] = 'uid';
|
||||
$this->additional_fields['type'] = 'type';
|
||||
$this->additional_fields['format'] = array('table' => 'node_revisions', 'field' => 'format');
|
||||
}
|
||||
|
||||
function render($values) {
|
||||
// Insure that user has access to export this node.
|
||||
$node = new stdClass();
|
||||
$node->nid = $values->{$this->aliases['nid']};
|
||||
$node->uid = $values->{$this->aliases['uid']};
|
||||
$node->type = $values->{$this->aliases['type']};
|
||||
$node->format = $values->{$this->aliases['format']};
|
||||
if (!node_export_access_check($node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$text = !empty($this->options['text']) ? $this->options['text'] : t('Node export');
|
||||
return l($text, "node/$node->nid/node_export", array('query' => drupal_get_destination()));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user