FINAL suepr merge step : added all modules to this super repos
This commit is contained in:
339
sites/all/modules/contrib/admin/uuid/LICENSE.txt
Normal file
339
sites/all/modules/contrib/admin/uuid/LICENSE.txt
Normal file
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
32
sites/all/modules/contrib/admin/uuid/README.txt
Normal file
32
sites/all/modules/contrib/admin/uuid/README.txt
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
INTRODUCTION
|
||||
------------
|
||||
|
||||
This module provides an API for adding universally unique identifiers (UUID) to
|
||||
Drupal objects, most notably entities.
|
||||
|
||||
FEATURES
|
||||
--------
|
||||
|
||||
* Automatic UUID generation:
|
||||
UUIDs will be generated for all core entities. An API is provided for other
|
||||
modules to enable support for custom entities.
|
||||
* UUID API for entities, properties and fields:
|
||||
With this unified API you can load entities with entity_uuid_load() so that
|
||||
all supported properties and fields are made with UUID references. You can
|
||||
also save entities formatted this way with entity_uuid_save() (depends on
|
||||
Entity API).
|
||||
* Export entities to use as default/demo content:
|
||||
The integration with Features module provides the ability to export UUID
|
||||
enabled entities with intact dependencies and references to other entities.
|
||||
This functionality depends on Deploy module 7.x-2.0-alpha1 (soon to be
|
||||
released) and is probably the most robust way for installation profiles and
|
||||
distributions to provide demo content!
|
||||
* Services integration:
|
||||
The integration with Services module alters all UUID enabled entity resources
|
||||
(nodes, users, taxonomies etc) to be based on UUIDs instead. This way it
|
||||
becomes easier to share and integrate content between sites. This
|
||||
functionality is used by Deploy module.
|
||||
* More integrations:
|
||||
UUID module integrates with Views, Token, Rules and provides some CTools
|
||||
plugins.
|
43
sites/all/modules/contrib/admin/uuid/UPGRADE.txt
Normal file
43
sites/all/modules/contrib/admin/uuid/UPGRADE.txt
Normal file
@@ -0,0 +1,43 @@
|
||||
|
||||
INTRODUCTION
|
||||
------------
|
||||
|
||||
This document describes how to upgrade between major and minor versions of the
|
||||
UUID module.
|
||||
|
||||
Upgrading between all major and minor versions have been successfully tested
|
||||
when following the steps described in UPGRADE.txt from Drupal core, with
|
||||
addition to the notes in this document.
|
||||
|
||||
Taking full backups of your files and database is always recommended before
|
||||
doing any upgrades.
|
||||
|
||||
UPGRADING FROM UUID 6.x to UUID 7.x
|
||||
-----------------------------------
|
||||
|
||||
In addition to the steps described by UPGRADE.txt from Drupal core, you need to
|
||||
follow these notes:
|
||||
|
||||
* Before upgrading, update to the latest UUID 6.x-1.x-dev
|
||||
|
||||
* When doing your upgrade, you must first upgrade to UUID 7.x-1.0-alpha1 in
|
||||
order to not lose any data during the upgrade. The reason is because the
|
||||
sub-modules responsible for the data migration between 6.x and 7.x was
|
||||
removed after the release of UUID 7.x-1.0-alpha1.
|
||||
|
||||
* After upgrading to UUID 7.x-1.0-alpha1 you can proceed upgrading to later
|
||||
versions of UUID.
|
||||
|
||||
UPGRADING FROM UUID 7.x-1.0-alpha1 TO LATER VERSION
|
||||
---------------------------------------------------
|
||||
|
||||
Make sure to follow these notes when upgrading from 7.x-1.0-alpha1 to later
|
||||
versions:
|
||||
|
||||
* Before upgrading, disable UUID and all UUID sub-modules.
|
||||
|
||||
* Run update.php.
|
||||
|
||||
* Enable the UUID module. The entity specific UUID sub-modules doesn't exist
|
||||
anymore. They are replaced with more efficient functionality in the UUID
|
||||
module. No data is lost.
|
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Plugin to provide an argument handler for all entity IDs.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Plugins are described by creating a $plugin array which will be used
|
||||
* by the system that includes this file.
|
||||
*/
|
||||
$plugin = array(
|
||||
'title' => t("Entity: UUID"),
|
||||
'description' => t('Creates an entity context from an entity UUID argument.'),
|
||||
'context' => 'uuid_entity_uuid_context',
|
||||
'get child' => 'uuid_entity_uuid_get_child',
|
||||
'get children' => 'uuid_entity_uuid_get_children',
|
||||
);
|
||||
|
||||
function uuid_entity_uuid_get_child($plugin, $parent, $child) {
|
||||
$plugins = uuid_entity_uuid_get_children($plugin, $parent);
|
||||
return $plugins[$parent . ':' . $child];
|
||||
}
|
||||
|
||||
function uuid_entity_uuid_get_children($original_plugin, $parent) {
|
||||
$entities = entity_get_info();
|
||||
$plugins = array();
|
||||
foreach ($entities as $entity_type => $entity) {
|
||||
$plugin = $original_plugin;
|
||||
$plugin['title'] = t('@entity: UUID', array('@entity' => $entity['label']));
|
||||
$plugin['keyword'] = $entity_type;
|
||||
$plugin['description'] = t('Creates @entity context from an UUID argument.', array('@entity' => $entity_type));
|
||||
$plugin['name'] = $parent . ':' . $entity_type;
|
||||
$plugin_id = $parent . ':' . $entity_type;
|
||||
drupal_alter('ctools_entity_context', $plugin, $entity, $plugin_id);
|
||||
$plugins[$plugin_id] = $plugin;
|
||||
}
|
||||
drupal_alter('ctools_entity_contexts', $plugins);
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Discover if this argument gives us the entity we crave.
|
||||
*/
|
||||
function uuid_entity_uuid_context($arg = NULL, $conf = NULL, $empty = FALSE) {
|
||||
$entity_type = explode(':', $conf['name']);
|
||||
$entity_type = $entity_type[1];
|
||||
// If unset it wants a generic, unfilled context.
|
||||
if ($empty) {
|
||||
return ctools_context_create_empty('entity:' . $entity_type);
|
||||
}
|
||||
|
||||
// We can accept either an entity object or a pure id.
|
||||
if (is_object($arg)) {
|
||||
return ctools_context_create('entity:' . $entity_type, $arg);
|
||||
}
|
||||
|
||||
if (!is_string($arg)) {
|
||||
return FALSE;
|
||||
}
|
||||
$entity_ids = entity_get_id_by_uuid($entity_type, array($arg));
|
||||
if (!isset($entity_ids[$arg])) {
|
||||
return FALSE;
|
||||
}
|
||||
$entity_id = $entity_ids[$arg];
|
||||
$entities = entity_load($entity_type, array($entity_id));
|
||||
if (!$entities) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return ctools_context_create('entity:' . $entity_type, $entities[$entity_id]);
|
||||
}
|
50
sites/all/modules/contrib/admin/uuid/uuid.admin.inc
Normal file
50
sites/all/modules/contrib/admin/uuid/uuid.admin.inc
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Administration functions for the uuid module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Menu callback: options for UUID.
|
||||
*/
|
||||
function uuid_admin_form() {
|
||||
$form = array();
|
||||
|
||||
$form['sync'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Synchronization'),
|
||||
);
|
||||
|
||||
$form['sync']['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Create missing UUIDs'),
|
||||
'#submit' => array('uuid_admin_sync_submit'),
|
||||
);
|
||||
|
||||
return system_settings_form($form);
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit handler for the UUID sync.
|
||||
*/
|
||||
function uuid_admin_sync_submit() {
|
||||
uuid_sync_all();
|
||||
drupal_set_message(t('Generated missing UUIDs.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Page callback to display Devel information about a UUID entity.
|
||||
*/
|
||||
function uuid_devel_load_by_uuid($entity_type, $entity) {
|
||||
$info = entity_get_info($entity_type);
|
||||
if (isset($info['uuid']) && $info['uuid'] == TRUE && !empty($info['entity keys']['uuid'])) {
|
||||
// Get the keys for local ID and UUID.
|
||||
$uuid_key = $info['entity keys']['uuid'];
|
||||
$uuid_entities = entity_uuid_load($entity_type, array($entity->{$uuid_key}));
|
||||
return kdevel_print_object(reset($uuid_entities), '$' . $entity_type . '->');
|
||||
}
|
||||
else {
|
||||
return t("This entity doesn't support UUID.");
|
||||
}
|
||||
}
|
165
sites/all/modules/contrib/admin/uuid/uuid.api.php
Normal file
165
sites/all/modules/contrib/admin/uuid/uuid.api.php
Normal file
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Hooks provided by the UUID module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Defines one or more UUID generators exposed by a module.
|
||||
*
|
||||
* @return
|
||||
* An associative array with the key being the machine name for the
|
||||
* implementation and the values being an array with the following keys:
|
||||
* - title: The human readable name for the generator.
|
||||
* - callback: The function to be called for generating the UUID.
|
||||
*
|
||||
* @see uuid_get_info()
|
||||
*/
|
||||
function hook_uuid_info() {
|
||||
$generators = array();
|
||||
$generators['my_module'] = array(
|
||||
'title' => t('My module UUID generator'),
|
||||
'callback' => 'my_module_generate_uuid',
|
||||
);
|
||||
return $generators;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures all records have a UUID assigned to them.
|
||||
*
|
||||
* When called this hook should ensure all records it is responsible for
|
||||
* have a UUID and if not create one.
|
||||
*
|
||||
* @see entity_uuid_sync()
|
||||
*/
|
||||
function hook_uuid_sync() {
|
||||
// Do what you need to do to generate missing UUIDs for you implementation.
|
||||
}
|
||||
|
||||
/**
|
||||
* Let modules transform their properties with local IDs to UUIDs when an
|
||||
* entity is loaded.
|
||||
*/
|
||||
function hook_entity_uuid_load(&$entities, $entity_type) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Let modules transform their fields with local IDs to UUIDs when an entity
|
||||
* is loaded.
|
||||
*/
|
||||
function hook_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Let modules transform their properties with UUIDs to local IDs when an
|
||||
* entity is saved.
|
||||
*/
|
||||
function hook_entity_uuid_presave(&$entity, $entity_type) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Let modules transform their fields with UUIDs to local IDs when an entity
|
||||
* is saved.
|
||||
*/
|
||||
function hook_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Let modules transform their properties when an entity is saved.
|
||||
*/
|
||||
function hook_entity_uuid_save($entity, $entity_type) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Let modules act when an entity is deleted.
|
||||
*/
|
||||
function hook_entity_uuid_delete($entity, $entity_type) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Let modules modify paths when they are being converted to UUID ones.
|
||||
*/
|
||||
function hook_uuid_menu_path_to_uri_alter($path, &$uri) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Let modules modify paths when they are being converted from UUID ones.
|
||||
*/
|
||||
function hook_uuid_menu_uri_to_path(&$path, $uri) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow modules to provide a list of default entities that will be imported.
|
||||
*/
|
||||
function hook_uuid_default_entities() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Let other modules do things before default entities are created on rebuild.
|
||||
*/
|
||||
function hook_uuid_entities_pre_rebuild($plan_name) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Let other modules do things after default entities are created on rebuild.
|
||||
*/
|
||||
function hook_uuid_entities_post_rebuild($plan_name) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Let other modules do things before default entities are created on revert.
|
||||
*/
|
||||
function hook_uuid_entities_pre_rebuild($plan_name) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Let other modules do things after default entities are created on revert.
|
||||
*/
|
||||
function hook_uuid_entities_post_rebuild($plan_name) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Let other modules alter entities that are about to be exported.
|
||||
*/
|
||||
function hook_uuid_entities_features_export_entity_alter(&$entity, $entity_type) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Let other modules alter fields on entities that are about to be exported.
|
||||
*/
|
||||
function hook_uuid_entities_features_export_field_alter($entity_type, &$entity, $field, $instance, $langcode, &$items) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter UUID URI data after processing.
|
||||
*/
|
||||
function hook_uuid_uri_data($data) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter UUID URI data after processing.
|
||||
*/
|
||||
function hook_uuid_uri_data($data) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter entity URI before creating UUID URI.
|
||||
*/
|
||||
function hook_uuid_id_uri_data($data) {
|
||||
}
|
407
sites/all/modules/contrib/admin/uuid/uuid.core.inc
Normal file
407
sites/all/modules/contrib/admin/uuid/uuid.core.inc
Normal file
@@ -0,0 +1,407 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Implementation of UUID hooks for all core modules.
|
||||
*
|
||||
* @todo
|
||||
* Replace all these hook implementations with a generic solution that uses
|
||||
* info from hook_entity_field_info() and hook_entity_property_info(). That
|
||||
* info should contain info about how UUIDs are mapped.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup uuid_property Propery implementations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_entity_uuid_load().
|
||||
*/
|
||||
function node_entity_uuid_load(&$entities, $entity_type) {
|
||||
if ($entity_type == 'node') {
|
||||
entity_property_id_to_uuid($entities, 'user', array('uid', 'revision_uid'));
|
||||
entity_property_id_to_uuid($entities, 'node', 'tnid');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_uuid_presave().
|
||||
*/
|
||||
function node_entity_uuid_presave(&$entity, $entity_type) {
|
||||
if ($entity_type == 'node') {
|
||||
entity_property_uuid_to_id($entity, 'user', array('uid', 'revision_uid'));
|
||||
entity_property_uuid_to_id($entity, 'node', 'tnid');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_uuid_load().
|
||||
*/
|
||||
function book_uuid_entities_features_export_entity_alter(&$entity, $entity_type) {
|
||||
if ($entity_type == 'node') {
|
||||
if (!empty($entity->book)) {
|
||||
$entity->book['bid'] = current(entity_get_uuid_by_id($entity_type, array($entity->book['bid'])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_uuid_presave().
|
||||
*/
|
||||
function book_entity_uuid_presave(&$entity, $entity_type) {
|
||||
if ($entity_type == 'node') {
|
||||
if (!empty($entity->book)) {
|
||||
$entity->book['bid'] = current(entity_get_id_by_uuid($entity_type, array($entity->book['bid'])));
|
||||
if (!$entity->book['bid']) {
|
||||
$entity->book['bid'] = 'new';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_uuid_presave().
|
||||
*/
|
||||
function user_entity_uuid_presave(&$entity, $entity_type) {
|
||||
if ($entity_type == 'user') {
|
||||
if (!empty($entity->picture)) {
|
||||
$uuids = entity_get_id_by_uuid('file', array($entity->picture['uuid']));
|
||||
$fid = current($uuids);
|
||||
if (!$entity->is_new) {
|
||||
$entity->picture = file_load($fid);
|
||||
}
|
||||
else {
|
||||
$entity->picture = $fid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_uuid_load().
|
||||
*/
|
||||
function comment_entity_uuid_load(&$entities, $entity_type) {
|
||||
switch ($entity_type) {
|
||||
case 'node':
|
||||
entity_property_id_to_uuid($entities, 'user', 'last_comment_uid');
|
||||
break;
|
||||
|
||||
case 'comment':
|
||||
entity_property_id_to_uuid($entities, 'user', array('uid', 'u_uid'));
|
||||
entity_property_id_to_uuid($entities, 'node', 'nid');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_uuid_presave().
|
||||
*/
|
||||
function comment_entity_uuid_presave(&$entity, $entity_type) {
|
||||
switch ($entity_type) {
|
||||
case 'node':
|
||||
entity_property_uuid_to_id($entity, 'user', 'last_comment_uid');
|
||||
break;
|
||||
|
||||
case 'comment':
|
||||
entity_property_uuid_to_id($entity, 'user', array('uid', 'u_uid'));
|
||||
entity_property_uuid_to_id($entity, 'node', 'nid');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_uuid_load().
|
||||
*/
|
||||
function file_entity_uuid_load(&$entities, $entity_type) {
|
||||
if ($entity_type == 'file') {
|
||||
entity_property_id_to_uuid($entities, 'user', 'uid');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_uuid_presave().
|
||||
*/
|
||||
function file_entity_uuid_presave(&$entity, $entity_type) {
|
||||
if ($entity_type == 'file') {
|
||||
entity_property_uuid_to_id($entity, 'user', 'uid');
|
||||
if (isset($entity->file_contents)) {
|
||||
$directory = drupal_dirname($entity->uri);
|
||||
file_prepare_directory($directory, FILE_CREATE_DIRECTORY);
|
||||
file_unmanaged_save_data(base64_decode($entity->file_contents), $entity->uri, FILE_EXISTS_REPLACE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_uuid_load().
|
||||
*/
|
||||
function taxonomy_entity_uuid_load(&$entities, $entity_type) {
|
||||
if ($entity_type == 'taxonomy_term') {
|
||||
foreach ($entities as &$entity) {
|
||||
if (isset($entity->parent)) {
|
||||
if (!is_array($entity->parent)) {
|
||||
$entity->parent = array($entity->parent);
|
||||
}
|
||||
$uuids = entity_get_uuid_by_id('taxonomy_term', $entity->parent);
|
||||
$entity->parent = array_values($uuids);
|
||||
}
|
||||
unset($entity->vid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_uuid_presave().
|
||||
*/
|
||||
function taxonomy_entity_uuid_presave(&$entity, $entity_type) {
|
||||
if ($entity_type == 'taxonomy_term') {
|
||||
if (isset($entity->parent)) {
|
||||
if (!is_array($entity->parent)) {
|
||||
$entity->parent = array($entity->parent);
|
||||
}
|
||||
$ids = entity_get_id_by_uuid('taxonomy_term', $entity->parent);
|
||||
$entity->parent = array_values($ids);
|
||||
}
|
||||
$vocabulary = taxonomy_vocabulary_machine_name_load($entity->vocabulary_machine_name);
|
||||
$entity->vid = $vocabulary->vid;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_uuid_load().
|
||||
*/
|
||||
function field_entity_uuid_load(&$entities, $entity_type) {
|
||||
foreach ($entities as $i => $entity) {
|
||||
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);
|
||||
if (!empty($field) && isset($entity->{$field_name})) {
|
||||
foreach ($entity->{$field_name} as $langcode => &$items) {
|
||||
// Invoke 'hook_field_uuid_load'. We can't use module_invoke() since
|
||||
// that is not passing by reference.
|
||||
$function = $field['module'] . '_field_uuid_load';
|
||||
if (function_exists($function)) {
|
||||
$function($entity_type, $entity, $field, $instance, $langcode, $items);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_uuid_presave().
|
||||
*/
|
||||
function field_entity_uuid_presave(&$entity, $entity_type) {
|
||||
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);
|
||||
if (!empty($field) && isset($entity->{$field_name})) {
|
||||
foreach ($entity->{$field_name} as $langcode => &$items) {
|
||||
// Invoke 'hook_field_uuid_load'. We can't use module_invoke() since
|
||||
// that is not passing by reference.
|
||||
$function = $field['module'] . '_field_uuid_presave';
|
||||
if (function_exists($function)) {
|
||||
$function($entity_type, $entity, $field, $instance, $langcode, $items);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "Property implementations"
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup uuid_field Field implementations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_field_uuid_load().
|
||||
*/
|
||||
function taxonomy_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
entity_property_id_to_uuid($items, 'taxonomy_term', 'tid');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_uuid_presave().
|
||||
*/
|
||||
function taxonomy_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
entity_property_uuid_to_id($items, 'taxonomy_term', 'tid');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_uuid_load().
|
||||
*/
|
||||
function file_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
entity_property_id_to_uuid($items, 'file', 'fid');
|
||||
entity_property_id_to_uuid($items, 'user', 'uid');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_uuid_presave().
|
||||
*/
|
||||
function file_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
entity_property_uuid_to_id($items, 'file', 'fid');
|
||||
entity_property_uuid_to_id($items, 'user', 'uid');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_uuid_load().
|
||||
*/
|
||||
function image_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
file_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, $items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_uuid_presave().
|
||||
*/
|
||||
function image_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
file_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, $items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_uuid_load().
|
||||
*/
|
||||
function node_reference_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
entity_property_id_to_uuid($items, 'node', 'nid');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_uuid_presave().
|
||||
*/
|
||||
function node_reference_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
entity_property_uuid_to_id($items, 'node', 'nid');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_uuid_load().
|
||||
*/
|
||||
function user_reference_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
entity_property_id_to_uuid($items, 'user', 'uid');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_uuid_presave().
|
||||
*/
|
||||
function user_reference_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
entity_property_uuid_to_id($items, 'user', 'uid');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_uuid_load().
|
||||
*/
|
||||
function entityreference_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
// TODO: This is not really good, but as of now 'entity_property_id_to_uuid()'
|
||||
// can't handle a single $item.
|
||||
entity_property_id_to_uuid($items, $field['settings']['target_type'], 'target_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_uuid_presave().
|
||||
*/
|
||||
function entityreference_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
// TODO: This is not really good, but as of now 'entity_property_id_to_uuid()'
|
||||
// can't handle a single $item.
|
||||
entity_property_uuid_to_id($items, $field['settings']['target_type'], 'target_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_uuid_load().
|
||||
*/
|
||||
function field_collection_entity_uuid_load(&$entities, $entity_type) {
|
||||
if ($entity_type == 'field_collection_item') {
|
||||
entity_property_id_to_uuid($entities, 'field_collection_item', 'value');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_uuid_presave().
|
||||
*/
|
||||
function field_collection_entity_uuid_presave(&$entity, $entity_type) {
|
||||
if ($entity_type == 'field_collection_item') {
|
||||
entity_property_uuid_to_id($entity, 'field_collection_item', 'value');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_uuid_load().
|
||||
*/
|
||||
function field_collection_field_uuid_load($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
entity_property_id_to_uuid($items, 'field_collection_item', 'value');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_uuid_presave().
|
||||
*/
|
||||
function field_collection_field_uuid_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
entity_property_uuid_to_id($items, 'field_collection_item', 'value');
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "Field implementations"
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup uuid_export Export alterations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_uuid_entities_features_export_entity_alter().
|
||||
*/
|
||||
function node_uuid_entities_features_export_entity_alter(&$entity, $entity_type) {
|
||||
if ($entity_type == 'node') {
|
||||
foreach (array('data', 'name', 'picture', 'revision_uid', 'last_comment_timestamp') as $property) {
|
||||
if (property_exists($entity, $property)) {
|
||||
unset($entity->{$property});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_uuid_entities_features_export_entity_alter().
|
||||
*/
|
||||
function user_uuid_entities_features_export_entity_alter(&$entity, $entity_type) {
|
||||
if ($entity_type == 'user') {
|
||||
foreach (array('data', 'access', 'login') as $property) {
|
||||
if (property_exists($entity, $property)) {
|
||||
unset($entity->{$property});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_uuid_entities_features_export_alter().
|
||||
*/
|
||||
function file_uuid_entities_features_export_field_alter($entity_type, $entity, $field, $instance, $langcode, &$items) {
|
||||
foreach ($items as &$item) {
|
||||
if (isset($item['timestamp'])) {
|
||||
unset($item['timestamp']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_uuid_entities_features_export_entity_alter().
|
||||
*/
|
||||
function workbench_uuid_entities_features_export_entity_alter(&$entity, $entity_type) {
|
||||
foreach (array('workbench_moderation', 'my_revision', 'workbench_access', 'workbench_access_scheme', 'workbench_access_by_role') as $property) {
|
||||
if (isset($entity->{$property})) {
|
||||
unset($entity->{$property});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "Export alterations"
|
||||
*/
|
41
sites/all/modules/contrib/admin/uuid/uuid.drush.inc
Normal file
41
sites/all/modules/contrib/admin/uuid/uuid.drush.inc
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Drush implementation for the uuid module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementats hook_drush_command().
|
||||
*/
|
||||
function uuid_drush_command() {
|
||||
$items = array();
|
||||
$items['uuid-create-missing'] = array(
|
||||
'description' => 'Create missing UUIDs for enabled entities.',
|
||||
'aliases' => array('uuid-create'),
|
||||
);
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementats of hook_drush_help().
|
||||
*/
|
||||
function uuid_drush_help($section) {
|
||||
switch ($section) {
|
||||
case 'drush:uuid-create-missing':
|
||||
return dt("This command will create missing UUIDs for those content types specified in the module settings for automatic generation.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Drush command callback.
|
||||
*/
|
||||
function drush_uuid_create_missing() {
|
||||
if (!drush_confirm(dt('Are you sure?'))) {
|
||||
return drush_user_abort();
|
||||
}
|
||||
module_load_include('inc', 'uuid', 'uuid');
|
||||
|
||||
drush_log(dt('Beginning bulk creation of UUIDs.'), 'ok');
|
||||
uuid_sync_all();
|
||||
}
|
543
sites/all/modules/contrib/admin/uuid/uuid.entity.inc
Normal file
543
sites/all/modules/contrib/admin/uuid/uuid.entity.inc
Normal file
@@ -0,0 +1,543 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Entity related functions for UUID module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Entity UUID exception class.
|
||||
*/
|
||||
class UuidEntityException extends Exception {}
|
||||
|
||||
/**
|
||||
* Helper function that returns entity info for all supported core modules,
|
||||
* relevant for UUID functionality.
|
||||
*
|
||||
* @see uuid_entity_info()
|
||||
* @see uuid_schema_alter()
|
||||
* @see uuid_install()
|
||||
* @see uuid_uninstall()
|
||||
*/
|
||||
function uuid_get_core_entity_info() {
|
||||
$info = array();
|
||||
$info['user'] = array(
|
||||
'base table' => 'users',
|
||||
'entity keys' => array(
|
||||
'uuid' => 'uuid',
|
||||
),
|
||||
);
|
||||
$info['node'] = array(
|
||||
'base table' => 'node',
|
||||
'revision table' => 'node_revision',
|
||||
'entity keys' => array(
|
||||
'uuid' => 'uuid',
|
||||
'revision uuid' => 'vuuid',
|
||||
),
|
||||
);
|
||||
if (module_exists('comment')) {
|
||||
$info['comment'] = array(
|
||||
'base table' => 'comment',
|
||||
'entity keys' => array(
|
||||
'uuid' => 'uuid',
|
||||
),
|
||||
);
|
||||
}
|
||||
if (module_exists('file')) {
|
||||
$info['file'] = array(
|
||||
'base table' => 'file_managed',
|
||||
'entity keys' => array(
|
||||
'uuid' => 'uuid',
|
||||
),
|
||||
);
|
||||
}
|
||||
if (module_exists('taxonomy')) {
|
||||
$info['taxonomy_term'] = array(
|
||||
'base table' => 'taxonomy_term_data',
|
||||
'entity keys' => array(
|
||||
'uuid' => 'uuid',
|
||||
),
|
||||
);
|
||||
}
|
||||
if (module_exists('field_collection')) {
|
||||
$info['field_collection_item'] = array(
|
||||
'base table' => 'field_collection_item',
|
||||
'entity keys' => array(
|
||||
'uuid' => 'uuid',
|
||||
),
|
||||
);
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* @defgroup uuid_entity_hooks UUID implementation of Entity API
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements of hook_entity_info_alter().
|
||||
*
|
||||
* @see uuid_core_entity_info().
|
||||
*/
|
||||
function uuid_entity_info_alter(&$info) {
|
||||
foreach (uuid_get_core_entity_info() as $entity_type => $core_info) {
|
||||
$info[$entity_type]['uuid'] = TRUE;
|
||||
$info[$entity_type]['entity keys']['uuid'] = $core_info['entity keys']['uuid'];
|
||||
if (!empty($core_info['entity keys']['revision uuid'])) {
|
||||
$info[$entity_type]['entity keys']['revision uuid'] = $core_info['entity keys']['revision uuid'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements of hook_entity_property_info_alter().
|
||||
*
|
||||
* This adds the UUID as an entity property for all UUID-enabled entities
|
||||
* which automatically gives us token and Rules integration.
|
||||
*/
|
||||
function uuid_entity_property_info_alter(&$info) {
|
||||
foreach (entity_get_info() as $entity_type => $entity_info) {
|
||||
if (isset($entity_info['uuid']) && $entity_info['uuid'] == TRUE && !empty($entity_info['entity keys']['uuid'])) {
|
||||
$info[$entity_type]['properties'][$entity_info['entity keys']['uuid']] = array(
|
||||
'label' => t('UUID'),
|
||||
'type' => 'text',
|
||||
'description' => t('The universally unique ID.'),
|
||||
'schema field' => $entity_info['entity keys']['uuid'],
|
||||
);
|
||||
if (!empty($entity_info['entity keys']['revision uuid'])) {
|
||||
$info[$entity_type]['properties'][$entity_info['entity keys']['revision uuid']] = array(
|
||||
'label' => t('Revision UUID'),
|
||||
'type' => 'text',
|
||||
'description' => t("The revision's universally unique ID."),
|
||||
'schema field' => $entity_info['entity keys']['revision uuid'],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements of hook_entity_presave().
|
||||
*
|
||||
* This is where all UUID-enabled entities get their UUIDs.
|
||||
*/
|
||||
function uuid_entity_presave($entity, $entity_type) {
|
||||
$info = entity_get_info($entity_type);
|
||||
if (isset($info['uuid']) && $info['uuid'] == TRUE && !empty($info['entity keys']['uuid'])) {
|
||||
$uuid_key = $info['entity keys']['uuid'];
|
||||
if (empty($entity->{$uuid_key})) {
|
||||
$entity->{$uuid_key} = uuid_generate();
|
||||
}
|
||||
if (!empty($info['entity keys']['revision uuid'])) {
|
||||
$vuuid_key = $info['entity keys']['revision uuid'];
|
||||
if ((isset($entity->revision) && $entity->revision == TRUE) || empty($entity->{$vuuid_key})) {
|
||||
$entity->{$vuuid_key} = uuid_generate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "UUID implementation of Entity API"
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup uuid_entity_support UUID support for Entity API
|
||||
* @{
|
||||
* Functions that extends the Entity API with UUID support.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Load entities by their UUID, that only should containing UUID references.
|
||||
*
|
||||
* This function is mostly useful if you want to load an entity from the local
|
||||
* database that only should contain UUID references.
|
||||
*
|
||||
* @see entity_load()
|
||||
*/
|
||||
function entity_uuid_load($entity_type, $uuids = array(), $conditions = array(), $reset = FALSE) {
|
||||
$ids = entity_get_id_by_uuid($entity_type, $uuids);
|
||||
$results = entity_load($entity_type, $ids, $conditions, $reset);
|
||||
$entities = array();
|
||||
|
||||
// We need to do this little magic here, because objects are passed by
|
||||
// reference. And because hook_entity_uuid_load() has the intention changing
|
||||
// primary properties and fields from local IDs to UUIDs it will also change
|
||||
// DrupalDefaultEntityController::entityCache by reference which is a static
|
||||
// cache of entities. And that is not something we want.
|
||||
foreach ($results as $key => $entity) {
|
||||
// This will avoid passing our loaded entities by reference.
|
||||
$entities[$key] = clone $entity;
|
||||
}
|
||||
|
||||
entity_make_entity_universal($entity_type, $entities);
|
||||
|
||||
return $entities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to make an entity universal (i.e. only global references).
|
||||
*/
|
||||
function entity_make_entity_universal($entity_type, $entities) {
|
||||
// Let other modules transform local ID references to UUID references.
|
||||
if (!empty($entities)) {
|
||||
$hook = 'entity_uuid_load';
|
||||
foreach (module_implements($hook) as $module) {
|
||||
$function = $module . '_' . $hook;
|
||||
if (function_exists($function)) {
|
||||
$function($entities, $entity_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Permanently saves an entity by its UUID.
|
||||
*
|
||||
* This function depends on the Entity API module to provide the
|
||||
* 'entity_save()' function.
|
||||
*
|
||||
* This function is mostly useful if you want to save an entity into the local
|
||||
* database that only contains UUID references.
|
||||
*
|
||||
* @see entity_save()
|
||||
*/
|
||||
function entity_uuid_save($entity_type, $entity) {
|
||||
// This function, and this function only, depends on the entity module.
|
||||
if (!module_exists('entity')) {
|
||||
throw new UuidEntityException(t('Calling %function requires the Entity API module (!link).', array('%function' => __FUNCTION__, '!link' => 'http://drupal.org/project/entity')));
|
||||
}
|
||||
|
||||
entity_make_entity_local($entity_type, $entity);
|
||||
|
||||
// Save the entity.
|
||||
entity_save($entity_type, $entity);
|
||||
|
||||
$hook = 'entity_uuid_save';
|
||||
foreach (module_implements($hook) as $module) {
|
||||
$function = $module . '_' . $hook;
|
||||
if (function_exists($function)) {
|
||||
$function($entity, $entity_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to make an entity local (i.e. only local references).
|
||||
*/
|
||||
function entity_make_entity_local($entity_type, $entity) {
|
||||
$info = entity_get_info($entity_type);
|
||||
if (isset($info['uuid']) && $info['uuid'] == TRUE && !empty($info['entity keys']['uuid'])) {
|
||||
// Get the keys for local ID and UUID.
|
||||
$id_key = $info['entity keys']['id'];
|
||||
$uuid_key = $info['entity keys']['uuid'];
|
||||
|
||||
// UUID entites must always provide a valid UUID when saving in order to do
|
||||
// the correct mapping between local and global IDs.
|
||||
if (empty($entity->{$uuid_key}) || !uuid_is_valid($entity->{$uuid_key})) {
|
||||
throw new UuidEntityException(t('Trying to save a @type entity with empty or invalid UUID.', array('@type' => $info['label'])));
|
||||
}
|
||||
|
||||
// Fetch the local ID by its UUID.
|
||||
$ids = entity_get_id_by_uuid($entity_type, array($entity->{$uuid_key}));
|
||||
$id = reset($ids);
|
||||
// Set the correct local ID.
|
||||
if (empty($id)) {
|
||||
unset($entity->{$id_key});
|
||||
$entity->is_new = TRUE;
|
||||
}
|
||||
else {
|
||||
$entity->{$id_key} = $id;
|
||||
$entity->is_new = FALSE;
|
||||
}
|
||||
|
||||
if (!empty($info['entity keys']['revision uuid'])) {
|
||||
// Get the keys for local revison ID and revision UUID.
|
||||
$vid_key = $info['entity keys']['revision'];
|
||||
$vuuid_key = $info['entity keys']['revision uuid'];
|
||||
$vid = NULL;
|
||||
// Fetch the local revision ID by its UUID.
|
||||
if (isset($entity->{$vuuid_key})) {
|
||||
$vids = entity_get_id_by_uuid($entity_type, array($entity->{$vuuid_key}), TRUE);
|
||||
$vid = reset($vids);
|
||||
}
|
||||
if (empty($vid) && isset($entity->{$vid_key})) {
|
||||
unset($entity->{$vid_key});
|
||||
}
|
||||
elseif (!empty($vid)) {
|
||||
$entity->{$vid_key} = $vid;
|
||||
}
|
||||
// Nodes need this when trying to save an existing node without a vid.
|
||||
if ($entity_type == 'node' && !isset($entity->vid) && !$entity->is_new) {
|
||||
$entity->revision = 0;
|
||||
$entity->vid = db_select('node', 'n')
|
||||
->condition('n.nid', $entity->nid)
|
||||
->fields('n', array('vid'))
|
||||
->execute()
|
||||
->fetchField();
|
||||
}
|
||||
}
|
||||
|
||||
// Let other modules transform UUID references to local ID references.
|
||||
$hook = 'entity_uuid_presave';
|
||||
foreach (module_implements($hook) as $module) {
|
||||
$function = $module . '_' . $hook;
|
||||
if (function_exists($function)) {
|
||||
$function($entity, $entity_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new UuidEntityException(t('Trying to operate on a @type entity, which doesn\'t support UUIDs.', array('@type' => $info['label'])));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Permanently delete the given entity by its UUID.
|
||||
*
|
||||
* This function depends on the Entity API module to provide the
|
||||
* 'entity_delete()' function.
|
||||
*
|
||||
* @see entity_delete()
|
||||
*/
|
||||
function entity_uuid_delete($entity_type, $uuid) {
|
||||
// This function, and this function only, depends on the entity module.
|
||||
if (!module_exists('entity')) {
|
||||
throw new UuidEntityException(t('Calling %function requires the Entity API module (!link).', array('%function' => __FUNCTION__, '!link' => 'http://drupal.org/project/entity')));
|
||||
}
|
||||
|
||||
$info = entity_get_info($entity_type);
|
||||
if (isset($info['uuid']) && $info['uuid'] == TRUE) {
|
||||
// Fetch the local ID by its UUID.
|
||||
$ids = entity_get_id_by_uuid($entity_type, array($uuid));
|
||||
$id = reset($ids);
|
||||
|
||||
// Let other modules transform UUID references to local ID references.
|
||||
$hook = 'entity_uuid_delete';
|
||||
foreach (module_implements($hook) as $module) {
|
||||
$function = $module . '_' . $hook;
|
||||
if (function_exists($function)) {
|
||||
$function($entity, $entity_type);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the entity.
|
||||
return entity_delete($entity_type, $id);
|
||||
}
|
||||
else {
|
||||
throw new UuidEntityException(t('Trying to delete a @type entity, which doesn\'t support UUIDs.', array('@type' => $info['label'])));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that retrieves entity IDs by their UUIDs.
|
||||
*
|
||||
* @todo
|
||||
* Statically cache as many IDs as possible and limit the query.
|
||||
*
|
||||
* @param $entity_type
|
||||
* The entity type we should be dealing with.
|
||||
* @param $uuids
|
||||
* An array of UUIDs for which we should find their entity IDs. If $revision
|
||||
* is TRUE this should be revision UUIDs instead.
|
||||
* @param $revision
|
||||
* If TRUE the revision IDs is returned instead.
|
||||
* @return
|
||||
* Array of entity IDs keyed by their UUIDs. If $revision is TRUE revision
|
||||
* IDs and UUIDs are returned instead.
|
||||
*/
|
||||
function entity_get_id_by_uuid($entity_type, $uuids, $revision = FALSE) {
|
||||
if (empty($uuids)) {
|
||||
return array();
|
||||
}
|
||||
$info = entity_get_info($entity_type);
|
||||
// Find out what entity keys to use.
|
||||
if (!$revision) {
|
||||
$table = $info['base table'];
|
||||
$id_key = $info['entity keys']['id'];
|
||||
$uuid_key = $info['entity keys']['uuid'];
|
||||
}
|
||||
elseif (isset($info['revision table'])) {
|
||||
$table = $info['revision table'];
|
||||
$id_key = $info['entity keys']['revision'];
|
||||
$uuid_key = $info['entity keys']['revision uuid'];
|
||||
}
|
||||
// If we want revision IDs, but the entity doesn't support it. Return empty.
|
||||
else {
|
||||
return array();
|
||||
}
|
||||
|
||||
// Get all UUIDs in one query.
|
||||
return db_select($table, 't')
|
||||
->fields('t', array($uuid_key, $id_key))
|
||||
->condition($uuid_key, array_values($uuids), 'IN')
|
||||
->execute()
|
||||
->fetchAllKeyed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that retrieves UUIDs by their entity IDs.
|
||||
*
|
||||
* @todo
|
||||
* Statically cache as many IDs as possible and limit the query.
|
||||
*
|
||||
* @param $entity_type
|
||||
* The entity type we should be dealing with.
|
||||
* @param $ids
|
||||
* An array of entity IDs for which we should find their UUIDs. If $revision
|
||||
* is TRUE this should be revision IDs instead.
|
||||
* @param $revision
|
||||
* If TRUE the revision UUIDs is returned instead.
|
||||
* @return
|
||||
* Array of entity UUIDs keyed by their IDs. If $revision is TRUE revision
|
||||
* IDs and UUIDs are returned instead.
|
||||
*/
|
||||
function entity_get_uuid_by_id($entity_type, $ids, $revision = FALSE) {
|
||||
if (empty($ids)) {
|
||||
return array();
|
||||
}
|
||||
$info = entity_get_info($entity_type);
|
||||
// Find out what entity keys to use.
|
||||
if (!$revision) {
|
||||
$table = $info['base table'];
|
||||
$id_key = $info['entity keys']['id'];
|
||||
$uuid_key = $info['entity keys']['uuid'];
|
||||
}
|
||||
elseif (isset($info['revision table'])) {
|
||||
$table = $info['revision table'];
|
||||
$id_key = $info['entity keys']['revision'];
|
||||
$uuid_key = $info['entity keys']['revision uuid'];
|
||||
}
|
||||
// If we want revision UUIDs, but the entity doesn't support it. Return empty.
|
||||
else {
|
||||
return array();
|
||||
}
|
||||
|
||||
// Get all UUIDs in one query.
|
||||
return db_select($table, 't')
|
||||
->fields('t', array($id_key, $uuid_key))
|
||||
->condition($id_key, array_values($ids), 'IN')
|
||||
->execute()
|
||||
->fetchAllKeyed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to change entity properties from ID to UUID.
|
||||
*
|
||||
* We never change user UID 0 or 1 to UUIDs. Those are low level user accounts
|
||||
* ("anonymous" and "root") that needs to be identified consistently across
|
||||
* any system.
|
||||
*
|
||||
* @todo
|
||||
* Add tests for this function.
|
||||
*
|
||||
* @param $objects
|
||||
* An array of objects that should get $properties changed. Can be either an
|
||||
* entity object or a field items array.
|
||||
* @param $entity_type
|
||||
* The type of entity that all $properties refers to.
|
||||
* @param $properties
|
||||
* An array of properties that should be changed. All properties must refer to
|
||||
* the same type of entity (the one referenced in $entity_type).
|
||||
*/
|
||||
function entity_property_id_to_uuid(&$objects, $entity_type, $properties) {
|
||||
if (!is_array($objects)) {
|
||||
$things = array(&$objects);
|
||||
}
|
||||
else {
|
||||
$things = &$objects;
|
||||
}
|
||||
if (!is_array($properties)) {
|
||||
$properties = array($properties);
|
||||
}
|
||||
$ids = array();
|
||||
$values = array();
|
||||
$i = 0;
|
||||
foreach ($things as &$object) {
|
||||
foreach ($properties as $property) {
|
||||
// This is probably an entity object.
|
||||
if (is_object($object) && isset($object->{$property})) {
|
||||
$values[$i] = &$object->{$property};
|
||||
}
|
||||
// This is probably a field items array.
|
||||
elseif (is_array($object) && isset($object[$property])) {
|
||||
$values[$i] = &$object[$property];
|
||||
}
|
||||
else {
|
||||
$i++;
|
||||
continue;
|
||||
}
|
||||
if (!($entity_type == 'user' && ($values[$i] == 0 || $values[$i] == 1))) {
|
||||
$ids[] = $values[$i];
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
$uuids = entity_get_uuid_by_id($entity_type, $ids);
|
||||
foreach ($values as $i => $value) {
|
||||
if (isset($uuids[$value])) {
|
||||
$values[$i] = $uuids[$value];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to change entity properties from UUID to ID.
|
||||
*
|
||||
* @todo
|
||||
* Add tests for this function.
|
||||
*
|
||||
* @param $objects
|
||||
* An array of objects that should get $properties changed. Can be either an
|
||||
* entity object or a field items array.
|
||||
* @param $entity_type
|
||||
* The type of entity that all $properties refers to.
|
||||
* @param $properties
|
||||
* An array of properties that should be changed. All properties must refer to
|
||||
* the same type of entity (the one referenced in $entity_type).
|
||||
*/
|
||||
function entity_property_uuid_to_id(&$objects, $entity_type, $properties) {
|
||||
if (!is_array($objects)) {
|
||||
$things = array(&$objects);
|
||||
}
|
||||
else {
|
||||
$things = &$objects;
|
||||
}
|
||||
if (!is_array($properties)) {
|
||||
$properties = array($properties);
|
||||
}
|
||||
$uuids = array();
|
||||
$values = array();
|
||||
$i = 0;
|
||||
foreach ($things as &$object) {
|
||||
foreach ($properties as $property) {
|
||||
// This is probably an entity object.
|
||||
if (is_object($object) && isset($object->{$property})) {
|
||||
$values[$i] = &$object->{$property};
|
||||
}
|
||||
// This is probably a field items array.
|
||||
elseif (is_array($object) && isset($object[$property])) {
|
||||
$values[$i] = &$object[$property];
|
||||
}
|
||||
else {
|
||||
$i++;
|
||||
continue;
|
||||
}
|
||||
if (uuid_is_valid($values[$i])) {
|
||||
$uuids[] = $values[$i];
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
$ids = entity_get_id_by_uuid($entity_type, $uuids);
|
||||
foreach ($values as $i => $value) {
|
||||
if (isset($ids[$value])) {
|
||||
$values[$i] = $ids[$value];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "UUID support for Entity API"
|
||||
*/
|
206
sites/all/modules/contrib/admin/uuid/uuid.features.inc
Normal file
206
sites/all/modules/contrib/admin/uuid/uuid.features.inc
Normal file
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Features support to export entities from any Deploy <em>fetch-only</em> plan.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements [component]_features_export_options().
|
||||
*
|
||||
* Deploy plans are used as the initial source for an export. Deploy solves
|
||||
* complex dependency chains for us, so the entities actually can be used as is.
|
||||
*/
|
||||
function uuid_entities_features_export_options() {
|
||||
$options = array();
|
||||
if (module_exists('deploy')) {
|
||||
$plans = deploy_plan_load_all(array('fetch_only' => 1));
|
||||
foreach ($plans as $plan) {
|
||||
$options[$plan->name] = $plan->title;
|
||||
}
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements [component]_features_export().
|
||||
*/
|
||||
function uuid_entities_features_export($components, &$export, $module_name) {
|
||||
foreach ($components as $plan_name) {
|
||||
$export['features']['uuid_entities'][$plan_name] = $plan_name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements [component]_features_export_render().
|
||||
*
|
||||
* Components corresponds to the name of Deploy plans. However, once exported,
|
||||
* entities can be rendered directly from the default hook without Deploy or the
|
||||
* initial plan.
|
||||
*/
|
||||
function uuid_entities_features_export_render($module_name, $components, $export = NULL) {
|
||||
$code = array();
|
||||
$code[] = ' $entities = array();';
|
||||
$code[] = '';
|
||||
|
||||
foreach ($components as $component) {
|
||||
$entities = array();
|
||||
if (module_exists('deploy') && $plan = deploy_plan_load($component)) {
|
||||
$entities = $plan->getIterator();
|
||||
}
|
||||
else {
|
||||
features_include_defaults(array('uuid_entities'));
|
||||
$default_entities = module_invoke($module_name, 'uuid_default_entities');
|
||||
foreach ($default_entities[$component] as $entity) {
|
||||
$metadata = $entity->__metadata;
|
||||
$entity_type = $metadata['type'];
|
||||
$entity_info = entity_get_info($entity_type);
|
||||
$results = entity_uuid_load($entity_type, array($entity->{$entity_info['entity keys']['uuid']}), NULL, TRUE);
|
||||
if (!empty($results)) {
|
||||
$entity = reset($results);
|
||||
// Re-attach the metadata after loading the clean entity.
|
||||
$entity->__metadata = $metadata;
|
||||
$entities[] = $entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($entities as $entity) {
|
||||
$entity_type = $entity->__metadata['type'];
|
||||
$entity_info = entity_get_info($entity_type);
|
||||
// We need to remove entity id and revision keys for better consistency.
|
||||
$id_key = $entity_info['entity keys']['id'];
|
||||
if (isset($entity->{$id_key})) {
|
||||
unset($entity->{$id_key});
|
||||
}
|
||||
if (!empty($entity_info['entity keys']['revision'])) {
|
||||
$vid_key = $entity_info['entity keys']['revision'];
|
||||
if (isset($entity->{$vid_key})) {
|
||||
unset($entity->{$vid_key});
|
||||
}
|
||||
if (!empty($entity_info['entity keys']['revision uuid'])) {
|
||||
$vuuid_key = $entity_info['entity keys']['revision uuid'];
|
||||
unset($entity->{$vuuid_key});
|
||||
}
|
||||
}
|
||||
// We unset some common timestamp properties, since those will change and
|
||||
// constantly leave the feature overidden.
|
||||
$keys = array('created', 'updated', 'changed', 'revision_timestamp', 'timestamp', 'stamp', 'current');
|
||||
foreach ($keys as $key) {
|
||||
if (isset($entity->{$key})) {
|
||||
unset($entity->{$key});
|
||||
}
|
||||
}
|
||||
// Let other modules alter exported entities.
|
||||
drupal_alter('uuid_entities_features_export_entity', $entity, $entity_type);
|
||||
// Field handling.
|
||||
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);
|
||||
if (!empty($entity->{$field_name})) {
|
||||
foreach ($entity->{$field_name} as $langcode => &$items) {
|
||||
// Let other modules alter fields on exported entities.
|
||||
// We are not using drupal_alter() here, because of it's complexity
|
||||
// dealing with over two alterable arguments.
|
||||
$hook = 'uuid_entities_features_export_field_alter';
|
||||
foreach (module_implements($hook) as $module_name) {
|
||||
$function = $module_name . '_' . $hook;
|
||||
$function($entity_type, $entity, $field, $instance, $langcode, $items);
|
||||
}
|
||||
foreach ($items as &$item) {
|
||||
// We don't need to export these common field keys.
|
||||
foreach (array('safe_value', 'safe_summary') as $key) {
|
||||
if (isset($item[$key])) {
|
||||
unset($item[$key]);
|
||||
}
|
||||
}
|
||||
uuid_entities_features_clean($item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
uuid_entities_features_clean($entity);
|
||||
|
||||
// Convert entities to array to avoid having them in JSON, returned from standard implementation of $entity->export().
|
||||
if (is_object($entity) && method_exists($entity, 'export')) {
|
||||
$entity = get_object_vars($entity);
|
||||
}
|
||||
$code[] = ' $entities[\'' . check_plain($component) . '\'][] = (object) ' . features_var_export($entity, ' ') . ';';
|
||||
}
|
||||
}
|
||||
$code[] = '';
|
||||
$code[] = ' return $entities;';
|
||||
return array('uuid_default_entities' => implode("\n", $code));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements [component]_features_export_rebuild().
|
||||
*/
|
||||
function uuid_entities_features_rebuild($module_name) {
|
||||
uuid_entities_rebuild($module_name, 'rebuild');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements [component]_features_export_revert().
|
||||
*/
|
||||
function uuid_entities_features_revert($module_name) {
|
||||
uuid_entities_rebuild($module_name, 'revert');
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to rebuild entities from a plan.
|
||||
*/
|
||||
function uuid_entities_rebuild($module_name = '', $op = 'rebuild') {
|
||||
features_include_defaults(array('uuid_entities'));
|
||||
$entities = module_invoke($module_name, 'uuid_default_entities');
|
||||
if (!empty($entities)) {
|
||||
foreach ($entities as $plan_name => $entities) {
|
||||
// Let other modules do things before default entities are created.
|
||||
module_invoke_all("uuid_entities_pre_$op", $plan_name);
|
||||
foreach ($entities as $entity) {
|
||||
entity_uuid_save($entity->__metadata['type'], $entity);
|
||||
}
|
||||
// Let other modules do things after default entities are created.
|
||||
module_invoke_all("uuid_entities_post_$op", $plan_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to sort properties of an object.
|
||||
*
|
||||
* This will maintain better consistency. Keys might get shifted order or type
|
||||
* due to alterations sometimes.
|
||||
*/
|
||||
function uuid_entities_features_clean(&$object) {
|
||||
$properties = array();
|
||||
foreach ($object as $key => $value) {
|
||||
$properties[$key] = $value;
|
||||
if (is_object($object)) {
|
||||
unset($object->{$key});
|
||||
}
|
||||
elseif (is_array($object)) {
|
||||
unset($object[$key]);
|
||||
}
|
||||
}
|
||||
ksort($properties);
|
||||
foreach ($properties as $key => $value) {
|
||||
// Make properties type consistent.
|
||||
if (is_string($value) || is_numeric($value)) {
|
||||
if (is_object($object)) {
|
||||
$object->{$key} = "$value";
|
||||
}
|
||||
elseif (is_array($object)) {
|
||||
$object[$key] = "$value";
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (is_object($object)) {
|
||||
$object->{$key} = $value;
|
||||
}
|
||||
elseif (is_array($object)) {
|
||||
$object[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
204
sites/all/modules/contrib/admin/uuid/uuid.inc
Normal file
204
sites/all/modules/contrib/admin/uuid/uuid.inc
Normal file
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Handling of universally unique identifiers.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pattern for detecting a valid UUID.
|
||||
*/
|
||||
define('UUID_PATTERN', '[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}');
|
||||
|
||||
/**
|
||||
* Generates an universally unique identifier.
|
||||
*
|
||||
* This function first checks for the PECL alternative for generating
|
||||
* universally unique identifiers. If that doesn't exist, then it falls back on
|
||||
* PHP for generating that.
|
||||
*
|
||||
* @return
|
||||
* An UUID, made up of 32 hex digits and 4 hyphens.
|
||||
*/
|
||||
function uuid_generate() {
|
||||
$callback = drupal_static(__FUNCTION__);
|
||||
|
||||
if (empty($callback)) {
|
||||
if (function_exists('uuid_create') && !function_exists('uuid_make')) {
|
||||
$callback = '_uuid_generate_pecl';
|
||||
}
|
||||
elseif (function_exists('com_create_guid')) {
|
||||
$callback = '_uuid_generate_com';
|
||||
}
|
||||
else {
|
||||
$callback = '_uuid_generate_php';
|
||||
}
|
||||
}
|
||||
return $callback();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate all missing UUIDs.
|
||||
*/
|
||||
function uuid_sync_all() {
|
||||
module_invoke_all('uuid_sync');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a UUID URI for an entity.
|
||||
*
|
||||
* @param object $entity
|
||||
* The entity to use for generating the UUID URI.
|
||||
* @param string $entity_type
|
||||
* The type of entity being used.
|
||||
*
|
||||
* @return string
|
||||
* The generated UUID URI or normal URI if entity doesn't support UUIDs.
|
||||
*/
|
||||
function uuid_entity_uuid_uri($entity, $entity_type) {
|
||||
$entity_info = entity_get_info($entity_type);
|
||||
|
||||
if (empty($entity_info['uuid'])) {
|
||||
$uri = $entity_info['uri callback']($entity);
|
||||
return $uri['path'];
|
||||
}
|
||||
|
||||
if (isset($entity_info['uuid uri callback'])) {
|
||||
return $entity_info['uuid uri callback']($entity);
|
||||
}
|
||||
|
||||
return "uuid/{$entity_type}/" . $entity->{$entity_info['entity keys']['uuid']};
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an ID URI string to an entity data array.
|
||||
*
|
||||
* @see uuid_id_uri_array_to_data()
|
||||
*
|
||||
* @param string $uri
|
||||
* The URI to convert.
|
||||
*
|
||||
* @return array
|
||||
* The entity data.
|
||||
*/
|
||||
function uuid_id_uri_to_data($uri) {
|
||||
$parts = explode('/', $uri);
|
||||
return uuid_id_uri_array_to_data($parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a URI array to entity data array.
|
||||
*
|
||||
* @param array $uri
|
||||
* The URI parts, often taken from arg().
|
||||
*
|
||||
* @return array
|
||||
* The entity data.
|
||||
*/
|
||||
function uuid_id_uri_array_to_data($uri) {
|
||||
$data = array(
|
||||
'request' => $uri,
|
||||
'entity_type' => $uri[0],
|
||||
'id' => $uri[1],
|
||||
);
|
||||
|
||||
drupal_alter('uuid_id_uri_data', $data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a UUID URI string to an entity data array.
|
||||
*
|
||||
* @see uuid_uri_array_to_data()
|
||||
*
|
||||
* @param string $uri
|
||||
* The URI to convert.
|
||||
*
|
||||
* @return array
|
||||
* The entity data.
|
||||
*/
|
||||
function uuid_uri_to_data($uri, $strip_uuid = TRUE) {
|
||||
return uuid_uri_array_to_data(explode('/', $uri));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a URI array to entity data array.
|
||||
*
|
||||
* @param array $uri
|
||||
* The URI parts, often taken from arg().
|
||||
*
|
||||
* @return array
|
||||
* The entity data.
|
||||
*/
|
||||
function uuid_uri_array_to_data($uri, $strip_uuid = TRUE) {
|
||||
if ($strip_uuid) {
|
||||
array_shift($uri);
|
||||
}
|
||||
|
||||
$data = array(
|
||||
'request' => $uri,
|
||||
'entity_type' => $uri[0],
|
||||
'uuid' => $uri[1],
|
||||
);
|
||||
|
||||
drupal_alter('uuid_uri_data', $data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a UUID using the Windows internal GUID generator.
|
||||
*
|
||||
* @see http://php.net/com_create_guid
|
||||
*/
|
||||
function _uuid_generate_com() {
|
||||
// Remove {} wrapper and make lower case to keep result consistent.
|
||||
return drupal_strtolower(trim(com_create_guid(), '{}'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an universally unique identifier using the PECL extension.
|
||||
*/
|
||||
function _uuid_generate_pecl() {
|
||||
return uuid_create(UUID_TYPE_DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a UUID v4 using PHP code.
|
||||
*
|
||||
* Based on code from @see http://php.net/uniqid#65879 , but corrected.
|
||||
*/
|
||||
function _uuid_generate_php() {
|
||||
// The field names refer to RFC 4122 section 4.1.2.
|
||||
return sprintf('%04x%04x-%04x-4%03x-%04x-%04x%04x%04x',
|
||||
// 32 bits for "time_low".
|
||||
mt_rand(0, 65535), mt_rand(0, 65535),
|
||||
// 16 bits for "time_mid".
|
||||
mt_rand(0, 65535),
|
||||
// 12 bits after the 0100 of (version) 4 for "time_hi_and_version".
|
||||
mt_rand(0, 4095),
|
||||
bindec(substr_replace(sprintf('%016b', mt_rand(0, 65535)), '10', 0, 2)),
|
||||
// 8 bits, the last two of which (positions 6 and 7) are 01, for "clk_seq_hi_res"
|
||||
// (hence, the 2nd hex digit after the 3rd hyphen can only be 1, 5, 9 or d)
|
||||
// 8 bits for "clk_seq_low" 48 bits for "node".
|
||||
mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// This is wrapped in an if block to avoid conflicts with PECL's uuid_is_valid().
|
||||
/**
|
||||
* Check that a string appears to be in the format of a UUID.
|
||||
*
|
||||
* @param $uuid
|
||||
* The string to test.
|
||||
*
|
||||
* @return
|
||||
* TRUE if the string is well formed.
|
||||
*/
|
||||
if (!function_exists('uuid_is_valid')) {
|
||||
function uuid_is_valid($uuid) {
|
||||
return preg_match('/^' . UUID_PATTERN . '$/', $uuid);
|
||||
}
|
||||
}
|
13
sites/all/modules/contrib/admin/uuid/uuid.info
Normal file
13
sites/all/modules/contrib/admin/uuid/uuid.info
Normal file
@@ -0,0 +1,13 @@
|
||||
name = Universally Unique ID
|
||||
description = Extends the entity functionality and adds support for universally unique identifiers.
|
||||
core = 7.x
|
||||
package = UUID
|
||||
configure = admin/config/system/uuid
|
||||
files[] = uuid.test
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-09-11
|
||||
version = "7.x-1.0-alpha5+0-dev"
|
||||
core = "7.x"
|
||||
project = "uuid"
|
||||
datestamp = "1378899072"
|
||||
|
232
sites/all/modules/contrib/admin/uuid/uuid.install
Normal file
232
sites/all/modules/contrib/admin/uuid/uuid.install
Normal file
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install, update and uninstall functions for the uuid module.
|
||||
*/
|
||||
|
||||
define('UUID_UPGRADE_VAR', 'uuid_upgrade_in_progress');
|
||||
|
||||
/**
|
||||
* Include some helper functions for the Entity API.
|
||||
*/
|
||||
module_load_include('inc', 'uuid', 'uuid.entity');
|
||||
|
||||
/**
|
||||
* Helper function that returns a schema field definition for UUID fields.
|
||||
*
|
||||
* @see uuid_schema_alter()
|
||||
* @see uuid_install()
|
||||
*/
|
||||
function uuid_schema_field_definition() {
|
||||
return array(
|
||||
'type' => 'char',
|
||||
'length' => 36,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
'description' => 'The Universally Unique Identifier.',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements of hook_schema_alter().
|
||||
*/
|
||||
function uuid_schema_alter(&$schema = array()) {
|
||||
$field = uuid_schema_field_definition();
|
||||
foreach (uuid_get_core_entity_info() as $entity_type => $info) {
|
||||
$schema[$info['base table']]['fields'][$info['entity keys']['uuid']] = $field;
|
||||
if (!empty($info['revision table']) && !empty($info['entity keys']['revision uuid'])) {
|
||||
$schema[$info['revision table']]['fields'][$info['entity keys']['revision uuid']] = $field;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_install().
|
||||
*/
|
||||
function uuid_install() {
|
||||
_uuid_install_uuid_fields();
|
||||
uuid_sync_all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Install the 'uuid' and 'vuuid' fields into Drupal core entity tables where needed.
|
||||
*
|
||||
* IMPORTANT: This function is called both at install and update time. If this method
|
||||
* is modified to add additional fields in the future, the update strategy must be
|
||||
* considered. See the comment in uuid_update_7102.
|
||||
*/
|
||||
function _uuid_install_uuid_fields() {
|
||||
$field = uuid_schema_field_definition();
|
||||
foreach (uuid_get_core_entity_info() as $entity_type => $info) {
|
||||
if (!db_field_exists($info['base table'], $info['entity keys']['uuid'])) {
|
||||
db_add_field($info['base table'], $info['entity keys']['uuid'], $field);
|
||||
db_add_index($info['base table'], $info['entity keys']['uuid'], array($info['entity keys']['uuid']));
|
||||
}
|
||||
if (!empty($info['revision table']) && !empty($info['entity keys']['revision uuid'])) {
|
||||
if (!db_field_exists($info['revision table'], $info['entity keys']['revision uuid'])) {
|
||||
db_add_field($info['revision table'], $info['entity keys']['revision uuid'], $field);
|
||||
db_add_index($info['revision table'], $info['entity keys']['revision uuid'], array($info['entity keys']['revision uuid']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_uninstall().
|
||||
*/
|
||||
function uuid_uninstall() {
|
||||
foreach (uuid_get_core_entity_info() as $entity_type => $info) {
|
||||
if (db_field_exists($info['base table'], $info['entity keys']['uuid'])) {
|
||||
db_drop_field($info['base table'], $info['entity keys']['uuid']);
|
||||
db_drop_index($info['base table'], $info['entity keys']['uuid']);
|
||||
}
|
||||
if (!empty($info['revision table']) && !empty($info['entity keys']['revision uuid'])) {
|
||||
if (db_field_exists($info['revision table'], $info['entity keys']['revision uuid'])) {
|
||||
db_drop_field($info['revision table'], $info['entity keys']['revision uuid']);
|
||||
db_drop_index($info['revision table'], $info['entity keys']['revision uuid']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_modules_installed().
|
||||
*/
|
||||
function uuid_modules_installed($modules) {
|
||||
// Run the installation hook. This makes sure that the schema for all
|
||||
// supported core entity types is set correct.
|
||||
uuid_install();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create uuid_vocabulary and uuid_term_data tables.
|
||||
*/
|
||||
function uuid_update_6001() {
|
||||
$ret = array();
|
||||
|
||||
db_create_table($ret, 'uuid_vocabulary', uuid_table_schema('vocabulary', 'vid'));
|
||||
db_create_table($ret, 'uuid_term_data', uuid_table_schema('term_data', 'tid'));
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* For each of out tables, drop the indexe on the UUID column and add a unique
|
||||
* key on that column.
|
||||
*/
|
||||
function uuid_update_6002() {
|
||||
$ret = array();
|
||||
|
||||
foreach (uuid_schema() as $table => $schema) {
|
||||
db_drop_index($ret, $table, $table . '_uuid_idx');
|
||||
db_add_unique_key($ret, $table, $table . '_uuid_key', array('uuid'));
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create uuid_comment table.
|
||||
*/
|
||||
function uuid_update_6003() {
|
||||
$ret = array();
|
||||
|
||||
db_create_table($ret, 'uuid_comments', uuid_table_schema('comments', 'cid'));
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix the column definitions for uuid columns in all tables
|
||||
* to use the more efficient char spec.
|
||||
*/
|
||||
function uuid_update_6004() {
|
||||
$ret = array();
|
||||
|
||||
// Use what's in uuid_table_schema in order to be consistent.
|
||||
$tables = uuid_schema();
|
||||
$spec = $tables['uuid_node']['fields']['uuid'];
|
||||
|
||||
foreach ($tables as $tablename => $schema) {
|
||||
if (db_table_exists($tablename)) {
|
||||
db_change_field($ret, $tablename, 'uuid', 'uuid', $spec);
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify existing uuid_node_revisions table to support revision deletion, and
|
||||
* add in as much legacy data as possible.
|
||||
*/
|
||||
function uuid_update_6005() {
|
||||
$ret = array();
|
||||
|
||||
if (db_table_exists('uuid_node_revisions')) {
|
||||
// Use what's already defined in uuid schema in order to be consistent.
|
||||
$schema = uuid_schema();
|
||||
$spec = $schema['uuid_node_revisions']['fields']['nid'];
|
||||
db_add_field($ret, 'uuid_node_revisions', 'nid', $spec);
|
||||
// Add node ids to the new column, for revisions that exist, but now have a
|
||||
// default value of 0 in uuid_node_revisions.
|
||||
$result = db_query('SELECT nr.nid, nr.vid FROM {node_revisions} AS nr LEFT JOIN {uuid_node_revisions} AS unr ON unr.vid=nr.vid WHERE unr.nid=%d', 0);
|
||||
while ($item = db_fetch_object($result)) {
|
||||
$ret[] = update_sql('UPDATE {uuid_node_revisions} SET nid=' . (int) $item->nid . ' WHERE vid=' . (int) $item->vid);
|
||||
}
|
||||
// Add uuid_node_revision rows for rows that don't exist, but should.
|
||||
$result = db_query('SELECT nr.nid, nr.vid FROM {node_revisions} AS nr LEFT JOIN {uuid_node_revisions} AS unr ON unr.vid=nr.vid WHERE unr.nid IS NULL');
|
||||
while ($item = db_fetch_object($result)) {
|
||||
$ret[] = update_sql(sprintf("INSERT INTO {uuid_node_revisions} (vid, uuid, nid) VALUES(%d, '%s', %d)", $item->vid, uuid_uuid(), $item->nid));
|
||||
}
|
||||
// Delete any orphaned revision vid, uuid pairs.
|
||||
$ret[] = update_sql('DELETE FROM {uuid_node_revisions} WHERE nid=0');
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove old variables.
|
||||
*/
|
||||
function uuid_update_7100() {
|
||||
$types = array(
|
||||
'nodes',
|
||||
'users',
|
||||
'taxonomy',
|
||||
'comments',
|
||||
);
|
||||
foreach ($types as $type) {
|
||||
variable_del('uuid_automatic_for_' . $type);
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear cache for installations that used alpha1. Modules that previously was
|
||||
* enabled in uuid_update_7100() doesn't exist anymore.
|
||||
*/
|
||||
function uuid_update_7101() {
|
||||
drupal_flush_all_caches();
|
||||
}
|
||||
|
||||
/**
|
||||
* Insure that the uuid and vuuid fields are added where needed.
|
||||
*
|
||||
* Note that update 7102 calls _uuid_install_uuid_fields(), which is an
|
||||
* idempotent function. If _uuid_install_uuid_fields() is changed at some
|
||||
* point in the future (but remains idempotent), then some uuid users
|
||||
* will have run update 7102, and some will not. A new uuid_update_7103()
|
||||
* function would would therefore be necessary to update all users to
|
||||
* the latest schema. At the same time, uuid_update_7102() could become
|
||||
* an empty function, as it would not be necessary to call _uuid_install_uuid_fields()
|
||||
* twice.
|
||||
*/
|
||||
function uuid_update_7102() {
|
||||
// If the user have disabled the UUID module during upgrade (as UPGRADE.txt
|
||||
// instructs), some functions will be missing. So include the module file.
|
||||
module_load_include('module', 'uuid', 'uuid');
|
||||
_uuid_install_uuid_fields();
|
||||
uuid_sync_all();
|
||||
}
|
229
sites/all/modules/contrib/admin/uuid/uuid.module
Normal file
229
sites/all/modules/contrib/admin/uuid/uuid.module
Normal file
@@ -0,0 +1,229 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Main module functions for the uuid module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Include main API functions.
|
||||
*/
|
||||
module_load_include('inc', 'uuid', 'uuid');
|
||||
|
||||
/**
|
||||
* Include the Entity API implementation of the UUID API.
|
||||
*/
|
||||
module_load_include('inc', 'uuid', 'uuid.entity');
|
||||
|
||||
/**
|
||||
* Include implementations for all core modules.
|
||||
*
|
||||
* Instead of having separate modules for all core implementations this file
|
||||
* implements all of them in their own name space. In some cases this adds some
|
||||
* unecessary code weight, but instead it saves us from module mania.
|
||||
*/
|
||||
module_load_include('inc', 'uuid', 'uuid.core');
|
||||
|
||||
/**
|
||||
* Implements of hook_menu().
|
||||
*/
|
||||
function uuid_menu() {
|
||||
$items = array();
|
||||
|
||||
$items['uuid'] = array(
|
||||
'title' => 'UUID redirector',
|
||||
'description' => 'Redirects requests for UUID URIs to the referenced entity.',
|
||||
'page callback' => 'uuid_redirector',
|
||||
'access callback' => TRUE,
|
||||
'type' => MENU_CALLBACK,
|
||||
);
|
||||
|
||||
$items['admin/config/system/uuid'] = array(
|
||||
'title' => 'Universally unique identifiers',
|
||||
'description' => 'Configure universally unique identifiers.',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('uuid_admin_form'),
|
||||
'access arguments' => array('administer uuid'),
|
||||
'type' => MENU_NORMAL_ITEM,
|
||||
'file' => 'uuid.admin.inc',
|
||||
);
|
||||
|
||||
// Conditional support for Devel. A good thing for developers.
|
||||
if (module_exists('devel')) {
|
||||
$entity_types = array(
|
||||
'user' => array('path' => 'user/%user/devel/load-by-uuid', 'arg' => 1),
|
||||
'node' => array('path' => 'node/%node/devel/load-by-uuid', 'arg' => 1),
|
||||
'comment' => array('path' => 'comment/%comment/devel/load-by-uuid', 'arg' => 1),
|
||||
'taxonomy_term' => array('path' => 'taxonomy/term/%taxonomy_term/devel/load-by-uuid', 'arg' => 2),
|
||||
);
|
||||
foreach ($entity_types as $entity_type => $info) {
|
||||
$items[$info['path']] = array(
|
||||
'title' => 'Load by UUID',
|
||||
'page callback' => 'uuid_devel_load_by_uuid',
|
||||
'page arguments' => array($entity_type, $info['arg']),
|
||||
'access arguments' => array('access devel information'),
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
'file' => 'uuid.admin.inc',
|
||||
'weight' => 100,
|
||||
);
|
||||
}
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements of hook_ctools_plugin_directory().
|
||||
*/
|
||||
function uuid_ctools_plugin_directory($module, $plugin) {
|
||||
if ($module == 'ctools') {
|
||||
return 'plugins/' . $plugin;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements of hook_permission().
|
||||
*/
|
||||
function uuid_permission() {
|
||||
return array(
|
||||
'administer uuid' => array(
|
||||
'title' => t('Administer UUID'),
|
||||
'description' => t('Allows configuration of the UUID module and APIs.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_hook_info().
|
||||
*/
|
||||
function uuid_hook_info() {
|
||||
$hook_names = array(
|
||||
'uuid_info',
|
||||
'uuid_sync',
|
||||
'entity_uuid_load',
|
||||
'field_uuid_load',
|
||||
'entity_uuid_presave',
|
||||
'entity_uuid_save',
|
||||
'entity_uuid_delete',
|
||||
'field_uuid_presave',
|
||||
'uuid_menu_path_to_uri_alter',
|
||||
'uuid_menu_uri_to_path_alter',
|
||||
'uuid_default_entities',
|
||||
'uuid_entities_pre_rebuild',
|
||||
'uuid_entities_pre_revert',
|
||||
'uuid_entities_post_rebuild',
|
||||
'uuid_entities_post_revert',
|
||||
'uuid_entities_features_export_entity_alter',
|
||||
'uuid_entities_features_export_field_alter',
|
||||
'uuid_uri_data',
|
||||
'uuid_id_uri_data',
|
||||
'uuid_uri_data',
|
||||
'uuid_id_uri_data',
|
||||
);
|
||||
|
||||
return array_fill_keys($hook_names, array('group' => 'uuid'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of hook_views_api().
|
||||
*/
|
||||
function uuid_views_api() {
|
||||
return array(
|
||||
'api' => 2,
|
||||
'path' => drupal_get_path('module', 'uuid'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements of hook_module_implements_alter().
|
||||
*
|
||||
* Moves implementation of hook_entity_info_alter() to the bottom so it is
|
||||
* invoked after all modules relying on the entity API.
|
||||
*
|
||||
* @see uuid_entity_info_alter()
|
||||
*/
|
||||
function uuid_module_implements_alter(&$Implementss, $hook) {
|
||||
if ($hook == 'entity_info_alter') {
|
||||
// Move our hook Implements to the bottom.
|
||||
$group = $Implementss['uuid'];
|
||||
unset($Implementss['uuid']);
|
||||
$Implementss['uuid'] = $group;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements of hook_uuid_sync().
|
||||
*/
|
||||
function uuid_uuid_sync() {
|
||||
foreach (entity_get_info() as $entity_type => $info) {
|
||||
if (isset($info['uuid']) && $info['uuid'] == TRUE && !empty($info['entity keys']['uuid'])) {
|
||||
_uuid_sync_table($info['base table'], $info['entity keys']['id'], $info['entity keys']['uuid']);
|
||||
if (!empty($info['entity keys']['revision uuid'])) {
|
||||
_uuid_sync_table($info['revision table'], $info['entity keys']['revision'], $info['entity keys']['revision uuid']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that executes the update on the actual table.
|
||||
*/
|
||||
function _uuid_sync_table($table, $id_field, $uuid_field) {
|
||||
// Fetch empty records.
|
||||
$result = db_select($table, 't')
|
||||
->fields('t', array($id_field))
|
||||
->condition(db_or()->condition($uuid_field, '')->isNull($uuid_field))
|
||||
->execute();
|
||||
|
||||
// Update empty records.
|
||||
foreach ($result as $record) {
|
||||
db_update($table)
|
||||
->fields(array($uuid_field => uuid_generate()))
|
||||
->condition($id_field, $record->{$id_field})
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_features_api().
|
||||
*
|
||||
* The Features support consists of exporting entities from a Deploy
|
||||
* <em>fetch-only</em> plan. Deploy is only required to generate the feature
|
||||
* it self.
|
||||
*
|
||||
* The reason why we depend on Deploy for the generation of the content is
|
||||
* because Deploy has the kind of dependency detection framework we need, to
|
||||
* identify all dependencies for all entities.
|
||||
*/
|
||||
function uuid_features_api() {
|
||||
return array(
|
||||
'uuid_entities' => array(
|
||||
'name' => t('UUID entities'),
|
||||
'default_hook' => 'uuid_default_entities',
|
||||
'default_file' => FEATURES_DEFAULTS_INCLUDED,
|
||||
'feature_source' => TRUE,
|
||||
'file' => drupal_get_path('module', 'uuid') .'/uuid.features.inc',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirects all UUID URI requests to the appropriate entity page.
|
||||
*/
|
||||
function uuid_redirector() {
|
||||
$entity_data = uuid_uri_array_to_data(arg());
|
||||
|
||||
$entity_info = entity_get_info($entity_data['entity_type']);
|
||||
if (empty($entity_info['uuid'])) {
|
||||
return drupal_not_found();
|
||||
}
|
||||
|
||||
$entities = entity_uuid_load($entity_data['entity_type'], array($entity_data['uuid']));
|
||||
if (!count($entities)) {
|
||||
return drupal_not_found();
|
||||
}
|
||||
|
||||
$uri = entity_uri($entity_data['entity_type'], current($entities));
|
||||
drupal_goto($uri['path'], array(), 301);
|
||||
}
|
||||
|
690
sites/all/modules/contrib/admin/uuid/uuid.test
Normal file
690
sites/all/modules/contrib/admin/uuid/uuid.test
Normal file
@@ -0,0 +1,690 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test suite for UUID module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class with some helper methods.
|
||||
*/
|
||||
class UUIDTestCase extends DrupalWebTestCase {
|
||||
|
||||
function setUp() {
|
||||
parent::setUp(func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that asserts a UUID.
|
||||
*/
|
||||
function assertUUID($uuid, $message = NULL) {
|
||||
$this->assertTrue(uuid_is_valid($uuid), $message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the UUID API functions.
|
||||
*/
|
||||
class UUIDAPITestCase extends UUIDTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'UUID API',
|
||||
'description' => 'Tests the UUID API functions.',
|
||||
'group' => 'UUID',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('uuid');
|
||||
}
|
||||
|
||||
function testAPIFunctions() {
|
||||
// This is a valid UUID, we know that.
|
||||
$valid_uuid = '0ab26e6b-f074-4e44-9da6-1205fa0e9761';
|
||||
// Test the uuid_is_valid() function.
|
||||
$this->assertUUID($valid_uuid, 'UUID validation works.');
|
||||
|
||||
// The default generator is 'php'.
|
||||
$uuid = uuid_generate();
|
||||
$this->assertUUID($uuid, 'PHP generator works.');
|
||||
|
||||
// Test the 'mysql' generator.
|
||||
variable_set('uuid_generator', 'mysql');
|
||||
drupal_static_reset('uuid_generate');
|
||||
$uuid = uuid_generate();
|
||||
$this->assertUUID($uuid, 'MySQL generator works.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Entity API functions.
|
||||
*/
|
||||
class UUIDEntityTestCase extends UUIDTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Entity API functions',
|
||||
'description' => 'Tests the Entity API functions.',
|
||||
'group' => 'UUID',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('uuid');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests Entity API's UUID functions.
|
||||
*/
|
||||
function testEntityAPIFunctions() {
|
||||
// Create some entities that we will work with.
|
||||
$user = $this->drupalCreateUser();
|
||||
$node = $this->drupalCreateNode(array('title' => 'original title', 'uid' => $user->uid));
|
||||
|
||||
// Test entity_get_id_by_uuid().
|
||||
$nids = entity_get_id_by_uuid('node', array($node->uuid), FALSE);
|
||||
$this->assertTrue(in_array($node->nid, $nids), 'Lookup of entity ID works.');
|
||||
$vids = entity_get_id_by_uuid('node', array($node->vuuid), TRUE);
|
||||
$this->assertTrue(in_array($node->vid, $vids), 'Lookup of entity revision ID works.');
|
||||
|
||||
// Test entity_get_uuid_by_id().
|
||||
$uuids = entity_get_uuid_by_id('node', array($node->nid), FALSE);
|
||||
$this->assertTrue(in_array($node->uuid, $uuids), 'Lookup of entity UUID works.');
|
||||
$vuuids = entity_get_uuid_by_id('node', array($node->vid), TRUE);
|
||||
$this->assertTrue(in_array($node->vuuid, $vuuids), 'Lookup of entity revision UUID works.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the User implementation.
|
||||
*/
|
||||
class UUIDUserTestCase extends UUIDTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'User implementation',
|
||||
'description' => 'Tests the User implementation.',
|
||||
'group' => 'UUID',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
// Some tests depends on the optional Entity API module.
|
||||
if (module_exists('entity')) {
|
||||
parent::setUp('uuid', 'entity');
|
||||
}
|
||||
else {
|
||||
parent::setUp('uuid');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test CRUD on users with UUID functions.
|
||||
*/
|
||||
function testUserCRUD() {
|
||||
$user = $this->drupalCreateUser();
|
||||
$this->assertUUID($user->uuid, 'User UUID was generated.');
|
||||
|
||||
// Test updating user.
|
||||
$user_test = clone $user;
|
||||
user_save($user_test, array('name' => 'new name'));
|
||||
$user_test = user_load($user->uid, TRUE);
|
||||
$this->assertEqual($user_test->uuid, $user->uuid, 'User UUID was intact after update.');
|
||||
|
||||
// Test entity_uuid_load().
|
||||
$users = entity_uuid_load('user', array($user->uuid), array(), TRUE);
|
||||
$user_test = reset($users);
|
||||
$this->assertEqual($user_test->uid, $user->uid, 'User was correctly loaded with UUID.');
|
||||
|
||||
// The following tests depends on the optional Entity API module.
|
||||
if (module_exists('entity')) {
|
||||
// Test entity_uuid_save() for users.
|
||||
$user_test = clone $user;
|
||||
$user_test->uid = rand();
|
||||
$user_test->name = 'new name';
|
||||
entity_uuid_save('user', $user_test);
|
||||
$user_test = user_load($user->uid, TRUE);
|
||||
$this->assertEqual($user_test->name, 'new name', 'Saving user with UUID mapped to correct user.');
|
||||
$this->assertEqual($user_test->uuid, $user->uuid, 'User UUID was intact after saving with UUID.');
|
||||
|
||||
// Test entity_uuid_delete() for users.
|
||||
entity_uuid_delete('user', $user->uuid);
|
||||
$user_test = user_load($user->uid);
|
||||
$this->assertFalse($user_test, 'Deleting user with UUID worked.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Node implementation.
|
||||
*/
|
||||
class UUIDNodeTestCase extends UUIDTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Node implementation',
|
||||
'description' => 'Tests the Node implementation.',
|
||||
'group' => 'UUID',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
// Some tests depends on the optional Entity API module.
|
||||
if (module_exists('entity')) {
|
||||
parent::setUp('uuid', 'entity');
|
||||
}
|
||||
else {
|
||||
parent::setUp('uuid');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests CRUD on nodes with UUID functions.
|
||||
*/
|
||||
function testNodeCRUD() {
|
||||
// Create some entities that we will work with.
|
||||
$user = $this->drupalCreateUser();
|
||||
$node = $this->drupalCreateNode(array('title' => 'original title', 'uid' => $user->uid));
|
||||
|
||||
$this->assertUUID($node->uuid, 'Node UUID was generated.');
|
||||
$this->assertUUID($node->vuuid, 'Node revision UUID was generated.');
|
||||
|
||||
// Test node update, without creating new revision.
|
||||
$node_test = clone $node;
|
||||
$node_test->title = 'new title';
|
||||
$node_test->revision = FALSE;
|
||||
node_save($node_test);
|
||||
$node_test = node_load($node->nid, FALSE, TRUE);
|
||||
$this->assertEqual($node_test->uuid, $node->uuid, 'Node UUID was intact after update, when not creating new revision.');
|
||||
$this->assertEqual($node_test->vuuid, $node->vuuid, 'Node revision UUID was intact after updating, when not creating new revision.');
|
||||
|
||||
// Test node update, with new revision.
|
||||
$node_test = clone $node;
|
||||
$node_test->title = 'newer title';
|
||||
$node_test->revision = TRUE;
|
||||
node_save($node_test);
|
||||
$node_test = node_load($node->nid, FALSE, TRUE);
|
||||
$this->assertEqual($node_test->uuid, $node->uuid, 'Node UUID was intact after updating, when creating new revision.');
|
||||
$this->assertNotEqual($node_test->vuuid, $node->vuuid, 'A new node revision UUID was generated, when creating new revision.');
|
||||
$this->assertUUID($node_test->vuuid, 'The new node revision UUID was valid.');
|
||||
|
||||
// Test entity_uuid_load().
|
||||
$nodes = entity_uuid_load('node', array($node->uuid), array(), TRUE);
|
||||
$node_test = reset($nodes);
|
||||
$this->assertEqual($node_test->nid, $node->nid, 'Node was correctly loaded with UUID.');
|
||||
$this->assertEqual($node_test->uid, $user->uuid, "Node property 'uid' was transformed to UUID when loaded with UUID.");
|
||||
|
||||
// The following tests depends on the optional Entity API module.
|
||||
if (module_exists('entity')) {
|
||||
// Reload the node again because we have created new revisions above.
|
||||
$node = node_load($node->nid, FALSE, TRUE);
|
||||
// Test entity_uuid_save() for nodes.
|
||||
$nodes = entity_uuid_load('node', array($node->uuid), array(), TRUE);
|
||||
$node_test = reset($nodes);
|
||||
$node_test->nid = rand();
|
||||
$node_test->vid = rand();
|
||||
$node_test->title = 'new title';
|
||||
$node_test->revision = FALSE;
|
||||
entity_uuid_save('node', $node_test);
|
||||
$node_test = node_load($node->nid, FALSE, TRUE);
|
||||
$this->assertEqual($node_test->title, 'new title', 'Saving node with UUID mapped to correct node, when not creating new revision.');
|
||||
$this->assertEqual($node_test->uuid, $node->uuid, 'Node UUID was intact after saving with UUID, when not creating new revision.');
|
||||
$this->assertEqual($node_test->vuuid, $node->vuuid, 'Node revison UUID was intact after saving with UUID, when not creating new revision.');
|
||||
$this->assertEqual($node_test->uid, $node->uid, "Node property 'uid' was intact after saving with UUID, when not creating new revision.");
|
||||
|
||||
// Test the same thing again, but now triggering a new revision.
|
||||
$nodes = entity_uuid_load('node', array($node->uuid), array(), TRUE);
|
||||
$node_test = reset($nodes);
|
||||
$node_test->nid = rand();
|
||||
$node_test->vid = rand();
|
||||
$node_test->title = 'newer title';
|
||||
$node_test->revision = TRUE;
|
||||
entity_uuid_save('node', $node_test);
|
||||
$node_test = node_load($node->nid, FALSE, TRUE);
|
||||
$this->assertEqual($node_test->title, 'newer title', 'Saving node with UUID mapped to correct node, when creating new revision.');
|
||||
$this->assertEqual($node_test->uuid, $node->uuid, 'Node UUID was intact after saving with UUID, when creating new revision.');
|
||||
$this->assertNotEqual($node_test->vuuid, $node->vuuid, 'A new node revison UUID was generated after saving with UUID, when creating new revision.');
|
||||
$this->assertUUID($node_test->vuuid, 'New node revision UUID was valid.');
|
||||
$this->assertEqual($node_test->uid, $node->uid, "Node property 'uid' was intact after saving with UUID, when creating new revision.");
|
||||
|
||||
// Test entity_uuid_delete() for nodes.
|
||||
entity_uuid_delete('node', $node->uuid);
|
||||
$node_test = node_load($node->nid);
|
||||
$this->assertFalse($node_test, 'Deleting node with UUID worked.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Comment implementation.
|
||||
*
|
||||
* @todo
|
||||
* Contribute patch to CommentHelperCase::setUp() to make it extendable.
|
||||
*/
|
||||
class UUIDCommentTestCase extends CommentHelperCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Comment implementation',
|
||||
'description' => 'Tests the Comment implementation.',
|
||||
'group' => 'UUID',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that asserts a UUID.
|
||||
*
|
||||
* We have duplicated this function from UUIDTestCase since we have to extend
|
||||
* CommentHelperCase instead.
|
||||
*/
|
||||
function assertUUID($uuid, $message = NULL) {
|
||||
$this->assertTrue(uuid_is_valid($uuid), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test CRUD on comments with UUID functions.
|
||||
*/
|
||||
function testCommentCRUD() {
|
||||
// This is sub optimal, but due to how CommentHelperCase::setUp() is
|
||||
// constructed we are enforced to do this. So unfortunately this test
|
||||
// depends on 'entity' module for now.
|
||||
module_enable(array('uuid', 'entity'), TRUE);
|
||||
$user = $this->drupalCreateUser();
|
||||
$this->drupalLogin($user);
|
||||
$node = $this->drupalCreateNode();
|
||||
$return = $this->postComment($node, 'Lorem ipsum');
|
||||
|
||||
$comment = comment_load($return->id);
|
||||
$this->assertUUID($comment->uuid, 'Comment UUID was generated.');
|
||||
|
||||
// Test updating comment.
|
||||
$comment_test = clone $comment;
|
||||
$comment_test->subject = 'new subject';
|
||||
comment_save($comment_test);
|
||||
$comment_test = comment_load($comment->cid);
|
||||
$this->assertEqual($comment_test->uuid, $comment->uuid, 'Comment UUID was intact after update.');
|
||||
|
||||
// Test entity_uuid_load().
|
||||
$comments = entity_uuid_load('comment', array($comment->uuid), array(), TRUE);
|
||||
$comment_test = reset($comments);
|
||||
$this->assertEqual($comment_test->cid, $return->id, 'Comment was correctly loaded with UUID.');
|
||||
$this->assertEqual($comment_test->uid, $user->uuid, "Comment property 'uid' was transformed to UUID when loaded with UUID.");
|
||||
$this->assertEqual($comment_test->nid, $node->uuid, "Comment property 'nid' was transformed to UUID when loaded with UUID.");
|
||||
|
||||
// The following tests depends on the optional Entity API module.
|
||||
if (module_exists('entity')) {
|
||||
// Test entity_uuid_save() for comments.
|
||||
$comments = entity_uuid_load('comment', array($comment->uuid), array(), TRUE);
|
||||
$comment_test = reset($comments);
|
||||
$comment_test->cid = rand();
|
||||
$comment_test->subject = 'newer subject';
|
||||
entity_uuid_save('comment', $comment_test);
|
||||
$comment_test = comment_load($comment->cid);
|
||||
$this->assertEqual($comment_test->subject, 'newer subject', 'Saving comment with UUID mapped to correct comment.');
|
||||
$this->assertEqual($comment_test->uuid, $comment->uuid, 'Comment UUID was intact after saving with UUID.');
|
||||
$this->assertEqual($comment_test->uid, $user->uid, "Comment property 'uid' was after saving with UUID.");
|
||||
$this->assertEqual($comment_test->nid, $node->nid, "Comment property 'nid' was after saving with UUID.");
|
||||
|
||||
// Test entity_uuid_delete() for comments.
|
||||
entity_uuid_delete('comment', $comment->uuid);
|
||||
$comment_test = comment_load($comment->cid);
|
||||
$this->assertFalse($comment_test, 'Deleting comment with UUID worked.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Taxonomy implementation.
|
||||
*/
|
||||
class UUIDTaxonomyTestCase extends TaxonomyWebTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Taxonomy implementation',
|
||||
'description' => 'Tests the Taxonomy implementation.',
|
||||
'group' => 'UUID',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A lot of code here is taken from TaxonomyTermTestCase::setUp().
|
||||
*/
|
||||
function setUp() {
|
||||
// Some tests depends on the optional Entity API module.
|
||||
if (module_exists('entity')) {
|
||||
parent::setUp('taxonomy', 'uuid', 'entity');
|
||||
}
|
||||
else {
|
||||
parent::setUp('taxonomy', 'uuid');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that asserts a UUID.
|
||||
*
|
||||
* We have duplicated this function from UUIDTestCase since we have to extend
|
||||
* TaxonomyWebTestCase instead.
|
||||
*/
|
||||
function assertUUID($uuid, $message = NULL) {
|
||||
$this->assertTrue(uuid_is_valid($uuid), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test CRUD on comments with UUID functions.
|
||||
*/
|
||||
function testTaxonomyCRUD() {
|
||||
$user = $this->drupalCreateUser(array('administer taxonomy', 'administer nodes', 'bypass node access'));
|
||||
$this->drupalLogin($user);
|
||||
|
||||
// Create a term by tagging a node. We'll use this node later too.
|
||||
$vocabulary = new stdClass;
|
||||
$vocabulary->vid = 1;
|
||||
$term = $this->createTerm($vocabulary);
|
||||
$this->assertUUID($term->uuid, 'Term UUID was generated.');
|
||||
|
||||
// Test updating term.
|
||||
$term_test = clone $term;
|
||||
$term_test->name = 'new name';
|
||||
taxonomy_term_save($term_test);
|
||||
$term_test = taxonomy_term_load($term->tid);
|
||||
$this->assertEqual($term_test->uuid, $term->uuid, 'Term UUID was intact after update.');
|
||||
|
||||
// Test entity_uuid_load().
|
||||
$terms = entity_uuid_load('taxonomy_term', array($term->uuid), array(), TRUE);
|
||||
$term_test = reset($terms);
|
||||
$this->assertEqual($term_test->tid, $term->tid, 'Term was correctly loaded with UUID.');
|
||||
|
||||
// The following tests depends on the Entity API module.
|
||||
if (module_exists('entity')) {
|
||||
// Test entity_uuid_save() for terms.
|
||||
$terms = entity_uuid_load('taxonomy_term', array($term->uuid), array(), TRUE);
|
||||
$term_test = reset($terms);
|
||||
$term_test->tid = rand();
|
||||
$term_test->name = 'newer name';
|
||||
entity_uuid_save('taxonomy_term', $term_test);
|
||||
$term_test = taxonomy_term_load($term->tid);
|
||||
$this->assertEqual($term_test->name, 'newer name', 'Saving term with UUID mapped to correct term.');
|
||||
$this->assertEqual($term_test->uuid, $term->uuid, 'Term UUID was intact after saving with UUID.');
|
||||
|
||||
// Test entity_uuid_delete() for nodes.
|
||||
entity_uuid_delete('taxonomy_term', $term->uuid);
|
||||
$term_test = taxonomy_term_load($term->tid);
|
||||
$this->assertFalse($term_test, 'Deleting term with UUID worked.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for the UUID synchronization.
|
||||
*/
|
||||
class UUIDSyncTestCase extends UUIDTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'UUID sync',
|
||||
'description' => 'Tests the UUID synchronization.',
|
||||
'group' => 'UUID',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that asserts that a database table column exists.
|
||||
*
|
||||
* @todo
|
||||
* There are something weird around this assertion.
|
||||
*/
|
||||
function assertTableColumn($table, $column, $message) {
|
||||
$result = db_query("SHOW COLUMNS FROM {$table}");
|
||||
$exists = FALSE;
|
||||
foreach ($result as $record) {
|
||||
if ($record->field == $column) {
|
||||
$exists = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->assertTrue($exists, $message);
|
||||
}
|
||||
|
||||
function testSync() {
|
||||
// These entities will not have UUID from the start, since the UUID module
|
||||
// isn't installed yet.
|
||||
$user = $this->drupalCreateUser();
|
||||
$node = $this->drupalCreateNode();
|
||||
|
||||
$this->assertTrue(!isset($node->uuid), "Node has no UUID before installation of UUID module.");
|
||||
$this->assertTrue(!isset($node->vuuid), "Node has no revision UUID before installation of UUID module.");
|
||||
$this->assertTrue(!isset($user->uuid), "User has no UUID before installation of UUID module.");
|
||||
|
||||
// Now enable the UUID module.
|
||||
module_enable(array('uuid'), TRUE);
|
||||
drupal_flush_all_caches();
|
||||
drupal_static_reset();
|
||||
|
||||
// Check that the UUID column was generated for {node}.
|
||||
$this->assertTableColumn('node', 'uuid', 'UUID column was generated for the node table.');
|
||||
$this->assertTableColumn('node_revision', 'vuuid', 'Revision UUID column was generated for the node_revision table.');
|
||||
$this->assertTableColumn('users', 'uuid', 'UUID column was generated for the user table.');
|
||||
|
||||
// Login with a user and click the sync button.
|
||||
$web_user = $this->drupalCreateUser(array('administer uuid'));
|
||||
$this->drupalLogin($web_user);
|
||||
$this->drupalPost('admin/config/system/uuid', array(), t('Create missing UUIDs'));
|
||||
|
||||
// Test if UUID was generated for nodes.
|
||||
$node_test = node_load($node->nid, FALSE, TRUE);
|
||||
$this->assertUUID($node_test->uuid, 'Node UUID was generated when clicking the sync button.');
|
||||
$this->assertUUID($node_test->vuuid, 'Node revision UUID was generated when clicking the sync button.');
|
||||
|
||||
// Test if UUID was generated for users.
|
||||
$user_test = user_load($user->uid, TRUE);
|
||||
$this->assertUUID($user_test->uuid, 'User UUID was generated when clicking the sync button.');
|
||||
}
|
||||
}
|
||||
|
||||
class UUIDExportEntitiesWithDeploy extends DrupalWebTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Export UUID entities',
|
||||
'description' => 'Test exporting UUID entities with Deploy and Features.',
|
||||
'group' => 'UUID',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('taxonomy', 'uuid', 'entity', 'features', 'deploy', 'deploy_example');
|
||||
}
|
||||
|
||||
function testExport() {
|
||||
$test_user = $this->drupalCreateUser();
|
||||
$test_node = $this->drupalCreateNode(array(
|
||||
'uid' => $test_user->uid,
|
||||
));
|
||||
deploy_manager_add_to_plan('deploy_example_plan', 'node', $test_node);
|
||||
// TODO: Test the actual insert.
|
||||
$this->assertTrue(TRUE, 'Added a node with a user dependency to be exported as a Feature module.');
|
||||
|
||||
// Login and recreate the example feature. The feature isn't installed. But
|
||||
// Features can still export the code, and we can test it.
|
||||
$web_user = $this->drupalCreateUser(array('administer features'));
|
||||
$this->drupalLogin($web_user);
|
||||
$code = $this->drupalPost('admin/structure/features/uuid_default_entities_example/recreate', array(), t('Download feature'));
|
||||
$this->assertTrue($code, 'Feature module was exported.');
|
||||
|
||||
// Ensure that we find what we expect in the exported code.
|
||||
$node_test1 = preg_match('/' . $test_node->title . '/', $code);
|
||||
$node_test2 = preg_match("/'uri' => 'node\/" . $test_node->uuid . "'/", $code);
|
||||
$this->assertTrue($node_test1, 'Node title was found in the expoted code.');
|
||||
$this->assertTrue($node_test2, 'Node URI was found in the expoted code.');
|
||||
$user_test1 = preg_match('/' . $test_user->name . '/', $code);
|
||||
$user_test2 = preg_match("/'uri' => 'user\/" . $test_user->uuid . "'/", $code);
|
||||
$this->assertTrue($user_test1, 'User was found in the expoted code.');
|
||||
$this->assertTrue($user_test2, 'User URI was found in the expoted code.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for the UUID synchronization.
|
||||
*/
|
||||
class UUIDImportEntitiesTestCase extends UUIDTestCase {
|
||||
|
||||
/**
|
||||
* Representation of the UUIDs that is exported in our example feature, that
|
||||
* we use for testing.
|
||||
*/
|
||||
public $term1_uuid = 'bcb92ce8-2236-e264-65c8-0c163ae716d1';
|
||||
public $term2_uuid = '4293a15c-531a-6164-7d1b-668ed019a6bd';
|
||||
public $term3_uuid = 'af738a46-f278-cf84-d94d-9e03879fd71e';
|
||||
public $node1_uuid = 'b0558664-c94b-3674-d9df-3e1696b2e471';
|
||||
public $node2_uuid = '5e3d8bbe-a1f2-f2d4-fdc0-71e6c23aa837';
|
||||
public $user1_uuid = '7cf875e6-dc15-4404-f190-5a7c3e91d14c';
|
||||
|
||||
/**
|
||||
* Helper method to assert the uuid_entities component in any features.
|
||||
*/
|
||||
function assertFeatureState($feature, $state, $message = '') {
|
||||
if (empty($message)) {
|
||||
switch ($state) {
|
||||
case FEATURES_DEFAULT:
|
||||
$readable_state = 'default';
|
||||
break;
|
||||
case FEATURES_OVERRIDDEN:
|
||||
$readable_state = 'overridden';
|
||||
break;
|
||||
default:
|
||||
$readable_state = 'unknown';
|
||||
break;
|
||||
}
|
||||
$message = format_string('%component in %feature had state: %state', array('%component' => 'uuid_entities', '%feature' => $feature, '%state' => $readable_state));
|
||||
}
|
||||
// Ensure that the features we used is in default state.
|
||||
$states = features_get_component_states(array($feature), TRUE, TRUE);
|
||||
if (!$this->assertEqual($states[$feature]['uuid_entities'], $state, $message)) {
|
||||
debug(format_string('Enabling functionality to show diff output for debug purposes.'));
|
||||
$success = module_enable(array('diff'));
|
||||
if ($success) {
|
||||
// Make sure we run on cold caches.
|
||||
drupal_flush_all_caches();
|
||||
drupal_static_reset();
|
||||
|
||||
$user = $this->drupalCreateUser(array('administer features'));
|
||||
$this->drupalLogin($user);
|
||||
$this->drupalGet('admin/structure/features/' . $feature . '/diff');
|
||||
}
|
||||
else {
|
||||
debug(format_string('Download !module to see diff output for debug purposes.', array('!module' => 'diff.module')));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getEntityByUuid($entity_type, $uuid) {
|
||||
$ids = entity_get_id_by_uuid($entity_type, array($uuid));
|
||||
$entities = entity_load($entity_type, $ids, NULL, TRUE);
|
||||
return reset($entities);
|
||||
}
|
||||
|
||||
function enableFeature($feature) {
|
||||
$success = module_enable(array($feature), TRUE);
|
||||
$this->assertTrue($success, t('Enabled modules: %modules', array('%modules' => implode(', ', array($feature)))));
|
||||
// Make sure we run on cold caches.
|
||||
drupal_flush_all_caches();
|
||||
drupal_static_reset();
|
||||
}
|
||||
|
||||
function revertFeature($feature) {
|
||||
features_revert(array($feature => array('uuid_entities')));
|
||||
$this->assertTrue(TRUE, format_string('Reverted feature: %feature', array('%feature' => $feature)));
|
||||
}
|
||||
|
||||
function testImport() {
|
||||
$term1 = $this->getEntityByUuid('taxonomy_term', $this->term1_uuid);
|
||||
$term2 = $this->getEntityByUuid('taxonomy_term', $this->term2_uuid);
|
||||
$term3 = $this->getEntityByUuid('taxonomy_term', $this->term3_uuid);
|
||||
$node1 = $this->getEntityByUuid('node', $this->node1_uuid);
|
||||
$node2 = $this->getEntityByUuid('node', $this->node2_uuid);
|
||||
$user1 = $this->getEntityByUuid('user', $this->user1_uuid);
|
||||
|
||||
// Ensure that we don't have our entities yet.
|
||||
$this->assertTrue(empty($term1), 'Term 1 has not been created yet.');
|
||||
$this->assertTrue(empty($term2), 'Term 2 has not been created yet.');
|
||||
$this->assertTrue(empty($term3), 'Term 3 has not been created yet.');
|
||||
$this->assertTrue(empty($node1), 'Node 1 has not been created yet.');
|
||||
$this->assertTrue(empty($node2), 'Node 2 has not been created yet.');
|
||||
$this->assertTrue(empty($user1), 'User 1 has not been created yet.');
|
||||
|
||||
$this->enableFeature('uuid_default_entities_example');
|
||||
|
||||
$term1 = $this->getEntityByUuid('taxonomy_term', $this->term1_uuid);
|
||||
$term2 = $this->getEntityByUuid('taxonomy_term', $this->term2_uuid);
|
||||
$term3 = $this->getEntityByUuid('taxonomy_term', $this->term3_uuid);
|
||||
$node1 = $this->getEntityByUuid('node', $this->node1_uuid);
|
||||
$node2 = $this->getEntityByUuid('node', $this->node2_uuid);
|
||||
$user1 = $this->getEntityByUuid('user', $this->user1_uuid);
|
||||
|
||||
// Ensure that our entities was created.
|
||||
$this->assertEqual($term1->uuid, $this->term1_uuid, 'Term 1 was created.');
|
||||
$this->assertEqual($term2->uuid, $this->term2_uuid, 'Term 2 was created.');
|
||||
$this->assertEqual($term3->uuid, $this->term3_uuid, 'Term 3 was created.');
|
||||
$this->assertEqual($node1->uuid, $this->node1_uuid, 'Node 1 was created.');
|
||||
$this->assertEqual($node2->uuid, $this->node2_uuid, 'Node 2 was created.');
|
||||
$this->assertEqual($user1->uuid, $this->user1_uuid, 'User 1 was created.');
|
||||
|
||||
// Check the features state.
|
||||
$this->assertFeatureState('uuid_default_entities_example', FEATURES_DEFAULT);
|
||||
|
||||
// New property.
|
||||
$new = 'foo bar';
|
||||
// Change a term.
|
||||
$term1->name = $new;
|
||||
$status = taxonomy_term_save($term1);
|
||||
$this->assertEqual($status, SAVED_UPDATED, 'Updated term 1.');
|
||||
// Change a node.
|
||||
$node1->title = $new;
|
||||
node_save($node1);
|
||||
$this->assertEqual($node1->title, $new, 'Updated node 1.');
|
||||
// Change a user.
|
||||
$user1->name = $new;
|
||||
$updated_user = user_save($user1);
|
||||
$this->assertEqual($user1->name, $updated_user->name, 'Updated user 1.');
|
||||
|
||||
// Check the features state.
|
||||
$this->assertFeatureState('uuid_default_entities_example', FEATURES_OVERRIDDEN);
|
||||
|
||||
// Revert the feature.
|
||||
$this->revertFeature('uuid_default_entities_example');
|
||||
|
||||
// Check the features state.
|
||||
$this->assertFeatureState('uuid_default_entities_example', FEATURES_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
class UUIDImportEntitiesWithDeploy extends UUIDImportEntitiesTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Import UUID entities, with Deploy',
|
||||
'description' => 'Test importing UUID entities with Features and Deploy.',
|
||||
'group' => 'UUID',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('taxonomy', 'uuid', 'entity', 'features', 'deploy', 'deploy_example');
|
||||
}
|
||||
}
|
||||
|
||||
class UUIDImportEntitiesWithoutDeploy extends UUIDImportEntitiesTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Import UUID entities, without Deploy',
|
||||
'description' => 'Test importing UUID entities with Features only.',
|
||||
'group' => 'UUID',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('taxonomy', 'uuid', 'entity', 'features');
|
||||
}
|
||||
}
|
60
sites/all/modules/contrib/admin/uuid/uuid.tokens.inc
Normal file
60
sites/all/modules/contrib/admin/uuid/uuid.tokens.inc
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Builds placeholder replacement tokens for uuid-related data.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_token_info().
|
||||
*/
|
||||
function uuid_token_info() {
|
||||
$tokens = array();
|
||||
foreach (entity_get_info() as $entity_type => $info) {
|
||||
if (isset($info['uuid']) && $info['uuid'] == TRUE && !empty($info['entity keys']['uuid'])) {
|
||||
$token_type = !empty($info['token type']) ? $info['token type'] : $entity_type;
|
||||
$tokens['tokens'][$token_type][$info['entity keys']['uuid']] = array(
|
||||
'name' => t('@entity_type UUID', array('@entity_type' => $info['label'])),
|
||||
'description' => t('The universally unique ID of the @entity', array('@entity' => drupal_strtolower($info['label']))),
|
||||
);
|
||||
if (!empty($info['entity keys']['revision uuid'])) {
|
||||
$tokens['tokens'][$token_type][$info['entity keys']['revision uuid']] = array(
|
||||
'name' => t('@entity_type revision UUID', array('@entity_type' => $info['label'])),
|
||||
'description' => t('The universally unique revision ID of the @entity', array('@entity' => drupal_strtolower($info['label']))),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_token_info_alter()
|
||||
*/
|
||||
function uuid_token_info_alter(&$data) {
|
||||
foreach (entity_get_info() as $entity_type => $info) {
|
||||
if (isset($info['uuid']) && $info['uuid'] == TRUE && !empty($info['entity keys']['uuid'])) {
|
||||
$token_type = !empty($info['token type']) ? $info['token type'] : $entity_type;
|
||||
if (empty($data['types'][$token_type])) {
|
||||
unset($data['tokens'][$token_type]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_tokens().
|
||||
*/
|
||||
function uuid_tokens($token_type, $tokens, $data = array(), $options = array()) {
|
||||
$replacements = array();
|
||||
if ($token_type == 'entity') {
|
||||
$info = entity_get_info($data['entity_type']);
|
||||
if (isset($info['uuid']) && $info['uuid'] == TRUE && !empty($info['entity keys']['uuid']) && !empty($tokens[$info['entity keys']['uuid']])) {
|
||||
$replacements[$tokens[$info['entity keys']['uuid']]] = $data['entity']->{$info['entity keys']['uuid']};
|
||||
if (!empty($info['entity keys']['revision uuid']) && !empty($tokens[$info['entity keys']['revision uuid']])) {
|
||||
$replacements[$tokens[$info['entity keys']['revision uuid']]] = $data['entity']->{$info['entity keys']['revision uuid']};
|
||||
}
|
||||
}
|
||||
}
|
||||
return $replacements;
|
||||
}
|
35
sites/all/modules/contrib/admin/uuid/uuid.views.inc
Normal file
35
sites/all/modules/contrib/admin/uuid/uuid.views.inc
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Views Implementation for UUID
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_views_data_alter().
|
||||
*/
|
||||
function uuid_views_data_alter(&$data) {
|
||||
foreach (entity_get_info() as $info) {
|
||||
if (isset($info['uuid']) && $info['uuid'] == TRUE && !empty($info['entity keys']['uuid'])) {
|
||||
$table = $info['base table'];
|
||||
$field = $info['entity keys']['uuid'];
|
||||
$data[$table][$field] = array(
|
||||
'title' => t('@type UUID', array('@type' => $info['label'])),
|
||||
'help' => t('The universally unique ID of the @type.', array('@type' => $info['label'])),
|
||||
'field' => array(
|
||||
'handler' => 'views_handler_field',
|
||||
'click sortable' => TRUE,
|
||||
),
|
||||
'filter' => array(
|
||||
'handler' => 'views_handler_filter_string',
|
||||
'allow empty' => TRUE,
|
||||
),
|
||||
'argument' => array(
|
||||
'handler' => 'views_handler_argument_string',
|
||||
),
|
||||
'sort' => array(
|
||||
'handler' => 'views_handler_sort',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,402 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* uuid_default_entities_example.features.uuid_entities.inc
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_uuid_default_entities().
|
||||
*/
|
||||
function uuid_default_entities_example_uuid_default_entities() {
|
||||
$entities = array();
|
||||
|
||||
$entities['deploy_example_plan'][] = (object) array(
|
||||
'__metadata' => array(
|
||||
'type' => 'taxonomy_term',
|
||||
'uri' => 'taxonomy_term/bcb92ce8-2236-e264-65c8-0c163ae716d1',
|
||||
'cause' => 'node/b0558664-c94b-3674-d9df-3e1696b2e471',
|
||||
),
|
||||
'description' => NULL,
|
||||
'format' => NULL,
|
||||
'name' => 'Foo',
|
||||
'path' => array(
|
||||
'alias' => 'term/foo',
|
||||
),
|
||||
'rdf_mapping' => array(
|
||||
'rdftype' => array(
|
||||
0 => 'skos:Concept',
|
||||
),
|
||||
'name' => array(
|
||||
'predicates' => array(
|
||||
0 => 'rdfs:label',
|
||||
1 => 'skos:prefLabel',
|
||||
),
|
||||
),
|
||||
'description' => array(
|
||||
'predicates' => array(
|
||||
0 => 'skos:definition',
|
||||
),
|
||||
),
|
||||
'vid' => array(
|
||||
'predicates' => array(
|
||||
0 => 'skos:inScheme',
|
||||
),
|
||||
'type' => 'rel',
|
||||
),
|
||||
'parent' => array(
|
||||
'predicates' => array(
|
||||
0 => 'skos:broader',
|
||||
),
|
||||
'type' => 'rel',
|
||||
),
|
||||
),
|
||||
'uuid' => 'bcb92ce8-2236-e264-65c8-0c163ae716d1',
|
||||
'vocabulary_machine_name' => 'tags',
|
||||
'weight' => '0',
|
||||
);
|
||||
$entities['deploy_example_plan'][] = (object) array(
|
||||
'__metadata' => array(
|
||||
'type' => 'taxonomy_term',
|
||||
'uri' => 'taxonomy_term/4293a15c-531a-6164-7d1b-668ed019a6bd',
|
||||
'cause' => 'node/b0558664-c94b-3674-d9df-3e1696b2e471',
|
||||
),
|
||||
'description' => NULL,
|
||||
'format' => NULL,
|
||||
'name' => 'Bar',
|
||||
'rdf_mapping' => array(
|
||||
'rdftype' => array(
|
||||
0 => 'skos:Concept',
|
||||
),
|
||||
'name' => array(
|
||||
'predicates' => array(
|
||||
0 => 'rdfs:label',
|
||||
1 => 'skos:prefLabel',
|
||||
),
|
||||
),
|
||||
'description' => array(
|
||||
'predicates' => array(
|
||||
0 => 'skos:definition',
|
||||
),
|
||||
),
|
||||
'vid' => array(
|
||||
'predicates' => array(
|
||||
0 => 'skos:inScheme',
|
||||
),
|
||||
'type' => 'rel',
|
||||
),
|
||||
'parent' => array(
|
||||
'predicates' => array(
|
||||
0 => 'skos:broader',
|
||||
),
|
||||
'type' => 'rel',
|
||||
),
|
||||
),
|
||||
'uuid' => '4293a15c-531a-6164-7d1b-668ed019a6bd',
|
||||
'vocabulary_machine_name' => 'tags',
|
||||
'weight' => '0',
|
||||
);
|
||||
$entities['deploy_example_plan'][] = (object) array(
|
||||
'__metadata' => array(
|
||||
'type' => 'node',
|
||||
'uri' => 'node/b0558664-c94b-3674-d9df-3e1696b2e471',
|
||||
'cause' => FALSE,
|
||||
),
|
||||
'body' => array(
|
||||
'und' => array(
|
||||
0 => array(
|
||||
'format' => 'filtered_html',
|
||||
'summary' => '',
|
||||
'value' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
),
|
||||
),
|
||||
),
|
||||
'cid' => '0',
|
||||
'comment' => '2',
|
||||
'comment_count' => '0',
|
||||
'field_image' => array(),
|
||||
'field_tags' => array(
|
||||
'und' => array(
|
||||
0 => array(
|
||||
'tid' => 'bcb92ce8-2236-e264-65c8-0c163ae716d1',
|
||||
),
|
||||
1 => array(
|
||||
'tid' => '4293a15c-531a-6164-7d1b-668ed019a6bd',
|
||||
),
|
||||
),
|
||||
),
|
||||
'language' => 'und',
|
||||
'last_comment_name' => NULL,
|
||||
'last_comment_uid' => '1',
|
||||
'log' => '',
|
||||
'path' => array(
|
||||
'alias' => 'lorem-ipsum',
|
||||
),
|
||||
'promote' => '1',
|
||||
'rdf_mapping' => array(
|
||||
'field_image' => array(
|
||||
'predicates' => array(
|
||||
0 => 'og:image',
|
||||
1 => 'rdfs:seeAlso',
|
||||
),
|
||||
'type' => 'rel',
|
||||
),
|
||||
'field_tags' => array(
|
||||
'predicates' => array(
|
||||
0 => 'dc:subject',
|
||||
),
|
||||
'type' => 'rel',
|
||||
),
|
||||
'rdftype' => array(
|
||||
0 => 'sioc:Item',
|
||||
1 => 'foaf:Document',
|
||||
),
|
||||
'title' => array(
|
||||
'predicates' => array(
|
||||
0 => 'dc:title',
|
||||
),
|
||||
),
|
||||
'created' => array(
|
||||
'predicates' => array(
|
||||
0 => 'dc:date',
|
||||
1 => 'dc:created',
|
||||
),
|
||||
'datatype' => 'xsd:dateTime',
|
||||
'callback' => 'date_iso8601',
|
||||
),
|
||||
'changed' => array(
|
||||
'predicates' => array(
|
||||
0 => 'dc:modified',
|
||||
),
|
||||
'datatype' => 'xsd:dateTime',
|
||||
'callback' => 'date_iso8601',
|
||||
),
|
||||
'body' => array(
|
||||
'predicates' => array(
|
||||
0 => 'content:encoded',
|
||||
),
|
||||
),
|
||||
'uid' => array(
|
||||
'predicates' => array(
|
||||
0 => 'sioc:has_creator',
|
||||
),
|
||||
'type' => 'rel',
|
||||
),
|
||||
'name' => array(
|
||||
'predicates' => array(
|
||||
0 => 'foaf:name',
|
||||
),
|
||||
),
|
||||
'comment_count' => array(
|
||||
'predicates' => array(
|
||||
0 => 'sioc:num_replies',
|
||||
),
|
||||
'datatype' => 'xsd:integer',
|
||||
),
|
||||
'last_activity' => array(
|
||||
'predicates' => array(
|
||||
0 => 'sioc:last_activity_date',
|
||||
),
|
||||
'datatype' => 'xsd:dateTime',
|
||||
'callback' => 'date_iso8601',
|
||||
),
|
||||
),
|
||||
'status' => '1',
|
||||
'sticky' => '0',
|
||||
'title' => 'Lorem ipsum',
|
||||
'tnid' => '0',
|
||||
'translate' => '0',
|
||||
'type' => 'article',
|
||||
'uid' => '1',
|
||||
'uuid' => 'b0558664-c94b-3674-d9df-3e1696b2e471',
|
||||
);
|
||||
$entities['deploy_example_plan'][] = (object) array(
|
||||
'__metadata' => array(
|
||||
'type' => 'taxonomy_term',
|
||||
'uri' => 'taxonomy_term/af738a46-f278-cf84-d94d-9e03879fd71e',
|
||||
'cause' => 'node/5e3d8bbe-a1f2-f2d4-fdc0-71e6c23aa837',
|
||||
),
|
||||
'description' => NULL,
|
||||
'format' => NULL,
|
||||
'name' => 'Baz',
|
||||
'rdf_mapping' => array(
|
||||
'rdftype' => array(
|
||||
0 => 'skos:Concept',
|
||||
),
|
||||
'name' => array(
|
||||
'predicates' => array(
|
||||
0 => 'rdfs:label',
|
||||
1 => 'skos:prefLabel',
|
||||
),
|
||||
),
|
||||
'description' => array(
|
||||
'predicates' => array(
|
||||
0 => 'skos:definition',
|
||||
),
|
||||
),
|
||||
'vid' => array(
|
||||
'predicates' => array(
|
||||
0 => 'skos:inScheme',
|
||||
),
|
||||
'type' => 'rel',
|
||||
),
|
||||
'parent' => array(
|
||||
'predicates' => array(
|
||||
0 => 'skos:broader',
|
||||
),
|
||||
'type' => 'rel',
|
||||
),
|
||||
),
|
||||
'uuid' => 'af738a46-f278-cf84-d94d-9e03879fd71e',
|
||||
'vocabulary_machine_name' => 'tags',
|
||||
'weight' => '0',
|
||||
);
|
||||
$entities['deploy_example_plan'][] = (object) array(
|
||||
'__metadata' => array(
|
||||
'type' => 'user',
|
||||
'uri' => 'user/7cf875e6-dc15-4404-f190-5a7c3e91d14c',
|
||||
'cause' => 'node/5e3d8bbe-a1f2-f2d4-fdc0-71e6c23aa837',
|
||||
),
|
||||
'init' => 'no@example.com',
|
||||
'language' => '',
|
||||
'mail' => 'no@example.com',
|
||||
'name' => 'mohamed',
|
||||
'pass' => '$S$DtyVr4YQkvCpofZdLT4.L23Xb6E8HUkmEgZikN919RTZXZSePwso',
|
||||
'picture' => NULL,
|
||||
'rdf_mapping' => array(
|
||||
'rdftype' => array(
|
||||
0 => 'sioc:UserAccount',
|
||||
),
|
||||
'name' => array(
|
||||
'predicates' => array(
|
||||
0 => 'foaf:name',
|
||||
),
|
||||
),
|
||||
'homepage' => array(
|
||||
'predicates' => array(
|
||||
0 => 'foaf:page',
|
||||
),
|
||||
'type' => 'rel',
|
||||
),
|
||||
),
|
||||
'roles' => array(
|
||||
2 => 'authenticated user',
|
||||
3 => 'administrator',
|
||||
),
|
||||
'signature' => '',
|
||||
'signature_format' => 'filtered_html',
|
||||
'status' => '1',
|
||||
'theme' => '',
|
||||
'timezone' => 'Asia/Riyadh',
|
||||
'uuid' => '7cf875e6-dc15-4404-f190-5a7c3e91d14c',
|
||||
);
|
||||
$entities['deploy_example_plan'][] = (object) array(
|
||||
'__metadata' => array(
|
||||
'type' => 'node',
|
||||
'uri' => 'node/5e3d8bbe-a1f2-f2d4-fdc0-71e6c23aa837',
|
||||
'cause' => FALSE,
|
||||
),
|
||||
'body' => array(
|
||||
'und' => array(
|
||||
0 => array(
|
||||
'format' => 'filtered_html',
|
||||
'summary' => '',
|
||||
'value' => 'Nunc sollicitudin justo ut augue egestas et varius quam consectetur.',
|
||||
),
|
||||
),
|
||||
),
|
||||
'cid' => '0',
|
||||
'comment' => '2',
|
||||
'comment_count' => '0',
|
||||
'field_image' => array(),
|
||||
'field_tags' => array(
|
||||
'und' => array(
|
||||
0 => array(
|
||||
'tid' => 'af738a46-f278-cf84-d94d-9e03879fd71e',
|
||||
),
|
||||
),
|
||||
),
|
||||
'language' => 'und',
|
||||
'last_comment_name' => NULL,
|
||||
'last_comment_uid' => '7cf875e6-dc15-4404-f190-5a7c3e91d14c',
|
||||
'log' => '',
|
||||
'promote' => '1',
|
||||
'rdf_mapping' => array(
|
||||
'field_image' => array(
|
||||
'predicates' => array(
|
||||
0 => 'og:image',
|
||||
1 => 'rdfs:seeAlso',
|
||||
),
|
||||
'type' => 'rel',
|
||||
),
|
||||
'field_tags' => array(
|
||||
'predicates' => array(
|
||||
0 => 'dc:subject',
|
||||
),
|
||||
'type' => 'rel',
|
||||
),
|
||||
'rdftype' => array(
|
||||
0 => 'sioc:Item',
|
||||
1 => 'foaf:Document',
|
||||
),
|
||||
'title' => array(
|
||||
'predicates' => array(
|
||||
0 => 'dc:title',
|
||||
),
|
||||
),
|
||||
'created' => array(
|
||||
'predicates' => array(
|
||||
0 => 'dc:date',
|
||||
1 => 'dc:created',
|
||||
),
|
||||
'datatype' => 'xsd:dateTime',
|
||||
'callback' => 'date_iso8601',
|
||||
),
|
||||
'changed' => array(
|
||||
'predicates' => array(
|
||||
0 => 'dc:modified',
|
||||
),
|
||||
'datatype' => 'xsd:dateTime',
|
||||
'callback' => 'date_iso8601',
|
||||
),
|
||||
'body' => array(
|
||||
'predicates' => array(
|
||||
0 => 'content:encoded',
|
||||
),
|
||||
),
|
||||
'uid' => array(
|
||||
'predicates' => array(
|
||||
0 => 'sioc:has_creator',
|
||||
),
|
||||
'type' => 'rel',
|
||||
),
|
||||
'name' => array(
|
||||
'predicates' => array(
|
||||
0 => 'foaf:name',
|
||||
),
|
||||
),
|
||||
'comment_count' => array(
|
||||
'predicates' => array(
|
||||
0 => 'sioc:num_replies',
|
||||
),
|
||||
'datatype' => 'xsd:integer',
|
||||
),
|
||||
'last_activity' => array(
|
||||
'predicates' => array(
|
||||
0 => 'sioc:last_activity_date',
|
||||
),
|
||||
'datatype' => 'xsd:dateTime',
|
||||
'callback' => 'date_iso8601',
|
||||
),
|
||||
),
|
||||
'status' => '1',
|
||||
'sticky' => '0',
|
||||
'title' => 'Nunc sollicitudin',
|
||||
'tnid' => '0',
|
||||
'translate' => '0',
|
||||
'type' => 'article',
|
||||
'uid' => '7cf875e6-dc15-4404-f190-5a7c3e91d14c',
|
||||
'uuid' => '5e3d8bbe-a1f2-f2d4-fdc0-71e6c23aa837',
|
||||
);
|
||||
|
||||
return $entities;
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
core = "7.x"
|
||||
dependencies[] = "entity"
|
||||
dependencies[] = "features"
|
||||
dependencies[] = "uuid"
|
||||
description = "Example feature mainly used for testing."
|
||||
features[uuid_entities][] = "deploy_example_plan"
|
||||
name = "UUID default entities example"
|
||||
package = "Features"
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-09-11
|
||||
version = "7.x-1.0-alpha5+0-dev"
|
||||
core = "7.x"
|
||||
project = "uuid"
|
||||
datestamp = "1378899072"
|
||||
|
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
*/
|
||||
|
||||
// Drupal needs this blank file.
|
@@ -0,0 +1,13 @@
|
||||
name = UUID Path
|
||||
description = Provides export functionality for url aliases.
|
||||
core = 7.x
|
||||
package = UUID
|
||||
dependencies[] = uuid
|
||||
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-09-11
|
||||
version = "7.x-1.0-alpha5+0-dev"
|
||||
core = "7.x"
|
||||
project = "uuid"
|
||||
datestamp = "1378899072"
|
||||
|
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* UUID path module functions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_entity_uuid_load().
|
||||
*/
|
||||
function uuid_path_entity_uuid_load(&$entities, $entity_type) {
|
||||
_uuid_path_load_url_aliases($entities, $entity_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_uuid_save().
|
||||
*/
|
||||
function uuid_path_entity_uuid_save(&$entity, $entity_type) {
|
||||
_uuid_path_save_url_aliases($entity, $entity_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads url aliases in the corresponding entity.
|
||||
*/
|
||||
function _uuid_path_load_url_aliases(&$entities, $entity_type) {
|
||||
$info = entity_get_info($entity_type);
|
||||
// we only care about entities with URLs.
|
||||
if (!isset($info['uri callback'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$callback = $info['uri callback'];
|
||||
foreach ($entities as $id => $entity) {
|
||||
$path = $callback($entity);
|
||||
$aliases = _uuid_path_url_alias_load($path['path']);
|
||||
|
||||
// Ignore local IDs.
|
||||
foreach($aliases as &$alias) {
|
||||
unset($alias->pid);
|
||||
unset($alias->source);
|
||||
}
|
||||
|
||||
$entities[$id]->url_alias = $aliases;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the received url aliases.
|
||||
*/
|
||||
function _uuid_path_save_url_aliases(&$entity, $entity_type) {
|
||||
$info = entity_get_info($entity_type);
|
||||
|
||||
// We only care when there is a url callback
|
||||
if (!isset($info['uri callback'])) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$callback = $info['uri callback'];
|
||||
$uri = $callback($entity);
|
||||
$path = $uri['path'];
|
||||
|
||||
// Delete existing aliases.
|
||||
path_delete(array('source' => $path));
|
||||
|
||||
// Continue if aliases are present.
|
||||
if(empty($entity->url_alias)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
foreach ($entity->url_alias as $alias) {
|
||||
$entry = (array) $alias;
|
||||
$entry['source'] = $path;
|
||||
path_save($entry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all aliases associated with a path.
|
||||
*
|
||||
* @param $path
|
||||
* The source path to look up.
|
||||
*
|
||||
* @return
|
||||
* Array of paths or NULL if none found.
|
||||
*/
|
||||
function _uuid_path_url_alias_load($path) {
|
||||
return db_select('url_alias')
|
||||
->condition('source', $path)
|
||||
->fields('url_alias')
|
||||
->execute()
|
||||
->fetchAll(PDO::FETCH_OBJ);
|
||||
}
|
||||
|
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
function _field_collection_resource_definition() {
|
||||
if (module_exists('field_collection')) {
|
||||
// We will allow uuid_services_services_resources_alter() to add the
|
||||
// default UUID-related operations to this resource.
|
||||
return array('field_collection_item' => array());
|
||||
}
|
||||
else {
|
||||
return array();
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
name = UUID Services
|
||||
description = Provides integration with the Services module, like exposing a UUID entity resource.
|
||||
core = 7.x
|
||||
package = Services - resources
|
||||
|
||||
dependencies[] = services
|
||||
dependencies[] = uuid
|
||||
dependencies[] = entity
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-09-11
|
||||
version = "7.x-1.0-alpha5+0-dev"
|
||||
core = "7.x"
|
||||
project = "uuid"
|
||||
datestamp = "1378899072"
|
||||
|
@@ -0,0 +1,228 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implements hook_services_resources_alter().
|
||||
*
|
||||
* Alter all resources that support UUIDs, to make use this functionality when
|
||||
* exposing them through Services.
|
||||
*
|
||||
* Since we are working with UUID enabled entities, the 'create' method is
|
||||
* redundant. Instead, clients should do a PUT to '<entity_type>/<uuid>'. This
|
||||
* will route through the 'update' method and create the entity if it doesn't
|
||||
* exist. This is the most logical thing to do, since it's up to the client to
|
||||
* generate and set the UUID on the entity.
|
||||
*/
|
||||
function uuid_services_services_resources_alter(&$resources, &$endpoint) {
|
||||
foreach (entity_get_info() as $entity_type => $entity_info) {
|
||||
if (isset($entity_info['uuid']) && $entity_info['uuid'] == TRUE && isset($resources[$entity_type])) {
|
||||
unset($resources[$entity_type]['operations']['create']);
|
||||
|
||||
// Alter 'retrieve' method to use UUID enabled functions and arguments.
|
||||
$resources[$entity_type]['operations']['retrieve']['help'] = t('Retrieve %label entities based on UUID.', array('%label' => $entity_info['label']));
|
||||
$resources[$entity_type]['operations']['retrieve']['callback'] = '_uuid_services_entity_retrieve';
|
||||
$resources[$entity_type]['operations']['retrieve']['access callback'] = '_uuid_services_entity_access';
|
||||
$resources[$entity_type]['operations']['retrieve']['access arguments'] = array('view');
|
||||
$resources[$entity_type]['operations']['retrieve']['access arguments append'] = TRUE;
|
||||
$resources[$entity_type]['operations']['retrieve']['args'] = array(
|
||||
// This argument isn't exposed in the service, only used internally..
|
||||
array(
|
||||
'name' => 'entity_type',
|
||||
'description' => t('The entity type.'),
|
||||
'type' => 'string',
|
||||
'default value' => $entity_type,
|
||||
'optional' => TRUE,
|
||||
),
|
||||
array(
|
||||
'name' => 'uuid',
|
||||
'description' => t('The %label UUID.', array('%label' => $entity_info['label'])),
|
||||
'type' => 'text',
|
||||
'source' => array('path' => 0),
|
||||
),
|
||||
);
|
||||
|
||||
// Alter 'update' method to use UUID enabled functions and arguments.
|
||||
$resources[$entity_type]['operations']['update']['help'] = t('Update or create %label entities based on UUID. The payload must be formatted according to the <a href="!url">OData protocol</a>.', array('%label' => $entity_info['label'], '!url' => 'http://www.odata.org/developers/protocols'));
|
||||
$resources[$entity_type]['operations']['update']['callback'] = '_uuid_services_entity_update';
|
||||
$resources[$entity_type]['operations']['update']['access callback'] = '_uuid_services_entity_access';
|
||||
$resources[$entity_type]['operations']['update']['access arguments'] = array('update');
|
||||
$resources[$entity_type]['operations']['update']['access arguments append'] = TRUE;
|
||||
$resources[$entity_type]['operations']['update']['args'] = array(
|
||||
// This argument isn't exposed in the service, only used internally..
|
||||
array(
|
||||
'name' => 'entity_type',
|
||||
'description' => t('The entity type.'),
|
||||
'type' => 'string',
|
||||
'default value' => $entity_type,
|
||||
'optional' => TRUE,
|
||||
),
|
||||
array(
|
||||
'name' => 'uuid',
|
||||
'description' => t('The %label UUID.', array('%label' => $entity_info['label'])),
|
||||
'type' => 'text',
|
||||
'source' => array('path' => 0),
|
||||
),
|
||||
array(
|
||||
'name' => 'entity',
|
||||
'description' => t('The %label entity object.', array('%label' => $entity_info['label'])),
|
||||
'type' => 'struct',
|
||||
'source' => 'data',
|
||||
),
|
||||
);
|
||||
|
||||
// Alter 'delete' method to use UUID enabled functions and arguments.
|
||||
$resources[$entity_type]['operations']['delete']['help'] = t('Delete %label entities based on UUID.', array('%label' => $entity_info['label']));
|
||||
$resources[$entity_type]['operations']['delete']['callback'] = '_uuid_services_entity_delete';
|
||||
$resources[$entity_type]['operations']['delete']['access callback'] = '_uuid_services_entity_access';
|
||||
$resources[$entity_type]['operations']['delete']['access arguments'] = array('delete');
|
||||
$resources[$entity_type]['operations']['delete']['access arguments append'] = TRUE;
|
||||
$resources[$entity_type]['operations']['delete']['args'] = array(
|
||||
// This argument isn't exposed in the service, only used internally..
|
||||
array(
|
||||
'name' => 'entity_type',
|
||||
'description' => t('The entity type.'),
|
||||
'type' => 'string',
|
||||
'default value' => $entity_type,
|
||||
'optional' => TRUE,
|
||||
),
|
||||
array(
|
||||
'name' => 'uuid',
|
||||
'description' => t('The %label UUID.', array('%label' => $entity_info['label'])),
|
||||
'type' => 'text',
|
||||
'source' => array('path' => 0),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the 'retrieve' method.
|
||||
*
|
||||
* @see entity_uuid_load()
|
||||
*/
|
||||
function _uuid_services_entity_retrieve($entity_type, $uuid) {
|
||||
try {
|
||||
$entities = entity_uuid_load($entity_type, array($uuid));
|
||||
$entity = reset($entities);
|
||||
return $entity;
|
||||
}
|
||||
catch (Exception $exception) {
|
||||
watchdog_exception('uuid_services', $exception);
|
||||
return services_error($exception, 406, $uuid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the 'update' method.
|
||||
*
|
||||
* @see entity_uuid_save()
|
||||
*/
|
||||
function _uuid_services_entity_update($entity_type, $uuid, $entity) {
|
||||
try {
|
||||
$controller = entity_get_controller($entity_type);
|
||||
if ($controller instanceof EntityAPIControllerInterface) {
|
||||
$entity = $controller->create($entity);
|
||||
}
|
||||
else {
|
||||
$entity = (object) $entity;
|
||||
}
|
||||
entity_uuid_save($entity_type, $entity);
|
||||
return $entity;
|
||||
}
|
||||
catch (Exception $exception) {
|
||||
watchdog_exception('uuid_services', $exception);
|
||||
return services_error($exception, 406, $entity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the 'delete' method.
|
||||
*
|
||||
* @see entity_uuid_delete()
|
||||
*/
|
||||
function _uuid_services_entity_delete($entity_type, $uuid) {
|
||||
try {
|
||||
$return = entity_uuid_delete($entity_type, array($uuid));
|
||||
return $return;
|
||||
}
|
||||
catch (Exception $exception) {
|
||||
watchdog_exception('uuid_services', $exception);
|
||||
return services_error($exception, 406, $uuid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Access callback.
|
||||
*
|
||||
* @param $op
|
||||
* The operation we are trying to do on the entity. Can only be:
|
||||
* - "view"
|
||||
* - "update"
|
||||
* - "delete"
|
||||
* See 'uuid_services_services_resources_alter()' for an explanation why
|
||||
* 'create' is missing.
|
||||
* @param $args
|
||||
* The arguments passed to the method. The keys are holding the following:
|
||||
* 0. <entity_type>
|
||||
* 1. <uuid>
|
||||
* 2. <entity> (only available if $op == 'update')
|
||||
*/
|
||||
function _uuid_services_entity_access($op, $args) {
|
||||
try {
|
||||
// Fetch the information we have to work with.
|
||||
$entity_type = $args[0];
|
||||
// Load functions always deal with multiple entities. So does this lookup
|
||||
// function. But in practice this will always only be one id.
|
||||
$entity_ids = entity_get_id_by_uuid($entity_type, array($args[1]));
|
||||
$entity = NULL;
|
||||
if (!empty($args[2])) {
|
||||
$entity = entity_create($entity_type, $args[2]);
|
||||
// We have to make the entity local (i.e. only have local references), for
|
||||
// access functions to work on it.
|
||||
entity_make_entity_local($entity_type, $entity);
|
||||
}
|
||||
// Fetch the local entity if we've got an id.
|
||||
elseif (!empty($entity_ids)) {
|
||||
$entities = entity_load($entity_type, $entity_ids);
|
||||
$entity = reset($entities);
|
||||
}
|
||||
|
||||
// If we've been routed to the 'update' method and the entity we are
|
||||
// operating on doesn't exist yet, that should be reflected.
|
||||
if ($op == 'update' && empty($entity_ids)) {
|
||||
$op = 'create';
|
||||
}
|
||||
// Taxonomy and Comment module uses 'edit' instead of 'update'.
|
||||
// Oh, how I love Drupal consistency.
|
||||
if (($entity_type == 'taxonomy_term' || $entity_type == 'comment') && $op == 'update') {
|
||||
$op = 'edit';
|
||||
}
|
||||
// The following code is taken from entity_access() with some extra logic
|
||||
// to handle the case where an entity type is not defining an access
|
||||
// callback. With this logic, it's important that all entity types that
|
||||
// needs access control have an access callback defined.
|
||||
if (($info = entity_get_info()) && isset($info[$entity_type]['access callback'])) {
|
||||
return $info[$entity_type]['access callback']($op, $entity, NULL, $entity_type);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
catch (Exception $exception) {
|
||||
watchdog_exception('uuid_services', $exception);
|
||||
return services_error($exception, 406, $entity_type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_services_resources().
|
||||
*/
|
||||
function uuid_services_services_resources() {
|
||||
module_load_include('inc', 'uuid_services', 'resources/field_collection.resource');
|
||||
|
||||
$resources = array(
|
||||
'#api_version' => 3002,
|
||||
);
|
||||
|
||||
$resources += _field_collection_resource_definition();
|
||||
|
||||
return $resources;
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* uuid_services_example.features.inc
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_ctools_plugin_api().
|
||||
*/
|
||||
function uuid_services_example_ctools_plugin_api() {
|
||||
list($module, $api) = func_get_args();
|
||||
if ($module == "services" && $api == "services") {
|
||||
return array("version" => "3");
|
||||
}
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
name = UUID Services Example
|
||||
description = Example feature of a UUID service. Works well with the Deploy Example feature as a client.
|
||||
core = 7.x
|
||||
package = Features
|
||||
php = 5.2.4
|
||||
dependencies[] = rest_server
|
||||
dependencies[] = services
|
||||
dependencies[] = uuid
|
||||
dependencies[] = uuid_services
|
||||
features[ctools][] = services:services:3
|
||||
features[features_api][] = api:2
|
||||
features[services_endpoint][] = uuid_services_example
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-09-11
|
||||
version = "7.x-1.0-alpha5+0-dev"
|
||||
core = "7.x"
|
||||
project = "uuid"
|
||||
datestamp = "1378899072"
|
||||
|
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Code for the UUID Services Example feature.
|
||||
*/
|
||||
|
||||
include_once('uuid_services_example.features.inc');
|
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* uuid_services_example.services.inc
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_default_services_endpoint().
|
||||
*/
|
||||
function uuid_services_example_default_services_endpoint() {
|
||||
$export = array();
|
||||
|
||||
$endpoint = new stdClass();
|
||||
$endpoint->disabled = FALSE; /* Edit this to true to make a default endpoint disabled initially */
|
||||
$endpoint->api_version = 3;
|
||||
$endpoint->name = 'uuid_services_example';
|
||||
$endpoint->server = 'rest_server';
|
||||
$endpoint->path = 'api';
|
||||
$endpoint->authentication = array(
|
||||
'services' => 'services',
|
||||
);
|
||||
$endpoint->server_settings = array(
|
||||
'formatters' => array(
|
||||
'json' => TRUE,
|
||||
'bencode' => FALSE,
|
||||
'jsonp' => FALSE,
|
||||
'php' => FALSE,
|
||||
'xml' => FALSE,
|
||||
'yaml' => FALSE,
|
||||
),
|
||||
'parsers' => array(
|
||||
'application/json' => TRUE,
|
||||
'application/x-www-form-urlencoded' => TRUE,
|
||||
'multipart/form-data' => TRUE,
|
||||
'application/vnd.php.serialized' => FALSE,
|
||||
'application/x-yaml' => FALSE,
|
||||
'application/xml' => FALSE,
|
||||
'text/xml' => FALSE,
|
||||
),
|
||||
);
|
||||
$endpoint->resources = array(
|
||||
'comment' => array(
|
||||
'operations' => array(
|
||||
'update' => array(
|
||||
'enabled' => '1',
|
||||
),
|
||||
),
|
||||
),
|
||||
'file' => array(
|
||||
'operations' => array(
|
||||
'update' => array(
|
||||
'enabled' => '1',
|
||||
),
|
||||
),
|
||||
),
|
||||
'node' => array(
|
||||
'operations' => array(
|
||||
'update' => array(
|
||||
'enabled' => '1',
|
||||
),
|
||||
),
|
||||
),
|
||||
'taxonomy_term' => array(
|
||||
'operations' => array(
|
||||
'update' => array(
|
||||
'enabled' => '1',
|
||||
),
|
||||
),
|
||||
),
|
||||
'user' => array(
|
||||
'operations' => array(
|
||||
'update' => array(
|
||||
'enabled' => '1',
|
||||
),
|
||||
),
|
||||
'actions' => array(
|
||||
'login' => array(
|
||||
'enabled' => '1',
|
||||
'settings' => array(
|
||||
'services' => array(
|
||||
'resource_api_version' => '1.0',
|
||||
),
|
||||
),
|
||||
),
|
||||
'logout' => array(
|
||||
'enabled' => '1',
|
||||
'settings' => array(
|
||||
'services' => array(
|
||||
'resource_api_version' => '1.0',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
$endpoint->debug = 1;
|
||||
$export['uuid_services_example'] = $endpoint;
|
||||
|
||||
return $export;
|
||||
}
|
Reference in New Issue
Block a user