first import

This commit is contained in:
Bachir Soussi Chiadmi
2015-04-08 11:40:19 +02:00
commit 1bc61b12ad
8435 changed files with 1582817 additions and 0 deletions

View File

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

View File

@@ -0,0 +1,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.

View 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');
}

View 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');
}

View 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');
}

View 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');
}

View 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');
}

View File

@@ -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.
}
}

View File

@@ -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;
}

View File

@@ -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"

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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"

View File

@@ -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);
}
}
}
}

View File

@@ -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;
}
}

View File

@@ -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))));
}
}

View File

@@ -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"

View File

@@ -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();
}
}

View File

@@ -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"

View File

@@ -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;
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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];
}
}
}
}

View File

@@ -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;
}

View 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',
),
);
}

View 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'])));
}
}
}

View 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',
),
);
}

View 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"

View 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.';
}

File diff suppressed because it is too large Load Diff

View 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');
}
}

View 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."),
),
),
),
);
}

View 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',
),
);
}

View File

@@ -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()));
}
}