Showroom feature
This commit is contained in:
parent
e8cadc31e1
commit
7abf64be00
@ -0,0 +1,76 @@
|
||||
For complete changelog, see:
|
||||
http://drupalcode.org/project/taxonomy_access.git/log/refs/heads/7.x-1.x
|
||||
|
||||
Taxonomy Access 7.x-1.x-dev, xxxx-xx-xx
|
||||
---------------------------------------
|
||||
|
||||
Taxonomy Access 7.x-1.0, 2015-09-18
|
||||
---------------------------------------
|
||||
o The return value of taxonomy_access_global_defaults() has changed. Callers
|
||||
may use _taxonomy_access_format_grant_record() to format each element of the
|
||||
return array for hook_node_access_records().
|
||||
|
||||
o The following constants have been added:
|
||||
- TAXONOMY_ACCESS_GLOBAL_DEFAULT = 0
|
||||
- TAXONOMY_ACCESS_VOCABULARY_DEFAULT = 0
|
||||
- TAXONOMY_ACCESS_NODE_ALLOW = 1
|
||||
- TAXONOMY_ACCESS_NODE_IGNORE = 0
|
||||
- TAXONOMY_ACCESS_NODE_DENY = 2
|
||||
- TAXONOMY_ACCESS_GLOBAL_DEFAULT = 0
|
||||
- TAXONOMY_ACCESS_GLOBAL_DEFAULT = 0
|
||||
|
||||
o Drupal core 7.8 is now explicitly required.
|
||||
|
||||
o The "Add tag" (create) grant now defaults to "Allow" for anonymous and
|
||||
authenticated users upon installation. (Existing installations will not be
|
||||
affected.)
|
||||
|
||||
Taxonomy Access 7.x-1.x-rc1, 2011-09-09
|
||||
---------------------------------------
|
||||
o Administrative paths have changed.
|
||||
|
||||
o Renamed grant realm from 'term_access' to 'taxonomy_access_role'.
|
||||
|
||||
o Field widgets are now automatically hidden if the user cannot add any terms.
|
||||
|
||||
o The vocabulary default for the "Add tag" grant (create op) now controls
|
||||
whether new terms can be created in the vocabulary in autocomplete fields.
|
||||
|
||||
o Moved "Add tag" (create op) functionality from hook_form_alter() to
|
||||
hook_field_widget_form_alter().
|
||||
|
||||
o Terms disallowed by "Add tag" (create op) are disabled rather than removed.
|
||||
This may be a configurable setting in the future.
|
||||
|
||||
o "Add tag" (create op) now allows selection of allowed child terms when
|
||||
the parent term is disabled.
|
||||
|
||||
o Optimized grant update functionality to reduce queries.
|
||||
|
||||
o Renamed several API functions:
|
||||
|
||||
- from: taxonomy_access_grant_update()
|
||||
to: taxonomy_access_set_term_grants()
|
||||
|
||||
- from: taxonomy_access_defaults_update()
|
||||
to: taxonomy_access_set_default_grants()
|
||||
|
||||
- form: taxonomy_access_recursive_grant_update()
|
||||
to: taxonomy_access_set_recursive_grants()
|
||||
|
||||
- from: taxonomy_access_delete_roles()
|
||||
to: taxonomy_access_delete_role_grants()
|
||||
|
||||
- from: taxonomy_access_delete_terms()
|
||||
to: taxonomy_access_delete_term_grants()
|
||||
|
||||
- from: taxonomy_access_delete_defaults()
|
||||
to: taxonomy_access_delete_default_grants()
|
||||
|
||||
o Renamed "List" and "Create" grants to "View tag" and "Add tag" for clarity.
|
||||
|
||||
o Automatically update node access as needed on shutdown.
|
||||
Hooks should merely add their list of nodes to
|
||||
taxonomy_access_affected_nodes() to be processed at the end of the request.
|
||||
|
||||
o Provide record deletion API.
|
@ -0,0 +1,50 @@
|
||||
TO INSTALL, simply install and enable the module, in these steps.
|
||||
|
||||
PLEASE CHECK that you use the right version of Taxonomy Access for your
|
||||
version of DRUPAL.
|
||||
|
||||
IMPORTANT: This is a complicated module. When you first learn to use this
|
||||
module, ALWAYS TRY IT FIRST ON A TEST SITE.
|
||||
|
||||
NOTE: If you want to USE TWO OR MORE "ACCESS" MODULES AT THE SAME TIME, TEST
|
||||
THEM CAREFULLY. (e.g: OG, node_privacy_by_role, taxonomy access, etc.)
|
||||
|
||||
TO UPDATE from previous versions of taxonomy_access: PLEASE READ UPDATE.TXT!
|
||||
WHEN UPDATING, ALWAYS disable the module first before uploading the new
|
||||
module, on the page:
|
||||
"Administration >> Modules"
|
||||
(http://www.example.com/admin/modules).
|
||||
|
||||
-----------------------
|
||||
INSTALLATION
|
||||
-----------------------
|
||||
|
||||
1. COPY the taxonomy_access directory to your Drupal
|
||||
installation's module directory.
|
||||
(By default: sites/all/modules/taxonomy_access/ in your Drupal directory.)
|
||||
|
||||
2. ENABLE THE MODULE on page:
|
||||
"Administration >> Modules"
|
||||
(http://www.example.com/admin/modules).
|
||||
|
||||
3. REBUILD YOUR NODE ACCESS PERMISSIONS on page:
|
||||
"Administration >> Reports >> Status report >> Node Access Permissions"
|
||||
(http://www.example.com/admin/reports/status/rebuild).
|
||||
|
||||
4. GRANT ADMINISTRATORS CONTROL of Taxonomy Access on page:
|
||||
"Administration >> People >> Permissions"
|
||||
(http://www.example.com/admin/people/permissions).
|
||||
|
||||
To administer Taxonomy Access, administrators must have "access
|
||||
administration pages" checked (under "system module") and "administer
|
||||
permissions" checked (under "user module").
|
||||
|
||||
5. CONFIGURE ACCESS GRANTS to the various categories at:
|
||||
"Administration >> Configuration >> Taxonomy access control"
|
||||
(http://www.example.com/admin/config/people/taxonomy_access).
|
||||
|
||||
Be sure to configure the authenticated role, as users with custom roles
|
||||
also have the authenticated user role.
|
||||
|
||||
NOTE: DATABASE TABLES are automatically added to database. Module creates two
|
||||
database tables: 'taxonomy_access_term' and 'taxonomy_access_default'.
|
339
sites/all/modules/contrib/taxonomy/taxonomy_access/LICENSE.txt
Normal file
339
sites/all/modules/contrib/taxonomy/taxonomy_access/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.
|
106
sites/all/modules/contrib/taxonomy/taxonomy_access/README.txt
Normal file
106
sites/all/modules/contrib/taxonomy/taxonomy_access/README.txt
Normal file
@ -0,0 +1,106 @@
|
||||
-----------------------
|
||||
GENERAL DESCRIPTION
|
||||
-----------------------
|
||||
This module allows you to set access permissions for various taxonomy
|
||||
categories based on user role.
|
||||
|
||||
There are permissions to VIEW, UPDATE, and DELETE nodes in each category.
|
||||
Additionally, the ADD TAG permission control whether the user can add a
|
||||
taxonomy term to a node, and the VIEW TAG permission controls whether the user
|
||||
can see the taxonomy term listed on the node.
|
||||
|
||||
|
||||
-----------------------
|
||||
HELP PAGES
|
||||
-----------------------
|
||||
For more information about how to control access permissions with the Taxonomy
|
||||
access control module (TAC), see the module's help page at:
|
||||
"Administration >> Help >> Taxonomy access control"
|
||||
(admin/help/taxonomy_access).
|
||||
|
||||
Also see the help pages at drupal.org: http://drupal.org/node/31601
|
||||
|
||||
|
||||
-----------------------
|
||||
DATABASE TABLES
|
||||
-----------------------
|
||||
Module creates two tables in database: 'taxonomy_access_term' and
|
||||
'taxonomy_access_default'
|
||||
|
||||
|
||||
-----------------------
|
||||
TROUBLESHOOTING
|
||||
-----------------------
|
||||
|
||||
If users can view or edit pages that they do not have permission for:
|
||||
|
||||
1. Make sure the user role does not have "administer nodes" permission. This
|
||||
permission will override any settings from Taxonomy Access.
|
||||
|
||||
2. Check whether the user role has "edit any [type] content" permissions
|
||||
under "node module" on the page:
|
||||
"Administration >> People >> Permissions"
|
||||
(http://www.example.com/admin/people/permissions).
|
||||
|
||||
Granting this permission overrides TAC's "Update" permissions for the given
|
||||
content type, so you will not be able to deny the role edit access to any
|
||||
nodes in that type. (The same is true of "delete any [type] content"
|
||||
permissions.)
|
||||
|
||||
3. Check to see if the user has other roles that may be granting other
|
||||
permissions. Remember: Deny overrides Allow within a role, but Allow from
|
||||
one role can override Deny from another.
|
||||
|
||||
4. Review the configuration for the authenticated user role on page:
|
||||
"Administration >> People >> Permissions"
|
||||
(http://www.example.com/admin/people/permissions).
|
||||
|
||||
Remember that users with custom roles also have the authenticated role, so
|
||||
they gain any permissions granted that role.
|
||||
|
||||
5. Check whether you have ANY OTHER node access modules installed.
|
||||
Other modules can override TAC's grants.
|
||||
|
||||
6. Do a General Database Housekeeping
|
||||
(Tables: 'node_access','taxonomy_access_term' and 'taxonomy_access_default'):
|
||||
|
||||
First DISABLE, then RE-ENABLE the Taxonomy access module on page:
|
||||
"Administration >> Modules"
|
||||
(http://www.example.com/admin/modules).
|
||||
|
||||
This will force the complete rebuild of the 'node_access' table.
|
||||
|
||||
7. For debugging, install devel_node_access module (Devel project).
|
||||
This can show you some information about node_access values in
|
||||
the database when viewing a node page.
|
||||
|
||||
8. Force rebuilding of the permissions cache (table 'node_access'):
|
||||
"Rebuild permissions" button on page:
|
||||
"Administration >> Reports >> Status report >> Node Access Permissions"
|
||||
(http://www.example.com/admin/reports/status/rebuild).
|
||||
|
||||
If the site is experiencing problems with permissions to content, you may
|
||||
have to rebuild the permissions cache. Possible causes for permission
|
||||
problems are disabling modules or configuration changes to permissions.
|
||||
Rebuilding will remove all privileges to posts, and replace them with
|
||||
permissions based on the current modules and settings.
|
||||
|
||||
-----------------------
|
||||
UNINSTALLING
|
||||
-----------------------
|
||||
|
||||
1. First DISABLE the Taxonomy access module on page:
|
||||
"Administration >> Modules"
|
||||
(http://www.example.com/admin/modules).
|
||||
|
||||
2. After disabling, you can uninstall completely by choosing Taxonomy
|
||||
Access on page:
|
||||
"Administration >> Modules >> Uninstall"
|
||||
(http://www.example.com/admin/modules/uninstall).
|
||||
|
||||
This will remove all your settings of Taxonomy Access: variables and tables
|
||||
('taxonomy_access_term' and 'taxonomy_access_default').
|
||||
|
||||
3. After uninstalling, if the site is experiencing problems with permissions to
|
||||
content, you can rebuild the permission cache.
|
||||
See "Troubleshooting" #8.
|
@ -0,0 +1,29 @@
|
||||
READ THIS FILE if you are updating from previous versions of
|
||||
'taxonomy_access.module'.
|
||||
|
||||
If you are installing taxonomy_access.module for the first time, you may ignore
|
||||
this file.
|
||||
|
||||
-----------------------
|
||||
UPDATING
|
||||
-----------------------
|
||||
|
||||
1. DISABLE THE MODULE on page:
|
||||
"Administration >> Modules"
|
||||
(http://www.example.com/admin/modules).
|
||||
|
||||
2. BACK UP your database.
|
||||
|
||||
3. COPY the new taxonomy_access directory over the existing module directory
|
||||
(By default: sites/all/modules/taxonomy_access/ in your Drupal directory.)
|
||||
|
||||
4. LOG IN AS MAIN ADMINISTRATOR (user with user ID 1).
|
||||
|
||||
5. ENABLE THE MODULE on page:
|
||||
"Administration >> Modules"
|
||||
(http://www.example.com/admin/modules).
|
||||
|
||||
6. RUN UPDATE.PHP by visiting:
|
||||
http://www.example.com/update.php
|
||||
|
||||
7. TEST YOUR SITE'S ACCESS CONTROL. If there are problems, see the README.txt.
|
Binary file not shown.
After Width: | Height: | Size: 160 B |
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Disable disallowed terms in taxonomy fields, and re-enable on submit.
|
||||
*
|
||||
* We do this in jQuery because FAPI does not yet support it:
|
||||
* @see
|
||||
* http://drupal.org/node/284917
|
||||
* @see
|
||||
* http://drupal.org/node/342316
|
||||
*
|
||||
* @todo
|
||||
* Use clearer coding standards.
|
||||
* @see
|
||||
* http://jsdemystified.drupalgardens.com/
|
||||
*/
|
||||
Drupal.behaviors.tac_create = {};
|
||||
Drupal.behaviors.tac_create.attach = function(context, settings) {
|
||||
var $ = jQuery;
|
||||
var $fields = $(Drupal.settings.taxonomy_access);
|
||||
|
||||
// For each controlled field, disable disallowed terms.
|
||||
$.each($fields, function(i, field) {
|
||||
var fieldname = "." + field.field;
|
||||
|
||||
// Disable disallowed term and its label, if any.
|
||||
$.each(field.disallowed_tids, function(j, tid) {
|
||||
|
||||
// Children of the widget element with the specified tid as a value.
|
||||
// Can be either <option> or <input>.
|
||||
// .tac_fieldname [value='1']
|
||||
selector = fieldname + " [value='" + tid + "']";
|
||||
$(selector).attr('disabled','disabled');
|
||||
|
||||
// Label sibling adjacent the child element.
|
||||
// .tac_fieldname [value='1'] + label
|
||||
label_selector = fieldname + " [value='" + tid + "']" + " + label";
|
||||
$(label_selector).attr('class','option disabled');
|
||||
});
|
||||
});
|
||||
|
||||
// Re-enable and re-select disallowed defaults on submit.
|
||||
$("form").submit(function() {
|
||||
|
||||
// For each controlled field, re-enable disallowed terms.
|
||||
$.each($fields, function(i, field) {
|
||||
var fieldname = "." + field.field;
|
||||
|
||||
// Enable and select disallowed defaults.
|
||||
$.each(field.disallowed_defaults, function(j, tid) {
|
||||
|
||||
// Children of the widget element with the specified tid as a value.
|
||||
// Can be either <option> or <input>.
|
||||
// .tac_fieldname [value='1']
|
||||
selector = fieldname + " [value='" + tid + "']";
|
||||
$(selector).attr('disabled','');
|
||||
$(selector).attr('selected','selected');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}
|
@ -0,0 +1,910 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Administrative interface for taxonomy access control.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Page callback: Renders the TAC permissions administration overview page.
|
||||
*
|
||||
* @return
|
||||
* Form to render.
|
||||
*
|
||||
* @see taxonomy_access_menu()
|
||||
*/
|
||||
function taxonomy_access_admin() {
|
||||
$roles = _taxonomy_access_user_roles();
|
||||
$active_rids = db_query(
|
||||
'SELECT rid FROM {taxonomy_access_default} WHERE vid = :vid',
|
||||
array(':vid' => TAXONOMY_ACCESS_GLOBAL_DEFAULT)
|
||||
)->fetchCol();
|
||||
|
||||
$header = array(t('Role'), t('Status'), t('Operations'));
|
||||
$rows = array();
|
||||
|
||||
foreach ($roles as $rid => $name) {
|
||||
$row = array();
|
||||
$row[] = $name;
|
||||
|
||||
if (in_array($rid, $active_rids)) {
|
||||
// Add edit operation link for active roles.
|
||||
$row[] = array('data' => t('Enabled'));
|
||||
|
||||
}
|
||||
else {
|
||||
// Add enable link for unconfigured roles.
|
||||
$row[] = array('data' => t('Disabled'));
|
||||
}
|
||||
$row[] = array('data' => l(
|
||||
t("Configure"),
|
||||
TAXONOMY_ACCESS_CONFIG . "/role/$rid/edit",
|
||||
array('attributes' => array('class' => array('module-link', 'module-link-configure')))));
|
||||
$rows[] = $row;
|
||||
}
|
||||
|
||||
$build['role_table'] = array(
|
||||
'#theme' => 'table',
|
||||
'#header' => $header,
|
||||
'#rows' => $rows,
|
||||
);
|
||||
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Form constructor for a form to to delete access rules for a particular role.
|
||||
*
|
||||
* @param int $rid
|
||||
* The role ID to disable.
|
||||
*
|
||||
* @see taxonomy_access_role_delete_confirm_submit()
|
||||
* @see taxonomy_access_menu()
|
||||
* @ingroup forms
|
||||
*/
|
||||
function taxonomy_access_role_delete_confirm($form, &$form_state, $rid) {
|
||||
$roles = _taxonomy_access_user_roles();
|
||||
if (taxonomy_access_role_enabled($rid)) {
|
||||
$form['rid'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $rid,
|
||||
);
|
||||
return confirm_form($form,
|
||||
t("Are you sure you want to delete all taxonomy access rules for the role %role?",
|
||||
array('%role' => $roles[$rid])),
|
||||
TAXONOMY_ACCESS_CONFIG . '/role/%/edit',
|
||||
t('This action cannot be undone.'),
|
||||
t('Delete all'),
|
||||
t('Cancel'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Form submission handler for taxonomy_role_delete_confirm().
|
||||
*/
|
||||
function taxonomy_access_role_delete_confirm_submit($form, &$form_state) {
|
||||
$roles = _taxonomy_access_user_roles();
|
||||
$rid = $form_state['values']['rid'];
|
||||
if (is_numeric($rid)
|
||||
&& $rid != DRUPAL_ANONYMOUS_RID
|
||||
&& $rid != DRUPAL_AUTHENTICATED_RID) {
|
||||
if ($form_state['values']['confirm']) {
|
||||
$form_state['redirect'] = TAXONOMY_ACCESS_CONFIG;
|
||||
taxonomy_access_delete_role_grants($rid);
|
||||
drupal_set_message(t('All taxonomy access rules deleted for role %role.',
|
||||
array('%role' => $roles[$rid])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a URL to enable a role with a token for CSRF protection.
|
||||
*
|
||||
* @param int $rid
|
||||
* The role ID.
|
||||
*
|
||||
* @return string
|
||||
* The full URL for the request path.
|
||||
*/
|
||||
function taxonomy_access_enable_role_url($rid) {
|
||||
// Create a query array with a token to validate the sumbission.
|
||||
$query = drupal_get_destination();
|
||||
$query['token'] = drupal_get_token($rid);
|
||||
|
||||
// Build and return the URL with the token and destination.
|
||||
return url(
|
||||
TAXONOMY_ACCESS_CONFIG . "/role/$rid/enable",
|
||||
array('query' => $query)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Page callback: Enables a role if the proper token is provided.
|
||||
*
|
||||
* @param int $rid
|
||||
* The role ID.
|
||||
*/
|
||||
function taxonomy_access_enable_role_validate($rid) {
|
||||
$rid = intval($rid);
|
||||
// If a valid token is not provided, return a 403.
|
||||
$query = drupal_get_query_parameters();
|
||||
if (empty($query['token']) || !drupal_valid_token($query['token'], $rid)) {
|
||||
return MENU_ACCESS_DENIED;
|
||||
}
|
||||
// Return a 404 for the anonymous or authenticated roles.
|
||||
if (in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
|
||||
return MENU_NOT_FOUND;
|
||||
}
|
||||
// Return a 404 for invalid role IDs.
|
||||
$roles = _taxonomy_access_user_roles();
|
||||
if (empty($roles[$rid])) {
|
||||
return MENU_NOT_FOUND;
|
||||
}
|
||||
|
||||
// If the parameters pass validation, enable the role and complete redirect.
|
||||
if (taxonomy_access_enable_role($rid)) {
|
||||
drupal_set_message(t('Role %name enabled successfully.',
|
||||
array('%name' => $roles[$rid])));
|
||||
}
|
||||
drupal_goto();
|
||||
}
|
||||
|
||||
/**
|
||||
* Form constructor for a form to manage grants by role.
|
||||
*
|
||||
* @param int $rid
|
||||
* The role ID.
|
||||
*
|
||||
* @see taxonomy_access_admin_form_submit()
|
||||
* @see taxonomy_access_menu()
|
||||
* @ingroup forms
|
||||
*/
|
||||
function taxonomy_access_admin_role($form, $form_state, $rid) {
|
||||
// Always include the role ID in the form.
|
||||
$rid = intval($rid);
|
||||
$form['rid'] = array('#type' => 'value', '#value' => $rid);
|
||||
|
||||
// For custom roles, allow the user to enable or disable grants for the role.
|
||||
if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
|
||||
$roles = _taxonomy_access_user_roles();
|
||||
|
||||
// If the role is not enabled, return only a link to enable it.
|
||||
if (!taxonomy_access_role_enabled($rid)) {
|
||||
$form['status'] = array(
|
||||
'#markup' => '<p>' . t(
|
||||
'Access control for the %name role is disabled. <a href="@url">Enable @name</a>.',
|
||||
array(
|
||||
'%name' => $roles[$rid],
|
||||
'@name' => $roles[$rid],
|
||||
'@url' => taxonomy_access_enable_role_url($rid))) . '</p>'
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
// Otherwise, add a link to disable and build the rest of the form.
|
||||
else {
|
||||
$disable_url = url(
|
||||
TAXONOMY_ACCESS_CONFIG . "/role/$rid/delete",
|
||||
array('query' => drupal_get_destination())
|
||||
);
|
||||
$form['status'] = array(
|
||||
'#markup' => '<p>' . t(
|
||||
'Access control for the %name role is enabled. <a href="@url">Disable @name</a>.',
|
||||
array('@name' => $roles[$rid], '%name' => $roles[$rid], '@url' => $disable_url)) . '</p>'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve role grants and display an administration form.
|
||||
// Disable list filtering while preparing this form.
|
||||
taxonomy_access_disable_list();
|
||||
|
||||
// Fetch all grants for the role.
|
||||
$defaults =
|
||||
db_query(
|
||||
'SELECT vid, grant_view, grant_update, grant_delete, grant_create,
|
||||
grant_list
|
||||
FROM {taxonomy_access_default}
|
||||
WHERE rid = :rid',
|
||||
array(':rid' => $rid))
|
||||
->fetchAllAssoc('vid', PDO::FETCH_ASSOC);
|
||||
|
||||
$records =
|
||||
db_query(
|
||||
'SELECT ta.tid, td.vid, ta.grant_view, ta.grant_update, ta.grant_delete,
|
||||
ta.grant_create, ta.grant_list
|
||||
FROM {taxonomy_access_term} ta
|
||||
INNER JOIN {taxonomy_term_data} td ON ta.tid = td.tid
|
||||
WHERE rid = :rid',
|
||||
array(':rid' => $rid))
|
||||
->fetchAllAssoc('tid', PDO::FETCH_ASSOC);
|
||||
$term_grants = array();
|
||||
foreach ($records as $record) {
|
||||
$term_grants[$record['vid']][$record['tid']] = $record;
|
||||
}
|
||||
|
||||
// Add a fieldset for the global default.
|
||||
$form['global_default'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Global default'),
|
||||
'#description' => t('The global default controls access to untagged nodes. It is also used as the default for disabled vocabularies.'),
|
||||
'#collapsible' => TRUE,
|
||||
// Collapse if there are vocabularies configured.
|
||||
'#collapsed' => (sizeof($defaults) > 1),
|
||||
);
|
||||
// Print term grant table.
|
||||
$form['global_default']['grants'] = taxonomy_access_grant_add_table($defaults[TAXONOMY_ACCESS_GLOBAL_DEFAULT], TAXONOMY_ACCESS_VOCABULARY_DEFAULT);
|
||||
|
||||
// Fetch all vocabularies and determine which are enabled for the role.
|
||||
$vocabs = array();
|
||||
$disabled = array();
|
||||
foreach (taxonomy_get_vocabularies() as $vocab) {
|
||||
$vocabs[$vocab->vid] = $vocab;
|
||||
if (!isset($defaults[$vocab->vid])) {
|
||||
$disabled[$vocab->vid] = $vocab->name;
|
||||
}
|
||||
}
|
||||
|
||||
// Add a fieldset to enable vocabularies.
|
||||
if (!empty($disabled)) {
|
||||
$form['enable_vocabs'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => TRUE,
|
||||
'#title' => t('Add vocabulary'),
|
||||
'#attributes' => array('class' => array('container-inline', 'taxonomy-access-add')),
|
||||
);
|
||||
$form['enable_vocabs']['enable_vocab'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Vocabulary'),
|
||||
'#options' => $disabled,
|
||||
);
|
||||
$form['enable_vocabs']['add'] = array(
|
||||
'#type' => 'submit',
|
||||
'#submit' => array('taxonomy_access_enable_vocab_submit'),
|
||||
'#value' => t('Add'),
|
||||
);
|
||||
}
|
||||
|
||||
// Add a fieldset for each enabled vocabulary.
|
||||
foreach ($defaults as $vid => $vocab_default) {
|
||||
if (!empty($vocabs[$vid])) {
|
||||
$vocab = $vocabs[$vid];
|
||||
$name = $vocab->machine_name;
|
||||
|
||||
// Fetch unconfigured terms and reorder term records by hierarchy.
|
||||
$sort = array();
|
||||
$add_options = array();
|
||||
if ($tree = taxonomy_get_tree($vid)) {
|
||||
foreach ($tree as $term) {
|
||||
if (empty($term_grants[$vid][$term->tid])) {
|
||||
$add_options["term $term->tid"] = str_repeat('-', $term->depth) . ' ' .check_plain($term->name);
|
||||
}
|
||||
else {
|
||||
$sort[$term->tid] = $term_grants[$vid][$term->tid];
|
||||
$sort[$term->tid]['name'] = str_repeat('-', $term->depth) . ' ' . check_plain($term->name);
|
||||
}
|
||||
}
|
||||
$term_grants[$vid] = $sort;
|
||||
}
|
||||
|
||||
$grants = array(TAXONOMY_ACCESS_VOCABULARY_DEFAULT => $vocab_default);
|
||||
$grants[TAXONOMY_ACCESS_VOCABULARY_DEFAULT]['name'] = t('Default');
|
||||
if (!empty($term_grants[$vid])) {
|
||||
$grants += $term_grants[$vid];
|
||||
}
|
||||
$form[$name] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => $vocab->name,
|
||||
'#attributes' => array('class' => array('taxonomy-access-vocab')),
|
||||
'#description' => t('The default settings apply to all terms in %vocab that do not have their own below.', array('%vocab' => $vocab->name)),
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => FALSE,
|
||||
);
|
||||
// Term grant table.
|
||||
$form[$name]['grants'] =
|
||||
taxonomy_access_grant_table($grants, $vocab->vid, t('Term'), !empty($term_grants[$vid]));
|
||||
// Fieldset to add a new term if there are any.
|
||||
if (!empty($add_options)) {
|
||||
$form[$name]['new'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => TRUE,
|
||||
'#title' => t('Add term'),
|
||||
'#tree' => TRUE,
|
||||
'#attributes' => array('class' => array('container-inline', 'taxonomy-access-add')),
|
||||
);
|
||||
$form[$name]['new'][$vid]['item'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Term'),
|
||||
'#options' => $add_options,
|
||||
);
|
||||
$form[$name]['new'][$vid]['recursive'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('with descendants'),
|
||||
);
|
||||
$form[$name]['new'][$vid]['grants'] =
|
||||
taxonomy_access_grant_add_table($vocab_default, $vid);
|
||||
$form[$name]['new'][$vid]['add'] = array(
|
||||
'#type' => 'submit',
|
||||
'#name' => $vid,
|
||||
'#submit' => array('taxonomy_access_add_term_submit'),
|
||||
'#value' => t('Add'),
|
||||
);
|
||||
}
|
||||
$disable_url = url(
|
||||
TAXONOMY_ACCESS_CONFIG . "/role/$rid/disable/$vid",
|
||||
array('query' => drupal_get_destination())
|
||||
);
|
||||
$form[$name]['disable'] = array(
|
||||
'#markup' => '<p>' . t(
|
||||
'To disable the %vocab vocabulary, <a href="@url">delete all @vocab access rules</a>.',
|
||||
array('%vocab' => $vocab->name, '@vocab' => $vocab->name, '@url' => $disable_url)) . '</p>'
|
||||
);
|
||||
}
|
||||
}
|
||||
$form['actions'] = array('#type' => 'actions');
|
||||
$form['actions']['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Save all'),
|
||||
'#submit' => array('taxonomy_access_save_all_submit'),
|
||||
);
|
||||
if (!empty($term_grants)) {
|
||||
$form['actions']['delete'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Delete selected'),
|
||||
'#submit' => array('taxonomy_access_delete_selected_submit'),
|
||||
);
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a grant table for multiple access rules.
|
||||
*
|
||||
* @param array $rows
|
||||
* An array of grant row data, keyed by an ID (term, vocab, role, etc.). Each
|
||||
* row should include the following keys:
|
||||
* - name: (optional) The label for the row (e.g., a term, vocabulary, or
|
||||
* role name).
|
||||
* - view: The View grant value select box for the element.
|
||||
* - update: The Update grant value select box for the element.
|
||||
* - delete: The Delete grant value select box for the element.
|
||||
* - create: The Add tag grant value select box for the element.
|
||||
* - list: The View tag grant value select box for the element.
|
||||
* @param int $parent_vid
|
||||
* The parent ID for the table in the form tree structure (typically a
|
||||
* vocabulary id).
|
||||
* @param string $first_col
|
||||
* The header for the first column (in the 'name' key for each row).
|
||||
* @param bool $delete
|
||||
* (optional) Whether to add a deletion checkbox to each row along with a
|
||||
* "Check all" box in the table header. The checbox is automatically disabled
|
||||
* for TAXONOMY_ACCESS_VOCABULARY_DEFAULT. Defaults to TRUE.
|
||||
*
|
||||
* @return
|
||||
* Renderable array containing the table.
|
||||
*
|
||||
* @see taxonomy_access_grant_table()
|
||||
*/
|
||||
function taxonomy_access_grant_table(array $rows, $parent_vid, $first_col, $delete = TRUE) {
|
||||
$header = taxonomy_access_grant_table_header();
|
||||
if ($first_col) {
|
||||
array_unshift(
|
||||
$header,
|
||||
array('data' => $first_col, 'class' => array('taxonomy-access-label'))
|
||||
);
|
||||
}
|
||||
if ($delete) {
|
||||
drupal_add_js('misc/tableselect.js');
|
||||
array_unshift($header, array('class' => array('select-all')));
|
||||
}
|
||||
$table = array(
|
||||
'#type' => 'taxonomy_access_grant_table',
|
||||
'#tree' => TRUE,
|
||||
'#header' => $header,
|
||||
);
|
||||
foreach ($rows as $id => $row) {
|
||||
$table[$parent_vid][$id] = taxonomy_access_admin_build_row($row, 'name', $delete);
|
||||
}
|
||||
// Disable the delete checkbox for the default.
|
||||
if ($delete && isset($table[$parent_vid][TAXONOMY_ACCESS_VOCABULARY_DEFAULT])) {
|
||||
$table[$parent_vid][TAXONOMY_ACCESS_VOCABULARY_DEFAULT]['remove']['#disabled'] = TRUE;
|
||||
}
|
||||
|
||||
return $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a grant table for adding access rules with one set of values.
|
||||
*
|
||||
* @param array $rows
|
||||
* An associative array of access rule data, with the following keys:
|
||||
* - view: The View grant value select box for the element.
|
||||
* - update: The Update grant value select box for the element.
|
||||
* - delete: The Delete grant value select box for the element.
|
||||
* - create: The Add tag grant value select box for the element.
|
||||
* - list: The View tag grant value select box for the element.
|
||||
* @param int $id
|
||||
* The ID for this set (e.g., a vocabulary ID).
|
||||
*
|
||||
* @return
|
||||
* Renderable array containing the table.
|
||||
*
|
||||
* @see taxonomy_access_grant_table()
|
||||
*/
|
||||
function taxonomy_access_grant_add_table($row, $id) {
|
||||
$header = taxonomy_access_grant_table_header();
|
||||
$table = array(
|
||||
'#type' => 'taxonomy_access_grant_table',
|
||||
'#tree' => TRUE,
|
||||
'#header' => $header,
|
||||
);
|
||||
$table[$id][TAXONOMY_ACCESS_VOCABULARY_DEFAULT] = taxonomy_access_admin_build_row($row);
|
||||
|
||||
return $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a header array for grant form tables.
|
||||
*
|
||||
* @return array
|
||||
* An array of header cell data for a grant table.
|
||||
*/
|
||||
function taxonomy_access_grant_table_header() {
|
||||
$header = array(
|
||||
array('data' => t('View')),
|
||||
array('data' => t('Update')),
|
||||
array('data' => t('Delete')),
|
||||
array('data' => t('Add Tag')),
|
||||
array('data' => t('View Tag')),
|
||||
);
|
||||
foreach ($header as &$cell) {
|
||||
$cell['class'] = array('taxonomy-access-grant');
|
||||
}
|
||||
return $header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme our grant table.
|
||||
*
|
||||
* @todo
|
||||
* Use a separate theme function for taxonomy_access_grant_add_table() to get
|
||||
* out of nesting hell?
|
||||
* @todo
|
||||
* I clearly have no idea what I'm doing here.
|
||||
*/
|
||||
function theme_taxonomy_access_grant_table($element_data) {
|
||||
$table = array();
|
||||
$table['header'] = $element_data['elements']['#header'];
|
||||
$table['attributes']['class'] = array('taxonomy-access-grant-table');
|
||||
$rows = array();
|
||||
foreach (element_children($element_data['elements']) as $element_key) {
|
||||
$child = $element_data['elements'][$element_key];
|
||||
foreach (element_children($child) as $child_key) {
|
||||
$record = $child[$child_key];
|
||||
$row = array();
|
||||
foreach (element_children($record) as $record_key) {
|
||||
$data = array('data' => $record[$record_key]);
|
||||
// If it's the default, add styling.
|
||||
if ($record_key == 'name') {
|
||||
$data['class'] = array('taxonomy-access-label');
|
||||
if ($child_key == TAXONOMY_ACCESS_VOCABULARY_DEFAULT) {
|
||||
$data['class'][] = 'taxonomy-access-default';
|
||||
}
|
||||
}
|
||||
// Add grant classes to grant cells.
|
||||
elseif (in_array($record_key, array('view', 'update', 'delete', 'create', 'list'))) {
|
||||
$grant_class = $record_key . '-' . $data['data']['#default_value'];
|
||||
$data['class'] = array('taxonomy-access-grant', $grant_class);
|
||||
}
|
||||
$row[] = $data;
|
||||
}
|
||||
$rows[] = $row;
|
||||
}
|
||||
}
|
||||
$table['rows'] = $rows;
|
||||
return theme('table', $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assembles a row of grant options for a term or default on the admin form.
|
||||
*
|
||||
* @param array $grants
|
||||
* An array of grants to use as form defaults.
|
||||
* @param $label_key
|
||||
* (optional) Key of the column to use as a label in each grant row. Defaults
|
||||
* to NULL.
|
||||
*/
|
||||
function taxonomy_access_admin_build_row(array $grants, $label_key = NULL, $delete = FALSE) {
|
||||
$form['#tree'] = TRUE;
|
||||
if ($delete) {
|
||||
$form['remove'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Delete access rule for @name', array('@name' => $grants[$label_key])),
|
||||
'#title_display' => 'invisible',
|
||||
);
|
||||
}
|
||||
if ($label_key) {
|
||||
$form[$label_key] = array(
|
||||
'#type' => 'markup',
|
||||
'#markup' => check_plain($grants[$label_key]),
|
||||
);
|
||||
}
|
||||
foreach (array('view', 'update', 'delete', 'create', 'list') as $grant) {
|
||||
$for = $label_key ? $grants[$label_key] : NULL;
|
||||
$form[$grant] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => _taxonomy_access_grant_field_label($grant, $for),
|
||||
'#title_display' => 'invisible',
|
||||
'#default_value' => is_string($grants['grant_' . $grant]) ? $grants['grant_' . $grant] : TAXONOMY_ACCESS_NODE_IGNORE,
|
||||
'#required' => TRUE,
|
||||
);
|
||||
}
|
||||
foreach (array('view', 'update', 'delete') as $grant) {
|
||||
$form[$grant]['#options'] = array(
|
||||
TAXONOMY_ACCESS_NODE_ALLOW => t('Allow'),
|
||||
TAXONOMY_ACCESS_NODE_IGNORE => t('Ignore'),
|
||||
TAXONOMY_ACCESS_NODE_DENY => t('Deny'),
|
||||
);
|
||||
}
|
||||
foreach (array('create', 'list') as $grant) {
|
||||
$form[$grant]['#options'] = array(
|
||||
TAXONOMY_ACCESS_TERM_ALLOW => t('Allow'),
|
||||
TAXONOMY_ACCESS_TERM_DENY => t('Deny'),
|
||||
);
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the proper invisible field label for each grant table element.
|
||||
*/
|
||||
function _taxonomy_access_grant_field_label($grant, $for = NULL) {
|
||||
if ($for) {
|
||||
$label = array('@label', $for);
|
||||
$titles = array(
|
||||
'view' => t('View grant for @label', $label),
|
||||
'update' => t('Update grant for @label', $label),
|
||||
'delete' => t('Delete grant for @label', $label),
|
||||
'create' => t('Add tag grant for @label', $label),
|
||||
'list' => t('View tag grant for @label', $label),
|
||||
);
|
||||
}
|
||||
else {
|
||||
$titles = array(
|
||||
'view' => t('View grant'),
|
||||
'update' => t('Update grant'),
|
||||
'delete' => t('Delete grant'),
|
||||
'create' => t('Add tag grant'),
|
||||
'list' => t('View tag grant'),
|
||||
);
|
||||
}
|
||||
|
||||
return $titles[$grant];
|
||||
}
|
||||
|
||||
/**
|
||||
* Form submission handler for taxonomy_access_admin_role().
|
||||
*
|
||||
* Processes submissions for the vocabulary 'Add' button.
|
||||
*/
|
||||
function taxonomy_access_enable_vocab_submit($form, &$form_state) {
|
||||
$rid = $form_state['values']['rid'];
|
||||
$vid = $form_state['values']['enable_vocab'];
|
||||
$roles = _taxonomy_access_user_roles();
|
||||
$vocab = taxonomy_vocabulary_load($vid);
|
||||
if (taxonomy_access_enable_vocab($vid, $rid)) {
|
||||
drupal_set_message(t(
|
||||
'Vocabulary %vocab enabled successfully for the %role role.',
|
||||
array(
|
||||
'%vocab' => $vocab->name,
|
||||
'%role' => $roles[$rid])));
|
||||
}
|
||||
else {
|
||||
drupal_set_message(t('The vocabulary could not be enabled.'), 'error');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Form submission handler for taxonomy_access_admin_role().
|
||||
*
|
||||
* Processes submissions for the term 'Add' button.
|
||||
*/
|
||||
function taxonomy_access_add_term_submit($form, &$form_state) {
|
||||
$vid = $form_state['clicked_button']['#name'];
|
||||
$new = $form_state['values']['new'][$vid];
|
||||
$rid = $form_state['values']['rid'];
|
||||
list($type, $id) = explode(' ', $new['item']);
|
||||
$rows = array();
|
||||
|
||||
$rows[$id] =
|
||||
_taxonomy_access_format_grant_record($id, $rid, $new['grants'][$vid][TAXONOMY_ACCESS_VOCABULARY_DEFAULT]);
|
||||
|
||||
// If we are adding children recursively, add those as well.
|
||||
if ($new['recursive'] == 1) {
|
||||
$children = _taxonomy_access_get_descendants($id);
|
||||
foreach ($children as $tid) {
|
||||
$rows[$tid] =
|
||||
_taxonomy_access_format_grant_record($tid, $rid, $new['grants'][$vid][TAXONOMY_ACCESS_VOCABULARY_DEFAULT]);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the grants for the row or rows.
|
||||
taxonomy_access_set_term_grants($rows);
|
||||
}
|
||||
|
||||
/**
|
||||
* Page callback: Returns a confirmation form to disable a vocabulary.
|
||||
*
|
||||
* @param int $rid
|
||||
* The role ID.
|
||||
* @param object $vocab
|
||||
* The vocabulary object.
|
||||
*
|
||||
* @todo
|
||||
* Check if vocab is enabled and return a 404 otherwise?
|
||||
*
|
||||
* @see taxonomy_access_menu()
|
||||
* @see taxonomy_access_admin_role().
|
||||
* @see taxonomy_access_disable_vocab_confirm_page()
|
||||
*/
|
||||
function taxonomy_access_disable_vocab_confirm_page($rid, $vocab) {
|
||||
$rid = intval($rid);
|
||||
|
||||
// Return a 404 on invalid vid or rid.
|
||||
if (!$vocab->vid || !$rid) {
|
||||
return MENU_NOT_FOUND;
|
||||
}
|
||||
|
||||
return drupal_get_form('taxonomy_access_disable_vocab_confirm', $rid, $vocab);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a confirmation form for disabling a vocabulary for a role.
|
||||
*
|
||||
* @param int $rid
|
||||
* The role ID.
|
||||
* @param object $vocab
|
||||
* The vocabulary object.
|
||||
*
|
||||
* @see taxonomy_access_disable_vocab_confirm_page()
|
||||
* @see taxonomy_access_disable_vocab_confirm_submit()
|
||||
* @ingroup forms
|
||||
*/
|
||||
function taxonomy_access_disable_vocab_confirm($form, &$form_state, $rid, $vocab) {
|
||||
$roles = _taxonomy_access_user_roles();
|
||||
if (taxonomy_access_role_enabled($rid)) {
|
||||
$form['rid'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $rid,
|
||||
);
|
||||
$form['vid'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $vocab->vid,
|
||||
);
|
||||
$form['vocab_name'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $vocab->name,
|
||||
);
|
||||
return confirm_form($form,
|
||||
t("Are you sure you want to delete all Taxonomy access rules for %vocab in the %role role?",
|
||||
array('%role' => $roles[$rid], '%vocab' => $vocab->name)),
|
||||
TAXONOMY_ACCESS_CONFIG . '/role/%/edit',
|
||||
t('This action cannot be undone.'),
|
||||
t('Delete all'),
|
||||
t('Cancel'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Form submission handler for taxonomy_access_disable_vocab_confirm().
|
||||
*
|
||||
* @param int $rid
|
||||
* The role ID to disable.
|
||||
*
|
||||
* @todo
|
||||
* Set a message on invalid $rid or $vid?
|
||||
*/
|
||||
function taxonomy_access_disable_vocab_confirm_submit($form, &$form_state) {
|
||||
$roles = _taxonomy_access_user_roles();
|
||||
$rid = intval($form_state['values']['rid']);
|
||||
$vid = intval($form_state['values']['vid']);
|
||||
// Do not proceed for invalid role IDs, and do not allow the global default
|
||||
// to be deleted.
|
||||
if (!$vid || !$rid || empty($roles[$rid])) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ($form_state['values']['confirm']) {
|
||||
$form_state['redirect'] = TAXONOMY_ACCESS_CONFIG;
|
||||
if (taxonomy_access_disable_vocab($vid, $rid)) {
|
||||
drupal_set_message(
|
||||
t('All Taxonomy access rules deleted for %vocab in role %role.',
|
||||
array(
|
||||
'%vocab' => $form_state['values']['vocab_name'],
|
||||
'%role' => $roles[$rid])
|
||||
));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Form submission handler for taxonomy_access_admin_role().
|
||||
*
|
||||
* Processes submissions for the "Delete selected" button.
|
||||
*
|
||||
* @todo
|
||||
* The parent form could probably be refactored to make this more efficient
|
||||
* (by putting these elements in a flat list) but that would require changing
|
||||
* taxonomy_access_grant_table() and taxonomy_access_build_row().
|
||||
*/
|
||||
function taxonomy_access_delete_selected_submit($form, &$form_state) {
|
||||
$rid = intval($form_state['values']['rid']);
|
||||
$delete_tids = array();
|
||||
foreach ($form_state['values']['grants'] as $vid => $tids) {
|
||||
foreach ($tids as $tid => $record) {
|
||||
if (!empty($record['remove'])) {
|
||||
$delete_tids[] = $tid;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($rid) {
|
||||
if (taxonomy_access_delete_term_grants($delete_tids, $rid)) {
|
||||
drupal_set_message(format_plural(
|
||||
sizeof($delete_tids),
|
||||
'1 term access rule was deleted.',
|
||||
'@count term access rules were deleted.'));
|
||||
}
|
||||
else {
|
||||
drupal_set_message(t('The records could not be deleted.'), 'warning');
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Form submission handler for taxonomy_access_admin_form().
|
||||
*
|
||||
* Processes submissions for the 'Save all' button.
|
||||
*/
|
||||
function taxonomy_access_save_all_submit($form, &$form_state) {
|
||||
$values = $form_state['values'];
|
||||
$rid = $values['rid'];
|
||||
$vocabs = taxonomy_get_vocabularies();
|
||||
|
||||
// Create four lists of records to update.
|
||||
$update_terms = array();
|
||||
$skip_terms = array();
|
||||
$update_defaults = array();
|
||||
$skip_defaults = array();
|
||||
|
||||
foreach ($values['grants'] as $vid => $rows) {
|
||||
if ($vid == TAXONOMY_ACCESS_GLOBAL_DEFAULT) {
|
||||
$element = $form['global_default'];
|
||||
}
|
||||
else {
|
||||
$vocab = $vocabs[$vid];
|
||||
$element = $form[$vocab->machine_name];
|
||||
}
|
||||
foreach ($rows as $tid => $row) {
|
||||
// Check the default values for this row.
|
||||
$defaults = array();
|
||||
$grants = array();
|
||||
foreach (array('view', 'update', 'delete', 'create', 'list') as $grant_name) {
|
||||
$grants[$grant_name] = $row[$grant_name];
|
||||
$defaults[$grant_name] =
|
||||
$element['grants'][$vid][$tid][$grant_name]['#default_value'];
|
||||
}
|
||||
|
||||
// Proceed if the user changed the row (values differ from defaults).
|
||||
if ($defaults != $grants) {
|
||||
// If the grants for node access match the defaults, then we
|
||||
// can skip updating node access records for this row.
|
||||
$update_nodes = FALSE;
|
||||
foreach (array('view', 'update', 'delete') as $op) {
|
||||
if ($defaults[$op] != $grants[$op]) {
|
||||
$update_nodes = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the row to one of the four arrays.
|
||||
switch (TRUE) {
|
||||
// Term record with node grant changes.
|
||||
case ($tid && $update_nodes):
|
||||
$update_terms[$tid] =
|
||||
_taxonomy_access_format_grant_record($tid, $rid, $grants);
|
||||
break;
|
||||
|
||||
// Term record and no node grant changes.
|
||||
case ($tid && !$update_nodes):
|
||||
$skip_terms[$tid] =
|
||||
_taxonomy_access_format_grant_record($tid, $rid, $grants);
|
||||
break;
|
||||
|
||||
// Vocab record with node grant changes.
|
||||
case (!$tid && $update_nodes):
|
||||
$update_defaults[$vid] =
|
||||
_taxonomy_access_format_grant_record($vid, $rid, $grants, TRUE);
|
||||
break;
|
||||
|
||||
// Vocab record and no node grant changes.
|
||||
case (!$tid && !$update_nodes):
|
||||
$skip_defaults[$vid] =
|
||||
_taxonomy_access_format_grant_record($vid, $rid, $grants, TRUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process each set.
|
||||
if (!empty($update_terms)) {
|
||||
taxonomy_access_set_term_grants($update_terms);
|
||||
}
|
||||
if (!empty($skip_terms)) {
|
||||
taxonomy_access_set_term_grants($skip_terms, FALSE);
|
||||
}
|
||||
if (!empty($update_defaults)) {
|
||||
taxonomy_access_set_default_grants($update_defaults);
|
||||
}
|
||||
if (!empty($skip_defaults)) {
|
||||
taxonomy_access_set_default_grants($skip_defaults, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates HTML markup with form instructions for the admin form.
|
||||
*
|
||||
* @return
|
||||
* Instructions HTML string.
|
||||
*/
|
||||
function _taxonomy_access_admin_instructions_html() {
|
||||
$instructions = '';
|
||||
$instructions .= ''
|
||||
. "<br /><br />"
|
||||
. "<div class=\"instructions\">"
|
||||
. "<h2>" . t("Explanation of fields") . "</h2>"
|
||||
. _taxonomy_access_grant_help_table()
|
||||
. "<p>"
|
||||
. t('Options for View, Update, and Delete are <em>Allow</em> (<acronym title="Allow">A</acronym>), <em>Ignore</em> (<acronym title="Ignore">I</acronym>), and <em>Deny</em> (<acronym title="Deny">D</acronym>).')
|
||||
. "</p>\n\n"
|
||||
. "<ul>\n"
|
||||
. "<li>"
|
||||
. t('<em>Deny</em> (<acronym title="Deny">D</acronym>) overrides <em>Allow</em> (<acronym title="Allow">A</acronym>) within this role.')
|
||||
. "</li>"
|
||||
. "<li>"
|
||||
. t('Both <em>Allow</em> (<acronym title="Allow">A</acronym>) and <em>Deny</em> (<acronym title="Deny">D</acronym>) override <em>Ignore</em> (<acronym title="Ignore">I</acronym>) within this role.')
|
||||
. "</li>"
|
||||
. "<li>"
|
||||
. t('If a user has <strong>multiple roles</strong>, an <em>Allow</em> (<acronym title="Allow">A</acronym>) from another role <strong>will</strong> override a <em>Deny</em> (<acronym title="Deny">D</acronym>) here.')
|
||||
. "</li>"
|
||||
. "</ul>\n\n"
|
||||
;
|
||||
if (arg(4) != DRUPAL_ANONYMOUS_RID && arg(4) != DRUPAL_AUTHENTICATED_RID) {
|
||||
// Role other than Anonymous or Authenticated
|
||||
$instructions .= ''
|
||||
. "<p>"
|
||||
. t('<strong>Remember:</strong> This role <strong>will</strong> inherit permissions from the <em>authenticated user</em> role. Be sure to <a href="@url">configure the authenticated user</a> properly.',
|
||||
array("@url" => url(
|
||||
TAXONOMY_ACCESS_CONFIG
|
||||
. "/role/"
|
||||
. DRUPAL_AUTHENTICATED_RID
|
||||
. '/edit')))
|
||||
. "</p>\n\n"
|
||||
;
|
||||
}
|
||||
$instructions .= ''
|
||||
. "<p>"
|
||||
. t('For more information and for troubleshooting guidelines, see the <a href="@help">help page</a> and the !readme.',
|
||||
array(
|
||||
'@help' => url('admin/help/taxonomy_access'),
|
||||
'!readme' => "<code>README.txt</code>"
|
||||
))
|
||||
. "</p>\n\n"
|
||||
. "</div>\n\n"
|
||||
;
|
||||
|
||||
return $instructions;
|
||||
|
||||
}
|
@ -0,0 +1,873 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Implements the Add Tag (create) grant on editing forms.
|
||||
*
|
||||
* These functions need to be included in three circumstances:
|
||||
* - Form building for forms with taxonomy fields.
|
||||
* - taxonomy_access_field_widget_form_alter()
|
||||
* - taxonomy_access_field_widget_taxonomy_autocomplete_form_alter()
|
||||
* - Form validation for forms with taxonomy fields.
|
||||
* - taxonomy_access_autocomplete_validate()
|
||||
* - taxonomy_access_options_validate()
|
||||
* - taxonomy_access_field_attach_validate()
|
||||
* - Taxonomy autocomplete AJAX requests.
|
||||
* - taxonomy_access_autocomplete()
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup tac_create Taxonomy Access Control: Add tag (create) permission
|
||||
* @{
|
||||
* Implement access control for taxonomy terms on node editing forms.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements the create grant for autocomplete fields.
|
||||
*
|
||||
* - Denies access if the user cannot alter the field values.
|
||||
* - Determines whether the user can autocreate new terms for the field.
|
||||
* - Removes default values disallowed by create.
|
||||
* - Adds information on autocreate and disallowed defaults to the element so
|
||||
* it is available to the validator.
|
||||
* - Adds the custom validator.
|
||||
* - Sets a custom autocomplete path to filter autocomplete by create.
|
||||
*
|
||||
* Some of the logic here is borrowed from taxonomy_autocomplete_validate().
|
||||
*
|
||||
* @see taxonomy_access_field_widget_taxonomy_autocomplete_form_alter()
|
||||
*/
|
||||
function _taxonomy_access_autocomplete_alter(&$element, &$form_state, $context) {
|
||||
|
||||
// Collect a list of terms and filter out those disallowed by create.
|
||||
$filtered = array();
|
||||
foreach ($context['items'] as $item) {
|
||||
$filtered[$item['tid']] = $item;
|
||||
}
|
||||
$disallowed_defaults = taxonomy_access_create_disallowed(array_keys($filtered));
|
||||
foreach ($disallowed_defaults as $tid) {
|
||||
unset($filtered[$tid]);
|
||||
}
|
||||
|
||||
// Assemble a list of all vocabularies for the field.
|
||||
$vids = array();
|
||||
foreach ($context['field']['settings']['allowed_values'] as $tree) {
|
||||
if ($vocab = taxonomy_vocabulary_machine_name_load($tree['vocabulary'])) {
|
||||
$vids[] = $vocab->vid;
|
||||
}
|
||||
}
|
||||
|
||||
// Determine whether the user has create for any terms in the given vocabs.
|
||||
$allowed_terms = FALSE;
|
||||
foreach ($vids as $vid) {
|
||||
$terms = taxonomy_access_user_create_terms_by_vocab($vid);
|
||||
if (!empty($terms)) {
|
||||
$allowed_terms = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Filter the vids to vocabs in which the user may create new terms.
|
||||
$allowed_vids = taxonomy_access_create_default_allowed($vids);
|
||||
|
||||
// If the field already has the maximum number of values, and all of these
|
||||
// values are disallowed, deny access to the field.
|
||||
if ($context['field']['cardinality'] != FIELD_CARDINALITY_UNLIMITED) {
|
||||
if (sizeof($disallowed_defaults) >= $context['field']['cardinality']) {
|
||||
$element['#access'] = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// If the user may not create any terms on this field, deny access.
|
||||
if (empty($allowed_vids) && !$allowed_terms) {
|
||||
$element['#access'] = FALSE;
|
||||
}
|
||||
|
||||
// Set the default value from the filtered item list.
|
||||
$element['#default_value'] =
|
||||
taxonomy_access_autocomplete_default_value($filtered);
|
||||
|
||||
// Custom validation. Set values for the validator indicating:
|
||||
// 1. Whether the user can autocreate terms in this field (vocab. default).
|
||||
// 2. Which tids were removed due to create restrictions.
|
||||
$element['#allow_autocreate'] = empty($allowed_vids) ? FALSE : TRUE;
|
||||
$element['#disallowed_defaults'] = $disallowed_defaults;
|
||||
$element['#element_validate'] =
|
||||
array('taxonomy_access_autocomplete_validate');
|
||||
|
||||
// Use a custom autocomplete path to filter by create rather than list.
|
||||
$element['#autocomplete_path'] =
|
||||
'taxonomy_access/autocomplete/' . $context['field']['field_name'];
|
||||
|
||||
unset($context);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements the create grant for options widgets.
|
||||
*
|
||||
* - Denies access if the user cannot alter the field values.
|
||||
* - Attaches jQuery to disable values disallowed by create.
|
||||
* - Adds the disallowed values from the element so they are available to the
|
||||
* custom validator.
|
||||
* - Adds the custom validator.
|
||||
*
|
||||
* We use jQuery to disable the options because of FAPI limitations:
|
||||
* @see http://drupal.org/node/284917
|
||||
* @see http://drupal.org/node/342316
|
||||
* @see http://drupal.org/node/12089
|
||||
*
|
||||
* @see taxonomy_access_field_widget_form_alter()
|
||||
*/
|
||||
function _taxonomy_access_options_alter(&$element, &$form_state, $context) {
|
||||
|
||||
// Check for an existing entity ID.
|
||||
$entity_id = 0;
|
||||
if (!empty($form_state['build_info']['args'][0])) {
|
||||
$info = entity_get_info($context['instance']['entity_type']);
|
||||
$pseudo_entity = (object) $form_state['build_info']['args'][0];
|
||||
if (isset($pseudo_entity->{$info['entity keys']['id']})) {
|
||||
$entity_id = $pseudo_entity->{$info['entity keys']['id']};
|
||||
}
|
||||
}
|
||||
// Collect a list of terms and determine which are allowed
|
||||
$tids = array_keys($element['#options']);
|
||||
|
||||
// Ignore the "none" option if present.
|
||||
$key = array_search('_none', $tids);
|
||||
if ($key !== FALSE) {
|
||||
unset($tids[$key]);
|
||||
}
|
||||
|
||||
$allowed_tids = taxonomy_access_create_allowed($tids);
|
||||
$disallowed_tids = taxonomy_access_create_disallowed($tids);
|
||||
|
||||
// If no options are allowed, deny access to the field.
|
||||
if (empty($allowed_tids)) {
|
||||
$element['#access'] = FALSE;
|
||||
}
|
||||
|
||||
// On node creation, simply remove disallowed default values.
|
||||
if (!$entity_id) {
|
||||
$disallowed_defaults = array();
|
||||
if (is_array($element['#default_value'])) {
|
||||
foreach ($element['#default_value'] as $key => $value) {
|
||||
if (in_array($value, $disallowed_tids)) {
|
||||
unset($element['#default_value'][0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif (in_array($element['#default_value'], $disallowed_tids)) {
|
||||
unset($element['#default_value']);
|
||||
}
|
||||
}
|
||||
// If the node already exists, check:
|
||||
// 1. Whether the field already has the maximum number of values
|
||||
// 2. Whether all of these values are disallowed.
|
||||
// If both these things are true, then the user cannot edit the field's
|
||||
// value, so disallow access.
|
||||
else {
|
||||
$defaults =
|
||||
is_array($element['#default_value'])
|
||||
? $element['#default_value']
|
||||
: array($element['#default_value'])
|
||||
;
|
||||
|
||||
$disallowed_defaults =
|
||||
array_intersect($defaults, $disallowed_tids);
|
||||
|
||||
if ($context['field']['cardinality'] != FIELD_CARDINALITY_UNLIMITED) {
|
||||
if (sizeof($disallowed_defaults) >= $context['field']['cardinality']) {
|
||||
$element['#access'] = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there are disallowed, terms, add CSS and JS for jQuery.
|
||||
// We use jQuery because FAPI does not currently support attributes
|
||||
// for individual options.
|
||||
if (!empty($disallowed_tids)) {
|
||||
|
||||
// Add a css class to the field that we can use in jQuery.
|
||||
$class_name = 'tac_' . $element['#field_name'];
|
||||
$element['#attributes']['class'][] = $class_name;
|
||||
|
||||
// Add js for disabling create options.
|
||||
$settings[] = array(
|
||||
'field' => $class_name,
|
||||
'disallowed_tids' => $disallowed_tids,
|
||||
'disallowed_defaults' => $disallowed_defaults,
|
||||
);
|
||||
$element['#attached']['js'][] =
|
||||
drupal_get_path('module', 'taxonomy_access') . '/tac_create.js';
|
||||
$element['#attached']['js'][] = array(
|
||||
'data' => array('taxonomy_access' => $settings),
|
||||
'type' => 'setting',
|
||||
);
|
||||
}
|
||||
|
||||
$element['#disallowed_defaults'] = $disallowed_defaults;
|
||||
$element['#element_validate'] = array('taxonomy_access_options_validate');
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve terms that the current user may create.
|
||||
*
|
||||
* @return array|true
|
||||
* An array of term IDs, or TRUE if the user may create all terms.
|
||||
*
|
||||
* @see taxonomy_access_user_create_terms_by_vocab()
|
||||
* @see _taxonomy_access_user_term_grants()
|
||||
*/
|
||||
function taxonomy_access_user_create_terms() {
|
||||
// Cache the terms the current user can create.
|
||||
$terms = &drupal_static(__FUNCTION__, NULL);
|
||||
if (is_null($terms)) {
|
||||
$terms = _taxonomy_access_user_term_grants(TRUE);
|
||||
}
|
||||
return $terms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve terms that the current user may create in specific vocabularies.
|
||||
*
|
||||
* @param int $vid
|
||||
* A vid to use as a filter.
|
||||
*
|
||||
* @return array|true
|
||||
* An array of term IDs, or TRUE if the user may create all terms.
|
||||
*
|
||||
* @see taxonomy_access_user_create_terms()
|
||||
* @see _taxonomy_access_user_term_grants()
|
||||
*/
|
||||
function taxonomy_access_user_create_terms_by_vocab($vid) {
|
||||
// Cache the terms the current user can create per vocabulary.
|
||||
static $terms = array();
|
||||
if (!isset($terms[$vid])) {
|
||||
$terms[$vid] = _taxonomy_access_user_term_grants(TRUE, array($vid));
|
||||
}
|
||||
return $terms[$vid];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve terms that the current user may create.
|
||||
*
|
||||
* @return array|true
|
||||
* An array of term IDs, or TRUE if the user may create all terms.
|
||||
*
|
||||
* @see _taxonomy_access_create_defaults()
|
||||
*/
|
||||
function taxonomy_access_user_create_defaults() {
|
||||
// Cache the terms the current user can create.
|
||||
static $vids = NULL;
|
||||
if (is_null($vids)) {
|
||||
$vids = _taxonomy_access_create_defaults();
|
||||
}
|
||||
return $vids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a list of term IDs for terms the user may not create.
|
||||
*
|
||||
* @param array $tids
|
||||
* The array of term IDs.
|
||||
*
|
||||
* @return array
|
||||
* An array of disallowed term IDs.
|
||||
*/
|
||||
function taxonomy_access_create_disallowed(array $tids) {
|
||||
$all_allowed = taxonomy_access_user_create_terms();
|
||||
|
||||
// If the user's create grant info is exactly TRUE, no terms are disallowed.
|
||||
if ($all_allowed === TRUE) {
|
||||
return array();
|
||||
}
|
||||
|
||||
return array_diff($tids, $all_allowed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter a list of term IDs to terms the user may create.
|
||||
*
|
||||
* @param array $tids
|
||||
* The array of term IDs.
|
||||
*
|
||||
* @return array
|
||||
* An array of disallowed term IDs.
|
||||
*/
|
||||
function taxonomy_access_create_allowed(array $tids) {
|
||||
$all_allowed = taxonomy_access_user_create_terms();
|
||||
|
||||
// If the user's create grant info is exactly TRUE, all terms are allowed.
|
||||
if ($all_allowed === TRUE) {
|
||||
return $tids;
|
||||
}
|
||||
|
||||
return array_intersect($tids, $all_allowed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter a list of vocab IDs to those in which the user may create by default.
|
||||
*
|
||||
* @param array $vids
|
||||
* The array of vocabulary IDs.
|
||||
*
|
||||
* @return array
|
||||
* An array of disallowed vocabulary IDs.
|
||||
*/
|
||||
function taxonomy_access_create_default_allowed(array $vids) {
|
||||
$all_allowed = taxonomy_access_user_create_defaults();
|
||||
|
||||
// If the user's create grant info is exactly TRUE, all terms are allowed.
|
||||
if ($all_allowed === TRUE) {
|
||||
return $vids;
|
||||
}
|
||||
|
||||
return array_intersect($vids, $all_allowed);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve vocabularies in which the current user may create terms.
|
||||
*
|
||||
* @param object|null $account
|
||||
* (optional) The account for which to retrieve grants. If no account is
|
||||
* passed, the current user will be used. Defaults to NULL.
|
||||
*
|
||||
* @return array
|
||||
* An array of term IDs, or TRUE if the user has the grant for all terms.
|
||||
*/
|
||||
function _taxonomy_access_create_defaults($account = NULL) {
|
||||
|
||||
// If the user can administer taxonomy, return TRUE for a global grant.
|
||||
if (user_access('administer taxonomy', $account)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Build a term grant query.
|
||||
$query = _taxonomy_access_grant_query(array('create'), TRUE);
|
||||
|
||||
// Select term grants for the current user's roles.
|
||||
if (is_null($account)) {
|
||||
global $user;
|
||||
$account = $user;
|
||||
}
|
||||
$query
|
||||
->fields('td', array('vid'))
|
||||
->groupBy('td.vid')
|
||||
->condition('tadg.rid', array_keys($account->roles), 'IN')
|
||||
;
|
||||
|
||||
// Fetch term IDs.
|
||||
$r = $query->execute()->fetchAll();
|
||||
$vids = array();
|
||||
|
||||
// If there are results, initialize a flag to test whether the user
|
||||
// has the grant for all terms.
|
||||
$grants_for_all_vocabs = empty($r) ? FALSE : TRUE;
|
||||
|
||||
foreach ($r as $record) {
|
||||
// If the user has the grant, add the term to the array.
|
||||
if ($record->grant_create) {
|
||||
$vids[] = $record->vid;
|
||||
}
|
||||
// Otherwise, flag that the user does not have the grant for all terms.
|
||||
else {
|
||||
$grants_for_all_vocabs = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// If the user has the grant for all terms, return TRUE for a global grant.
|
||||
if ($grants_for_all_vocabs) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return $vids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Autocomplete menu callback: filter allowed terms by create, not list.
|
||||
*
|
||||
* For now we essentially duplicate the code from taxonomy.module, because
|
||||
* it calls drupal_json_output without providing the logic separately.
|
||||
*
|
||||
* @see http://drupal.org/node/1169964
|
||||
* @see taxonomy_autocomplete()
|
||||
*/
|
||||
function taxonomy_access_autocomplete($field_name, $tags_typed = '') {
|
||||
// Enforce that list grants do not filter the autocomplete.
|
||||
taxonomy_access_disable_list();
|
||||
|
||||
$field = field_info_field($field_name);
|
||||
|
||||
// The user enters a comma-separated list of tags. We only autocomplete the last tag.
|
||||
$tags_typed = drupal_explode_tags($tags_typed);
|
||||
$tag_last = drupal_strtolower(array_pop($tags_typed));
|
||||
|
||||
$matches = array();
|
||||
if ($tag_last != '') {
|
||||
|
||||
// Part of the criteria for the query come from the field's own settings.
|
||||
$vids = array();
|
||||
$vocabularies = taxonomy_vocabulary_get_names();
|
||||
foreach ($field['settings']['allowed_values'] as $tree) {
|
||||
$vids[] = $vocabularies[$tree['vocabulary']]->vid;
|
||||
}
|
||||
|
||||
$query = db_select('taxonomy_term_data', 't');
|
||||
$query->addTag('translatable');
|
||||
$query->addTag('term_access');
|
||||
|
||||
// Do not select already entered terms.
|
||||
if (!empty($tags_typed)) {
|
||||
$query->condition('t.name', $tags_typed, 'NOT IN');
|
||||
}
|
||||
// Select rows that match by term name.
|
||||
$tags_return = $query
|
||||
->fields('t', array('tid', 'name'))
|
||||
->condition('t.vid', $vids)
|
||||
->condition('t.name', '%' . db_like($tag_last) . '%', 'LIKE')
|
||||
->range(0, 10)
|
||||
->execute()
|
||||
->fetchAllKeyed();
|
||||
|
||||
// Unset suggestions disallowed by create grants.
|
||||
$disallowed = taxonomy_access_create_disallowed(array_keys($tags_return));
|
||||
foreach ($disallowed as $tid) {
|
||||
unset($tags_return[$tid]);
|
||||
}
|
||||
|
||||
$prefix = count($tags_typed) ? drupal_implode_tags($tags_typed) . ', ' : '';
|
||||
|
||||
$term_matches = array();
|
||||
foreach ($tags_return as $tid => $name) {
|
||||
$n = $name;
|
||||
// Term names containing commas or quotes must be wrapped in quotes.
|
||||
if (strpos($name, ',') !== FALSE || strpos($name, '"') !== FALSE) {
|
||||
$n = '"' . str_replace('"', '""', $name) . '"';
|
||||
}
|
||||
$term_matches[$prefix . $n] = check_plain($name);
|
||||
}
|
||||
}
|
||||
|
||||
drupal_json_output($term_matches);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates taxonomy autocomplete values for create grants.
|
||||
*
|
||||
* For now we essentially duplicate the code from taxonomy.module, because
|
||||
* it calls form_set_value() without providing the logic separately.
|
||||
*
|
||||
* We use two properties set in hook_field_widget_form_alter():
|
||||
* - $element['#allow_autocreate']
|
||||
* - $element['#disallowed_defaults']
|
||||
*
|
||||
* @todo
|
||||
* Specify autocreate per vocabulary?
|
||||
*
|
||||
* @see taxonomy_autocomplete_validate()
|
||||
* @see taxonomy_access_autocomplete()
|
||||
* @see taxonomy_access_field_widget_taxonomy_autocomplete_form_alter()
|
||||
*/
|
||||
function _taxonomy_access_autocomplete_validate($element, &$form_state) {
|
||||
// Autocomplete widgets do not send their tids in the form, so we must detect
|
||||
// them here and process them independently.
|
||||
$value = array();
|
||||
if ($tags = $element['#value']) {
|
||||
// Collect candidate vocabularies.
|
||||
$field = field_widget_field($element, $form_state);
|
||||
$vocabularies = array();
|
||||
foreach ($field['settings']['allowed_values'] as $tree) {
|
||||
if ($vocabulary = taxonomy_vocabulary_machine_name_load($tree['vocabulary'])) {
|
||||
$vocabularies[$vocabulary->vid] = $vocabulary;
|
||||
}
|
||||
}
|
||||
|
||||
// Translate term names into actual terms.
|
||||
$typed_terms = drupal_explode_tags($tags);
|
||||
foreach ($typed_terms as $typed_term) {
|
||||
// See if the term exists in the chosen vocabulary and return the tid;
|
||||
// otherwise, create a new 'autocreate' term for insert/update.
|
||||
if ($possibilities = taxonomy_term_load_multiple(array(), array('name' => trim($typed_term), 'vid' => array_keys($vocabularies)))) {
|
||||
$term = array_pop($possibilities);
|
||||
}
|
||||
// Only autocreate if the user has create for the vocab. default.
|
||||
elseif ($element['#allow_autocreate']) {
|
||||
$vocabulary = reset($vocabularies);
|
||||
$term = array(
|
||||
'tid' => 'autocreate',
|
||||
'vid' => $vocabulary->vid,
|
||||
'name' => $typed_term,
|
||||
'vocabulary_machine_name' => $vocabulary->machine_name,
|
||||
);
|
||||
}
|
||||
// If they cannot autocreate and this is a new term, set an error.
|
||||
else {
|
||||
form_error(
|
||||
$element,
|
||||
t('You may not create new tags in %name.',
|
||||
array('%name' => t($element['#title']))
|
||||
)
|
||||
);
|
||||
}
|
||||
if ($term) {
|
||||
$value[] = (array) $term;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add in the terms that were disallowed.
|
||||
// taxonomy.module expects arrays, not objects.
|
||||
$disallowed = taxonomy_term_load_multiple($element['#disallowed_defaults']);
|
||||
foreach ($disallowed as $key => $term) {
|
||||
$disallowed[$key] = (array) $term;
|
||||
}
|
||||
$value = array_merge($value, $disallowed);
|
||||
|
||||
// Subsequent validation will be handled by hook_field_attach_validate().
|
||||
// Set the value in the form.
|
||||
form_set_value($element, $value, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Form element validation handler for taxonomy option fields.
|
||||
*
|
||||
* We use a property set in hook_field_widget_form_alter():
|
||||
* - $element['#disallowed_defaults']
|
||||
*
|
||||
* @see options_field_widget_validate()
|
||||
* @see taxonomy_access_field_widget_form_alter()
|
||||
*/
|
||||
function _taxonomy_access_options_validate($element, &$form_state) {
|
||||
if ($element['#required'] && $element['#value'] == '_none') {
|
||||
form_error($element, t('!name field is required.', array('!name' => $element['#title'])));
|
||||
}
|
||||
|
||||
// Clone the element and add in disallowed defaults.
|
||||
$el = $element;
|
||||
if (!empty($element['#disallowed_defaults'])) {
|
||||
if (empty($el['#value'])) {
|
||||
$el['#value'] = $element['#disallowed_defaults'];
|
||||
}
|
||||
elseif (is_array($el['#value'])) {
|
||||
$el['#value'] = array_unique(array_merge($el['#value'], $element['#disallowed_defaults']));
|
||||
}
|
||||
else {
|
||||
$el['#value'] = array_unique(array_merge(array($el['#value']), $element['#disallowed_defaults']));
|
||||
}
|
||||
}
|
||||
|
||||
// Transpose selections from field => delta to delta => field, turning
|
||||
// multiple selected options into multiple parent elements.
|
||||
$items = _options_form_to_storage($el);
|
||||
|
||||
// Subsequent validation will be handled by hook_field_attach_validate().
|
||||
// Set the value in the form.
|
||||
form_set_value($element, $items, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default value re-generation for autocomplete fields.
|
||||
*
|
||||
* @param array $items
|
||||
* An array of values from form build info, filtered by create grants.
|
||||
*
|
||||
* @return string
|
||||
* Field default value.
|
||||
*
|
||||
* @see taxonomy_field_widget_form()
|
||||
*/
|
||||
function taxonomy_access_autocomplete_default_value(array $items) {
|
||||
// Preserve the original state of the list flag.
|
||||
$flag_state = taxonomy_access_list_enabled();
|
||||
|
||||
// Enforce that list grants do not filter the options list.
|
||||
taxonomy_access_disable_list();
|
||||
|
||||
// Assemble list of tags.
|
||||
$tags = array();
|
||||
foreach ($items as $item) {
|
||||
$tags[$item['tid']] = isset($item['taxonomy_term']) ? $item['taxonomy_term'] : taxonomy_term_load($item['tid']);
|
||||
}
|
||||
|
||||
// Assemble the default value using taxonomy.module.
|
||||
$tags = taxonomy_implode_tags($tags);
|
||||
|
||||
// Restore list flag to previous state.
|
||||
if ($flag_state) {
|
||||
taxonomy_access_enable_list();
|
||||
}
|
||||
|
||||
return $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates form submissions of taxonomy fields for create grants.
|
||||
*
|
||||
* @todo
|
||||
* Use field label and term names in errors rather than field name and tids.
|
||||
*
|
||||
* @see http://drupal.org/node/1220212
|
||||
* @see entity_form_field_validate()
|
||||
*/
|
||||
function _taxonomy_access_field_validate($entity_type, $entity, &$errors) {
|
||||
// Check for a pre-existing entity (i.e., the entity is being updated).
|
||||
$old_fields = FALSE;
|
||||
|
||||
// The entity is actually a "pseudo-entity," and the user profile form
|
||||
// neglects to include the uid. So, we need to load it manually.
|
||||
if ($entity_type == 'user') {
|
||||
// Some modules which extend the user profile form cause additional
|
||||
// validation to happen with "pseudo-entities" that do not include the
|
||||
// name. So, check if it exists.
|
||||
if (isset($entity->name)) {
|
||||
if ($account = user_load_by_name($entity->name)) {
|
||||
$entity->uid = $account->uid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list($entity_id, , $bundle) = entity_extract_ids($entity_type, $entity);
|
||||
if ($entity_id) {
|
||||
// Load the entity.
|
||||
$old_entity = entity_load($entity_type, array($entity_id));
|
||||
$old_entity = $old_entity[$entity_id];
|
||||
|
||||
// Fetch the original entity's taxonomy fields.
|
||||
$old_fields =
|
||||
_taxonomy_access_entity_fields($entity_type, $old_entity, $bundle);
|
||||
}
|
||||
|
||||
// Fetch the updated entity's taxonomy fields.
|
||||
$new_fields =
|
||||
_taxonomy_access_entity_fields($entity_type, $entity, $bundle);
|
||||
|
||||
// Set errors if there are any disallowed changes.
|
||||
$changes = _taxonomy_access_compare_fields($new_fields, $old_fields);
|
||||
|
||||
// We care about the overall value list, so delta is not important.
|
||||
$delta = 0;
|
||||
|
||||
// Check each field and langcode for disallowed changes.
|
||||
foreach ($changes as $field_name => $langcodes) {
|
||||
foreach ($langcodes as $langcode => $disallowed) {
|
||||
if ($disallowed) {
|
||||
if (!empty($disallowed['added'])) {
|
||||
$text = 'You may not add the following tags to %field: %tids';
|
||||
$errors[$field_name][$langcode][$delta][] = array(
|
||||
'error' => 'taxonomy_access_disallowed_added',
|
||||
'message' => t($text, array(
|
||||
'%field' => $field_name,
|
||||
'%tids' => implode(', ', $disallowed['added']),
|
||||
)),
|
||||
);
|
||||
}
|
||||
if (!empty($disallowed['removed'])) {
|
||||
$text = 'You may not remove the following tags from %field: %tids';
|
||||
$errors[$field_name][$langcode][$delta][] = array(
|
||||
'error' => 'taxonomy_access_disallowed_removed',
|
||||
'message' => t($text, array(
|
||||
'%field' => $field_name,
|
||||
'%tids' => implode(', ', $disallowed['removed']),
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper function to extract the taxonomy fields from an entity.
|
||||
*
|
||||
* @param object $entity
|
||||
* The entity object.
|
||||
*
|
||||
* @return array
|
||||
* An associative array of field information, containing:
|
||||
* - field_list: A flat array of all this entity's taxonomy fields, with the
|
||||
* format $field_name => $field_name.
|
||||
* - langcodes: A flat array of all langcodes in this entity's fields, with
|
||||
* the format $langcode => $langcode.
|
||||
* - data: An associative array of non-empty fields:
|
||||
* - $field_name: An associative array keyed by langcode.
|
||||
* - $langcode: Array of field values for this field name and langcode.
|
||||
*
|
||||
* @see http://drupal.org/node/1220168
|
||||
*/
|
||||
function _taxonomy_access_entity_fields($entity_type, $entity, $bundle) {
|
||||
// Maintain separate lists of field names and langcodes for quick comparison.
|
||||
$fields = array();
|
||||
$fields['field_list'] = array();
|
||||
$fields['langcodes'] = array();
|
||||
$fields['data'] = array();
|
||||
|
||||
// If there is no entity, return the empty structure.
|
||||
if (!$entity) {
|
||||
return $fields;
|
||||
}
|
||||
|
||||
// Get a list of possible fields for the bundle.
|
||||
// The bundle does not contain the field type (see #122016), so our only use
|
||||
// for it is the field names.
|
||||
$possible = array_keys(field_info_instances($entity_type, $bundle));
|
||||
|
||||
// Sort through the entity for relevant field data.
|
||||
foreach ($entity as $field_name => $field) {
|
||||
|
||||
// Only proceed if this element is a valid field for the bundle.
|
||||
if (in_array($field_name, $possible, TRUE)) {
|
||||
|
||||
// Check whether each entity field is a taxonomy field.
|
||||
$info = field_info_field($field_name);
|
||||
if ($info['type'] == 'taxonomy_term_reference') {
|
||||
foreach ($field as $langcode => $values) {
|
||||
|
||||
// Add non-empty fields to the lists.
|
||||
if (!empty($values)) {
|
||||
$fields['langcodes'][$langcode] = $langcode;
|
||||
$fields['field_list'][$field_name] = $field_name;
|
||||
$fields['data'][$field_name][$langcode] = $values;
|
||||
}
|
||||
unset($values);
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($info);
|
||||
unset($field);
|
||||
}
|
||||
|
||||
unset($entity);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to compare field values and look for disallowed changes.
|
||||
*
|
||||
* @param array $new
|
||||
* An associative array of the updated field information as returned by
|
||||
* _taxonomy_access_entity_fields().
|
||||
* @param array $old
|
||||
* (optional) An associative array of the original field information,
|
||||
* or FALSE if there is no original field data. Defaults to FALSE.
|
||||
*
|
||||
* @return array
|
||||
* An array of disallowed changes, with the structure:
|
||||
* - $field_name: An associative array keyed by langcode.
|
||||
* - $langcode: Disallowed changes for this field name and langcode,
|
||||
* or FALSE if none.
|
||||
* - 'added' => An array of added terms that are disallowed.
|
||||
* - 'removed' => An array of removed termss that are disallowed.
|
||||
*
|
||||
* @see _taxonomy_access_entity_fields()
|
||||
* @see _taxonomy_access_disallowed_changes()
|
||||
*/
|
||||
function _taxonomy_access_compare_fields($new, $old = FALSE) {
|
||||
$disallowed_changes = array();
|
||||
|
||||
// If there are no original fields, simply process new.
|
||||
if (!$old) {
|
||||
foreach ($new['data'] as $field_name => $langcodes) {
|
||||
foreach ($langcodes as $langcode => $values) {
|
||||
$changes = _taxonomy_access_disallowed_changes($values, array());
|
||||
if ($changes) {
|
||||
if (!isset($disallowed_changes[$field_name])) {
|
||||
$disallowed_changes[$field_name] = array();
|
||||
}
|
||||
$disallowed_changes[$field_name][$langcode] = $changes;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, aggregate and compare field data.
|
||||
else {
|
||||
$all_fields = $new['field_list'] + $old['field_list'];
|
||||
$all_langcodes = $new['langcodes'] + $old['langcodes'];
|
||||
|
||||
foreach ($all_fields as $field_name) {
|
||||
foreach ($all_langcodes as $langcode) {
|
||||
$new_values = array();
|
||||
if (isset($new['field_list'][$field_name])
|
||||
&& isset($new['data'][$field_name][$langcode])) {
|
||||
$new_values = $new['data'][$field_name][$langcode];
|
||||
}
|
||||
$old_values = array();
|
||||
if (isset($old['field_list'][$field_name])
|
||||
&& isset($old['data'][$field_name][$langcode])) {
|
||||
$old_values = $old['data'][$field_name][$langcode];
|
||||
}
|
||||
$changes = _taxonomy_access_disallowed_changes($new_values, $old_values);
|
||||
if ($changes) {
|
||||
if (!isset($disallowed_changes[$field_name])) {
|
||||
$disallowed_changes[$field_name] = array();
|
||||
}
|
||||
$disallowed_changes[$field_name][$langcode] = $changes;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset($old);
|
||||
unset($new);
|
||||
return $disallowed_changes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to check for term reference changes disallowed by create.
|
||||
*
|
||||
* @param array $new_field
|
||||
* The entity or form values of the updated field.
|
||||
* @param array $old_field
|
||||
* The entity or form values of the original field.
|
||||
*
|
||||
* @return array|false
|
||||
* Returns FALSE if there are no disallowed changes. Otherwise, an array:
|
||||
* - 'added' => An array of added terms that are disallowed.
|
||||
* - 'removed' => An array of removed termss that are disallowed.
|
||||
*/
|
||||
function _taxonomy_access_disallowed_changes(array $new_field, array $old_field) {
|
||||
|
||||
// Assemble a list of term IDs from the original entity, if any.
|
||||
$old_tids = array();
|
||||
foreach ($old_field as $old_item) {
|
||||
// Some things are NULL for some reason.
|
||||
if ($old_item['tid']) {
|
||||
$old_tids[] = $old_item['tid'];
|
||||
}
|
||||
}
|
||||
|
||||
// Assemble a list of term IDs from the updated entity.
|
||||
$new_tids = array();
|
||||
foreach ($new_field as $delta => $new_item) {
|
||||
// Some things are NULL for some reason.
|
||||
// Allow the special tid "autocreate" so users can create new terms.
|
||||
if ($new_item['tid'] && ($new_item['tid'] != 'autocreate')) {
|
||||
$new_tids[$delta] = $new_item['tid'];
|
||||
}
|
||||
}
|
||||
|
||||
// Check for added tids, and unset ones the user may not add.
|
||||
$added = array_diff($new_tids, $old_tids);
|
||||
$may_not_add = taxonomy_access_create_disallowed($added);
|
||||
|
||||
// Check for removed tids, and restore ones the user may not remove.
|
||||
$removed = array_diff($old_tids, $new_tids);
|
||||
$may_not_remove = taxonomy_access_create_disallowed($removed);
|
||||
|
||||
// If there were any disallowed changes, return them.
|
||||
if (!empty($may_not_add) || !empty($may_not_remove)) {
|
||||
return array('added' => $may_not_add, 'removed' => $may_not_remove);
|
||||
}
|
||||
|
||||
// Return FALSE if all changes were valid.
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* End of "defgroup tac_create".
|
||||
* @}
|
||||
*/
|
@ -0,0 +1,94 @@
|
||||
table.grant_help th {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
table.grant_help td p {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
table.grant_help em.perm {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
label.disabled {
|
||||
color: #999;
|
||||
font-style: italic;
|
||||
}
|
||||
.view-0,
|
||||
.update-0,
|
||||
.delete-0 {
|
||||
background-color: #fffce5;
|
||||
}
|
||||
.view-1,
|
||||
.update-1,
|
||||
.delete-1,
|
||||
.create-1,
|
||||
.list-1 {
|
||||
background-color: #e5ffe2;
|
||||
}
|
||||
.view-2,
|
||||
.update-2,
|
||||
.delete-2,
|
||||
.create-0,
|
||||
.list-0 {
|
||||
background-color: #fef5f1;
|
||||
}
|
||||
.taxonomy-access-grant-table {
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
width: inherit;
|
||||
}
|
||||
.taxonomy-access-grant-table th.select-all {
|
||||
width: 2em;
|
||||
}
|
||||
.taxonomy-access-grant-table td.taxonomy-access-label {
|
||||
padding-right: 4em;
|
||||
min-width: 12em;
|
||||
}
|
||||
.taxonomy-access-grant-table td.taxonomy-access-default {
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
}
|
||||
.taxonomy-access-grant-table td.taxonomy-access-grant {
|
||||
width: 7em;
|
||||
}
|
||||
fieldset#edit-vocabs .fieldset-description {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/**
|
||||
* I apologize, because what follows is a hodgepodge to override the default
|
||||
* fieldset styling in both Seven and Bartik, and might not even work in some
|
||||
* themes.
|
||||
*/
|
||||
#taxonomy-access-admin-role fieldset {
|
||||
margin-bottom: 0.5em;
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
#taxonomy-access-admin-role fieldset.taxonomy-access-add.collapsible,
|
||||
#taxonomy-access-admin-role fieldset.taxonomy-access-add.collapsed {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 1em;
|
||||
border: none;
|
||||
background: none;
|
||||
}
|
||||
fieldset.taxonomy-access-add > legend {
|
||||
background: none;
|
||||
border: none;
|
||||
font-family: inherit;
|
||||
position: static;
|
||||
}
|
||||
fieldset.taxonomy-access-add > legend a {
|
||||
color: #0076bc;
|
||||
}
|
||||
fieldset.taxonomy-access-add .fieldset-wrapper {
|
||||
margin-top: 0px;
|
||||
padding-top: 0.5em;
|
||||
}
|
||||
html.js fieldset.collapsible.taxonomy-access-add > legend .fieldset-legend,
|
||||
html.js fieldset.collapsed.taxonomy-access-add > legend .fieldset-legend {
|
||||
background: transparent url(images/add.png) no-repeat 0 center;
|
||||
text-transform: none;
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
name = Taxonomy Access Control
|
||||
description = Access control for user roles based on taxonomy categories.
|
||||
dependencies[] = taxonomy (>=7.8)
|
||||
core = 7.x
|
||||
configure = admin/config/people/taxonomy_access
|
||||
|
||||
files[] = taxonomy_access.test
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-09-19
|
||||
version = "7.x-1.0"
|
||||
core = "7.x"
|
||||
project = "taxonomy_access"
|
||||
datestamp = "1442635740"
|
||||
|
@ -0,0 +1,302 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Install, update, and uninstall functions for Taxonomy Access Control.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Implements hook_update_last_removed().
|
||||
*/
|
||||
function taxonomy_access_last_removed() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements hook_install().
|
||||
*
|
||||
* Adds tables to database: 'taxonomy_access_term', 'taxonomy_access_default'
|
||||
*/
|
||||
function taxonomy_access_install() {
|
||||
|
||||
// Default global perms for roles 1 (anonymous) and 2 (authenticated).
|
||||
db_query(
|
||||
'INSERT INTO {taxonomy_access_default}
|
||||
(vid, rid, grant_view, grant_update, grant_delete, grant_create, grant_list)
|
||||
VALUES
|
||||
(:vid, :rid, :node_allow, :ignore, :ignore, :term_allow, :term_allow)',
|
||||
array(
|
||||
':vid' => TAXONOMY_ACCESS_GLOBAL_DEFAULT,
|
||||
':rid' => DRUPAL_ANONYMOUS_RID,
|
||||
':node_allow' => TAXONOMY_ACCESS_NODE_ALLOW,
|
||||
':ignore' => TAXONOMY_ACCESS_NODE_IGNORE,
|
||||
':term_allow' => TAXONOMY_ACCESS_TERM_ALLOW)
|
||||
);
|
||||
db_query(
|
||||
'INSERT INTO {taxonomy_access_default}
|
||||
(vid, rid, grant_view, grant_update, grant_delete, grant_create, grant_list)
|
||||
VALUES
|
||||
(:vid, :rid, :node_allow, :ignore, :ignore, :term_allow, :term_allow)',
|
||||
array(
|
||||
':vid' => TAXONOMY_ACCESS_GLOBAL_DEFAULT,
|
||||
':rid' => DRUPAL_AUTHENTICATED_RID,
|
||||
':node_allow' => TAXONOMY_ACCESS_NODE_ALLOW,
|
||||
':ignore' => TAXONOMY_ACCESS_NODE_IGNORE,
|
||||
':term_allow' => TAXONOMY_ACCESS_TERM_ALLOW)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_schema().
|
||||
*/
|
||||
function taxonomy_access_schema() {
|
||||
$schema = array();
|
||||
|
||||
$schema['taxonomy_access_term'] = array(
|
||||
'description' => 'Identifies which roles may view, update, delete, create, and list nodes with a given term.',
|
||||
'fields' => array(
|
||||
'tid' => array(
|
||||
'description' => 'The term_data.tid this record affects. Overrides vocabulary default in taxonomy_access_default.',
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => TAXONOMY_ACCESS_VOCABULARY_DEFAULT,
|
||||
),
|
||||
'rid' => array(
|
||||
'description' => "The role.rid a user must possess to gain this row's privileges on nodes for this term.",
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
),
|
||||
'grant_view' => array(
|
||||
'description' => 'Whether this role can view nodes with this term. 0=>Ignore, 1=>Allow, 2=>Deny.',
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'size' => 'tiny',
|
||||
'not null' => TRUE,
|
||||
'default' => TAXONOMY_ACCESS_NODE_IGNORE,
|
||||
),
|
||||
'grant_update' => array(
|
||||
'description' => 'Whether this role can edit nodes with this term. 0=>Ignore, 1=>Allow, 2=>Deny.',
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'size' => 'tiny',
|
||||
'not null' => TRUE,
|
||||
'default' => TAXONOMY_ACCESS_NODE_IGNORE,
|
||||
),
|
||||
'grant_delete' => array(
|
||||
'description' => 'Whether this role can delete nodes with this term. 0=>Ignore, 1=>Allow, 2=>Deny.',
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'size' => 'tiny',
|
||||
'not null' => TRUE,
|
||||
'default' => TAXONOMY_ACCESS_NODE_IGNORE,
|
||||
),
|
||||
'grant_create' => array(
|
||||
'description' => 'Whether this role can set this term when adding or editing a node. 0=>No, 1=>Yes.',
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'size' => 'tiny',
|
||||
'not null' => TRUE,
|
||||
'default' => TAXONOMY_ACCESS_TERM_DENY,
|
||||
),
|
||||
'grant_list' => array(
|
||||
'description' => 'Whether this role can view the name of this term on a node or in category lists. 0=>No, 1=>Yes.',
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'size' => 'tiny',
|
||||
'not null' => TRUE,
|
||||
'default' => TAXONOMY_ACCESS_TERM_ALLOW,
|
||||
),
|
||||
),
|
||||
'primary key' => array('tid', 'rid'),
|
||||
);
|
||||
|
||||
$schema['taxonomy_access_default'] = array(
|
||||
'description' => 'Sets vocabulary defaults for which roles may view, update, delete, create, and list nodes with a given term. Overridden by {taxonomy_access_term}.',
|
||||
'fields' => array(
|
||||
'vid' => array(
|
||||
'description' => 'The vocabulary.vid for which this row sets defaults.',
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => TAXONOMY_ACCESS_VOCABULARY_DEFAULT,
|
||||
),
|
||||
'rid' => array(
|
||||
'description' => "The role.rid a user must possess to gain this row's privileges on nodes for terms in this vocabulary.",
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
),
|
||||
'grant_view' => array(
|
||||
'description' => 'Whether this role can view nodes with terms in this vocabulary. 0=>Ignore, 1=>Allow, 2=>Deny.',
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'size' => 'tiny',
|
||||
'not null' => TRUE,
|
||||
'default' => TAXONOMY_ACCESS_NODE_IGNORE,
|
||||
),
|
||||
'grant_update' => array(
|
||||
'description' => 'Whether this role can edit nodes with terms in this vocabulary. 0=>Ignore, 1=>Allow, 2=>Deny.',
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'size' => 'tiny',
|
||||
'not null' => TRUE,
|
||||
'default' => TAXONOMY_ACCESS_NODE_IGNORE,
|
||||
),
|
||||
'grant_delete' => array(
|
||||
'description' => 'Whether this role can delete nodes with terms in this vocabulary. 0=>Ignore, 1=>Allow, 2=>Deny.',
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'size' => 'tiny',
|
||||
'not null' => TRUE,
|
||||
'default' => TAXONOMY_ACCESS_NODE_IGNORE,
|
||||
),
|
||||
'grant_create' => array(
|
||||
'description' => 'Whether this role can set terms in this vocabulary when adding or editing a node. 0=>No, 1=>Yes.',
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'size' => 'tiny',
|
||||
'not null' => TRUE,
|
||||
'default' => TAXONOMY_ACCESS_TERM_DENY,
|
||||
),
|
||||
'grant_list' => array(
|
||||
'description' => 'Whether this role can view the name of terms in this vocabulary on a node or in category lists. 0=>No, 1=>Yes.',
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'size' => 'tiny',
|
||||
'not null' => TRUE,
|
||||
'default' => TAXONOMY_ACCESS_TERM_DENY,
|
||||
),
|
||||
),
|
||||
'primary key' => array('vid', 'rid'),
|
||||
);
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add vocabulary defaults for all configured vocabularies.
|
||||
*/
|
||||
function taxonomy_access_update_7002() {
|
||||
// Get a list of all vocabularies with any term configurations for each role.
|
||||
$ta_configs = db_query(
|
||||
"SELECT td.vid, ta.rid
|
||||
FROM {taxonomy_access_term} ta
|
||||
INNER JOIN {taxonomy_term_data} td ON ta.tid = td.tid
|
||||
GROUP BY td.vid, ta.rid"
|
||||
)->fetchAll();
|
||||
|
||||
// Get a list of all configured vocabularies.
|
||||
$td_configs = db_query(
|
||||
"SELECT vid, rid
|
||||
FROM {taxonomy_access_default}"
|
||||
)->fetchAll();
|
||||
|
||||
$records = array();
|
||||
$global_defaults = taxonomy_access_global_defaults();
|
||||
|
||||
foreach ($ta_configs as $config) {
|
||||
if (!in_array($config, $td_configs)) {
|
||||
$record = (array) $global_defaults[$config->rid];
|
||||
$records[] = _taxonomy_access_format_grant_record($config->vid, $config->rid, $record, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
if (taxonomy_access_set_default_grants($records)) {
|
||||
return t('Update completed successfully.');
|
||||
}
|
||||
else {
|
||||
return t('Update failed.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename grant realm.
|
||||
*/
|
||||
function taxonomy_access_update_7001() {
|
||||
db_query(
|
||||
"UPDATE {node_access} SET realm = 'taxonomy_access_role'
|
||||
WHERE realm = 'term_access'"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename database tables to follow Drupal 7 standards.
|
||||
*/
|
||||
function taxonomy_access_update_7000() {
|
||||
db_rename_table('term_access', 'taxonomy_access_term');
|
||||
db_rename_table('term_access_defaults', 'taxonomy_access_default');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_enable().
|
||||
*
|
||||
* Housekeeping: while we were away, did you delete any terms/vocabs/roles?
|
||||
* 1: Weight this module below the Taxonomy module.
|
||||
* 2: Delete ta, tad rows for missing roles.
|
||||
* 3: Delete ta rows for missing terms.
|
||||
* 4: Delete tad rows for missing vocabs.
|
||||
*/
|
||||
function taxonomy_access_enable() {
|
||||
|
||||
// Weight this module below the Taxonomy module.
|
||||
$tax_weight =
|
||||
db_query(
|
||||
"SELECT weight FROM {system}
|
||||
WHERE name = 'taxonomy'"
|
||||
)
|
||||
->fetchField()
|
||||
;
|
||||
|
||||
db_update('system')
|
||||
->fields(array('weight' => ($tax_weight + 1)))
|
||||
->condition('name', 'taxonomy_access')
|
||||
->execute();
|
||||
|
||||
// Delete any records for roles not in {roles}.
|
||||
$roles = _taxonomy_access_user_roles();
|
||||
$config_roles =
|
||||
db_query("SELECT DISTINCT rid FROM {taxonomy_access_default}")
|
||||
->fetchCol();
|
||||
$missing_roles = array_diff($config_roles, array_keys($roles));
|
||||
|
||||
// Core flags node access for rebuild on enable, so skip node updates.
|
||||
foreach ($missing_roles as $rid) {
|
||||
taxonomy_access_delete_role_grants($rid, FALSE);
|
||||
}
|
||||
|
||||
// Delete any term configurations not in {taxonomy_term_data}.
|
||||
$term_ids =
|
||||
db_query(
|
||||
"SELECT ta.tid
|
||||
FROM {taxonomy_access_term} ta
|
||||
LEFT JOIN {taxonomy_term_data} td ON ta.tid = td.tid
|
||||
WHERE ta.tid <> :tid AND td.tid IS NULL",
|
||||
array(':tid' => TAXONOMY_ACCESS_VOCABULARY_DEFAULT))
|
||||
->fetchCol()
|
||||
;
|
||||
|
||||
// Core flags node access for rebuild on enable, so skip node updates.
|
||||
taxonomy_access_delete_term_grants($term_ids, NULL, FALSE);
|
||||
unset($term_ids);
|
||||
|
||||
// Delete any defaults for vocabularies not in {taxonomy_vocabulary}.
|
||||
$vocab_ids =
|
||||
db_query(
|
||||
"SELECT tad.vid
|
||||
FROM {taxonomy_access_default} tad
|
||||
LEFT JOIN {taxonomy_vocabulary} tv ON tad.vid = tv.vid
|
||||
WHERE tad.vid <> :vid AND tv.vid IS NULL",
|
||||
array(':vid' => TAXONOMY_ACCESS_GLOBAL_DEFAULT))
|
||||
->fetchCol()
|
||||
;
|
||||
|
||||
// Core flags node access for rebuild on enable, so skip node updates.
|
||||
taxonomy_access_delete_default_grants($vocab_ids, FALSE);
|
||||
unset($vocab_ids);
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -31,5 +31,71 @@ function showroom_field_default_field_bases() {
|
||||
'type' => 'text_with_summary',
|
||||
);
|
||||
|
||||
// Exported field_base: 'field_showroom'.
|
||||
$field_bases['field_showroom'] = array(
|
||||
'active' => 1,
|
||||
'cardinality' => 1,
|
||||
'deleted' => 0,
|
||||
'entity_types' => array(),
|
||||
'field_name' => 'field_showroom',
|
||||
'field_permissions' => array(
|
||||
'type' => 2,
|
||||
),
|
||||
'indexes' => array(
|
||||
'tid' => array(
|
||||
0 => 'tid',
|
||||
),
|
||||
),
|
||||
'locked' => 0,
|
||||
'module' => 'taxonomy',
|
||||
'settings' => array(
|
||||
'allowed_values' => array(
|
||||
0 => array(
|
||||
'vocabulary' => 'showroom',
|
||||
'parent' => 0,
|
||||
'depth' => '',
|
||||
),
|
||||
),
|
||||
'entity_translation_sync' => FALSE,
|
||||
'options_list_callback' => 'content_taxonomy_allowed_values',
|
||||
'profile2_private' => FALSE,
|
||||
),
|
||||
'translatable' => 0,
|
||||
'type' => 'taxonomy_term_reference',
|
||||
);
|
||||
|
||||
// Exported field_base: 'field_tode_showroom'.
|
||||
$field_bases['field_tode_showroom'] = array(
|
||||
'active' => 1,
|
||||
'cardinality' => 1,
|
||||
'deleted' => 0,
|
||||
'entity_types' => array(),
|
||||
'field_name' => 'field_tode_showroom',
|
||||
'field_permissions' => array(
|
||||
'type' => 2,
|
||||
),
|
||||
'indexes' => array(
|
||||
'tid' => array(
|
||||
0 => 'tid',
|
||||
),
|
||||
),
|
||||
'locked' => 0,
|
||||
'module' => 'taxonomy',
|
||||
'settings' => array(
|
||||
'allowed_values' => array(
|
||||
0 => array(
|
||||
'vocabulary' => 'showroom',
|
||||
'parent' => 0,
|
||||
'depth' => '',
|
||||
),
|
||||
),
|
||||
'entity_translation_sync' => FALSE,
|
||||
'options_list_callback' => 'content_taxonomy_allowed_values',
|
||||
'profile2_private' => FALSE,
|
||||
),
|
||||
'translatable' => 0,
|
||||
'type' => 'taxonomy_term_reference',
|
||||
);
|
||||
|
||||
return $field_bases;
|
||||
}
|
||||
|
@ -10,6 +10,904 @@
|
||||
function showroom_field_default_field_instances() {
|
||||
$field_instances = array();
|
||||
|
||||
// Exported field_instance: 'node-showroom-body'.
|
||||
$field_instances['node-showroom-body'] = array(
|
||||
'bundle' => 'showroom',
|
||||
'default_value' => NULL,
|
||||
'deleted' => 0,
|
||||
'description' => '',
|
||||
'display' => array(
|
||||
'bookmark' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'cardbig' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'cardfull' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'cardmedium' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'cardsmall' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'default' => array(
|
||||
'label' => 'hidden',
|
||||
'module' => 'text',
|
||||
'settings' => array(),
|
||||
'type' => 'text_default',
|
||||
'weight' => 0,
|
||||
),
|
||||
'homeblock' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'teaser' => array(
|
||||
'label' => 'hidden',
|
||||
'module' => 'text',
|
||||
'settings' => array(
|
||||
'trim_length' => 600,
|
||||
),
|
||||
'type' => 'text_summary_or_trimmed',
|
||||
'weight' => 0,
|
||||
),
|
||||
),
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'body',
|
||||
'label' => 'Body',
|
||||
'required' => FALSE,
|
||||
'settings' => array(
|
||||
'display_summary' => TRUE,
|
||||
'entity_translation_sync' => FALSE,
|
||||
'text_processing' => 1,
|
||||
'user_register_form' => FALSE,
|
||||
),
|
||||
'widget' => array(
|
||||
'module' => 'text',
|
||||
'settings' => array(
|
||||
'rows' => 20,
|
||||
'summary_rows' => 5,
|
||||
),
|
||||
'type' => 'text_textarea_with_summary',
|
||||
'weight' => 5,
|
||||
),
|
||||
);
|
||||
|
||||
// Exported field_instance: 'node-showroom-field_public_address'.
|
||||
$field_instances['node-showroom-field_public_address'] = array(
|
||||
'bundle' => 'showroom',
|
||||
'default_value' => NULL,
|
||||
'deleted' => 0,
|
||||
'description' => '',
|
||||
'display' => array(
|
||||
'bookmark' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'cardbig' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'cardfull' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'cardmedium' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'cardsmall' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'default' => array(
|
||||
'label' => 'above',
|
||||
'module' => 'addressfield',
|
||||
'settings' => array(
|
||||
'format_handlers' => array(
|
||||
0 => 'address',
|
||||
),
|
||||
'use_widget_handlers' => 1,
|
||||
),
|
||||
'type' => 'addressfield_default',
|
||||
'weight' => 2,
|
||||
),
|
||||
'homeblock' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'teaser' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
),
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_public_address',
|
||||
'label' => 'Adresse',
|
||||
'required' => 0,
|
||||
'settings' => array(
|
||||
'entity_translation_sync' => FALSE,
|
||||
'user_register_form' => FALSE,
|
||||
),
|
||||
'widget' => array(
|
||||
'active' => 1,
|
||||
'module' => 'addressfield',
|
||||
'settings' => array(
|
||||
'available_countries' => array(
|
||||
'AD' => 'AD',
|
||||
'AE' => 'AE',
|
||||
'AF' => 'AF',
|
||||
'AG' => 'AG',
|
||||
'AI' => 'AI',
|
||||
'AL' => 'AL',
|
||||
'AM' => 'AM',
|
||||
'AN' => 'AN',
|
||||
'AO' => 'AO',
|
||||
'AQ' => 'AQ',
|
||||
'AR' => 'AR',
|
||||
'AS' => 'AS',
|
||||
'AT' => 'AT',
|
||||
'AU' => 'AU',
|
||||
'AW' => 'AW',
|
||||
'AX' => 'AX',
|
||||
'AZ' => 'AZ',
|
||||
'BA' => 'BA',
|
||||
'BB' => 'BB',
|
||||
'BD' => 'BD',
|
||||
'BE' => 'BE',
|
||||
'BF' => 'BF',
|
||||
'BG' => 'BG',
|
||||
'BH' => 'BH',
|
||||
'BI' => 'BI',
|
||||
'BJ' => 'BJ',
|
||||
'BL' => 'BL',
|
||||
'BM' => 'BM',
|
||||
'BN' => 'BN',
|
||||
'BO' => 'BO',
|
||||
'BQ' => 'BQ',
|
||||
'BR' => 'BR',
|
||||
'BS' => 'BS',
|
||||
'BT' => 'BT',
|
||||
'BV' => 'BV',
|
||||
'BW' => 'BW',
|
||||
'BY' => 'BY',
|
||||
'BZ' => 'BZ',
|
||||
'CA' => 'CA',
|
||||
'CC' => 'CC',
|
||||
'CD' => 'CD',
|
||||
'CF' => 'CF',
|
||||
'CG' => 'CG',
|
||||
'CH' => 'CH',
|
||||
'CI' => 'CI',
|
||||
'CK' => 'CK',
|
||||
'CL' => 'CL',
|
||||
'CM' => 'CM',
|
||||
'CN' => 'CN',
|
||||
'CO' => 'CO',
|
||||
'CR' => 'CR',
|
||||
'CU' => 'CU',
|
||||
'CV' => 'CV',
|
||||
'CW' => 'CW',
|
||||
'CX' => 'CX',
|
||||
'CY' => 'CY',
|
||||
'CZ' => 'CZ',
|
||||
'DE' => 'DE',
|
||||
'DJ' => 'DJ',
|
||||
'DK' => 'DK',
|
||||
'DM' => 'DM',
|
||||
'DO' => 'DO',
|
||||
'DZ' => 'DZ',
|
||||
'EC' => 'EC',
|
||||
'EE' => 'EE',
|
||||
'EG' => 'EG',
|
||||
'EH' => 'EH',
|
||||
'ER' => 'ER',
|
||||
'ES' => 'ES',
|
||||
'ET' => 'ET',
|
||||
'FI' => 'FI',
|
||||
'FJ' => 'FJ',
|
||||
'FK' => 'FK',
|
||||
'FM' => 'FM',
|
||||
'FO' => 'FO',
|
||||
'FR' => 'FR',
|
||||
'GA' => 'GA',
|
||||
'GB' => 'GB',
|
||||
'GD' => 'GD',
|
||||
'GE' => 'GE',
|
||||
'GF' => 'GF',
|
||||
'GG' => 'GG',
|
||||
'GH' => 'GH',
|
||||
'GI' => 'GI',
|
||||
'GL' => 'GL',
|
||||
'GM' => 'GM',
|
||||
'GN' => 'GN',
|
||||
'GP' => 'GP',
|
||||
'GQ' => 'GQ',
|
||||
'GR' => 'GR',
|
||||
'GS' => 'GS',
|
||||
'GT' => 'GT',
|
||||
'GU' => 'GU',
|
||||
'GW' => 'GW',
|
||||
'GY' => 'GY',
|
||||
'HK' => 'HK',
|
||||
'HM' => 'HM',
|
||||
'HN' => 'HN',
|
||||
'HR' => 'HR',
|
||||
'HT' => 'HT',
|
||||
'HU' => 'HU',
|
||||
'ID' => 'ID',
|
||||
'IE' => 'IE',
|
||||
'IL' => 'IL',
|
||||
'IM' => 'IM',
|
||||
'IN' => 'IN',
|
||||
'IO' => 'IO',
|
||||
'IQ' => 'IQ',
|
||||
'IR' => 'IR',
|
||||
'IS' => 'IS',
|
||||
'IT' => 'IT',
|
||||
'JE' => 'JE',
|
||||
'JM' => 'JM',
|
||||
'JO' => 'JO',
|
||||
'JP' => 'JP',
|
||||
'KE' => 'KE',
|
||||
'KG' => 'KG',
|
||||
'KH' => 'KH',
|
||||
'KI' => 'KI',
|
||||
'KM' => 'KM',
|
||||
'KN' => 'KN',
|
||||
'KP' => 'KP',
|
||||
'KR' => 'KR',
|
||||
'KW' => 'KW',
|
||||
'KY' => 'KY',
|
||||
'KZ' => 'KZ',
|
||||
'LA' => 'LA',
|
||||
'LB' => 'LB',
|
||||
'LC' => 'LC',
|
||||
'LI' => 'LI',
|
||||
'LK' => 'LK',
|
||||
'LR' => 'LR',
|
||||
'LS' => 'LS',
|
||||
'LT' => 'LT',
|
||||
'LU' => 'LU',
|
||||
'LV' => 'LV',
|
||||
'LY' => 'LY',
|
||||
'MA' => 'MA',
|
||||
'MC' => 'MC',
|
||||
'MD' => 'MD',
|
||||
'ME' => 'ME',
|
||||
'MF' => 'MF',
|
||||
'MG' => 'MG',
|
||||
'MH' => 'MH',
|
||||
'MK' => 'MK',
|
||||
'ML' => 'ML',
|
||||
'MM' => 'MM',
|
||||
'MN' => 'MN',
|
||||
'MO' => 'MO',
|
||||
'MP' => 'MP',
|
||||
'MQ' => 'MQ',
|
||||
'MR' => 'MR',
|
||||
'MS' => 'MS',
|
||||
'MT' => 'MT',
|
||||
'MU' => 'MU',
|
||||
'MV' => 'MV',
|
||||
'MW' => 'MW',
|
||||
'MX' => 'MX',
|
||||
'MY' => 'MY',
|
||||
'MZ' => 'MZ',
|
||||
'NA' => 'NA',
|
||||
'NC' => 'NC',
|
||||
'NE' => 'NE',
|
||||
'NF' => 'NF',
|
||||
'NG' => 'NG',
|
||||
'NI' => 'NI',
|
||||
'NL' => 'NL',
|
||||
'NO' => 'NO',
|
||||
'NP' => 'NP',
|
||||
'NR' => 'NR',
|
||||
'NU' => 'NU',
|
||||
'NZ' => 'NZ',
|
||||
'OM' => 'OM',
|
||||
'PA' => 'PA',
|
||||
'PE' => 'PE',
|
||||
'PF' => 'PF',
|
||||
'PG' => 'PG',
|
||||
'PH' => 'PH',
|
||||
'PK' => 'PK',
|
||||
'PL' => 'PL',
|
||||
'PM' => 'PM',
|
||||
'PN' => 'PN',
|
||||
'PR' => 'PR',
|
||||
'PS' => 'PS',
|
||||
'PT' => 'PT',
|
||||
'PW' => 'PW',
|
||||
'PY' => 'PY',
|
||||
'QA' => 'QA',
|
||||
'RE' => 'RE',
|
||||
'RO' => 'RO',
|
||||
'RS' => 'RS',
|
||||
'RU' => 'RU',
|
||||
'RW' => 'RW',
|
||||
'SA' => 'SA',
|
||||
'SB' => 'SB',
|
||||
'SC' => 'SC',
|
||||
'SD' => 'SD',
|
||||
'SE' => 'SE',
|
||||
'SG' => 'SG',
|
||||
'SH' => 'SH',
|
||||
'SI' => 'SI',
|
||||
'SJ' => 'SJ',
|
||||
'SK' => 'SK',
|
||||
'SL' => 'SL',
|
||||
'SM' => 'SM',
|
||||
'SN' => 'SN',
|
||||
'SO' => 'SO',
|
||||
'SR' => 'SR',
|
||||
'SS' => 'SS',
|
||||
'ST' => 'ST',
|
||||
'SV' => 'SV',
|
||||
'SX' => 'SX',
|
||||
'SY' => 'SY',
|
||||
'SZ' => 'SZ',
|
||||
'TC' => 'TC',
|
||||
'TD' => 'TD',
|
||||
'TF' => 'TF',
|
||||
'TG' => 'TG',
|
||||
'TH' => 'TH',
|
||||
'TJ' => 'TJ',
|
||||
'TK' => 'TK',
|
||||
'TL' => 'TL',
|
||||
'TM' => 'TM',
|
||||
'TN' => 'TN',
|
||||
'TO' => 'TO',
|
||||
'TR' => 'TR',
|
||||
'TT' => 'TT',
|
||||
'TV' => 'TV',
|
||||
'TW' => 'TW',
|
||||
'TZ' => 'TZ',
|
||||
'UA' => 'UA',
|
||||
'UG' => 'UG',
|
||||
'UM' => 'UM',
|
||||
'US' => 'US',
|
||||
'UY' => 'UY',
|
||||
'UZ' => 'UZ',
|
||||
'VA' => 'VA',
|
||||
'VC' => 'VC',
|
||||
'VE' => 'VE',
|
||||
'VG' => 'VG',
|
||||
'VI' => 'VI',
|
||||
'VN' => 'VN',
|
||||
'VU' => 'VU',
|
||||
'WF' => 'WF',
|
||||
'WS' => 'WS',
|
||||
'YE' => 'YE',
|
||||
'YT' => 'YT',
|
||||
'ZA' => 'ZA',
|
||||
'ZM' => 'ZM',
|
||||
'ZW' => 'ZW',
|
||||
),
|
||||
'default_country' => '',
|
||||
'format_handlers' => array(
|
||||
'address' => 'address',
|
||||
'address-hide-postal-code' => 0,
|
||||
'address-hide-street' => 0,
|
||||
'address-hide-country' => 0,
|
||||
'organisation' => 0,
|
||||
'name-full' => 0,
|
||||
'name-oneline' => 0,
|
||||
'address-optional' => 0,
|
||||
),
|
||||
),
|
||||
'type' => 'addressfield_standard',
|
||||
'weight' => 8,
|
||||
),
|
||||
);
|
||||
|
||||
// Exported field_instance: 'node-showroom-field_public_email'.
|
||||
$field_instances['node-showroom-field_public_email'] = array(
|
||||
'bundle' => 'showroom',
|
||||
'default_value' => NULL,
|
||||
'deleted' => 0,
|
||||
'description' => '',
|
||||
'display' => array(
|
||||
'bookmark' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'cardbig' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'cardfull' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'cardmedium' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'cardsmall' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'default' => array(
|
||||
'label' => 'above',
|
||||
'module' => 'email',
|
||||
'settings' => array(),
|
||||
'type' => 'email_default',
|
||||
'weight' => 3,
|
||||
),
|
||||
'homeblock' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'teaser' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
),
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_public_email',
|
||||
'label' => 'Email',
|
||||
'required' => 0,
|
||||
'settings' => array(
|
||||
'entity_translation_sync' => FALSE,
|
||||
'user_register_form' => FALSE,
|
||||
),
|
||||
'widget' => array(
|
||||
'active' => 1,
|
||||
'module' => 'email',
|
||||
'settings' => array(
|
||||
'size' => 60,
|
||||
),
|
||||
'type' => 'email_textfield',
|
||||
'weight' => 10,
|
||||
),
|
||||
);
|
||||
|
||||
// Exported field_instance: 'node-showroom-field_public_phone'.
|
||||
$field_instances['node-showroom-field_public_phone'] = array(
|
||||
'bundle' => 'showroom',
|
||||
'deleted' => 0,
|
||||
'description' => '',
|
||||
'display' => array(
|
||||
'bookmark' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'cardbig' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'cardfull' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'cardmedium' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'cardsmall' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'default' => array(
|
||||
'label' => 'above',
|
||||
'module' => 'cck_phone',
|
||||
'settings' => array(),
|
||||
'type' => 'global_phone_number',
|
||||
'weight' => 4,
|
||||
),
|
||||
'homeblock' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'teaser' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
),
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_public_phone',
|
||||
'label' => 'Phone',
|
||||
'required' => 0,
|
||||
'settings' => array(
|
||||
'all_country_codes' => 1,
|
||||
'country_code_position' => 'after',
|
||||
'country_codes' => array(
|
||||
'country_selection' => array(
|
||||
'ad' => 0,
|
||||
'ae' => 0,
|
||||
'af' => 0,
|
||||
'ag' => 0,
|
||||
'ai' => 0,
|
||||
'al' => 0,
|
||||
'am' => 0,
|
||||
'an' => 0,
|
||||
'ao' => 0,
|
||||
'ar' => 0,
|
||||
'as' => 0,
|
||||
'at' => 0,
|
||||
'au' => 0,
|
||||
'aw' => 0,
|
||||
'az' => 0,
|
||||
'ba' => 0,
|
||||
'bb' => 0,
|
||||
'bd' => 0,
|
||||
'be' => 0,
|
||||
'bf' => 0,
|
||||
'bg' => 0,
|
||||
'bh' => 0,
|
||||
'bi' => 0,
|
||||
'bj' => 0,
|
||||
'bm' => 0,
|
||||
'bn' => 0,
|
||||
'bo' => 0,
|
||||
'br' => 0,
|
||||
'bs' => 0,
|
||||
'bt' => 0,
|
||||
'bw' => 0,
|
||||
'by' => 0,
|
||||
'bz' => 0,
|
||||
'ca' => 0,
|
||||
'cc' => 0,
|
||||
'cd' => 0,
|
||||
'cf' => 0,
|
||||
'cg' => 0,
|
||||
'ch' => 0,
|
||||
'ci' => 0,
|
||||
'ck' => 0,
|
||||
'cl' => 0,
|
||||
'cm' => 0,
|
||||
'cn' => 0,
|
||||
'co' => 0,
|
||||
'cr' => 0,
|
||||
'cu' => 0,
|
||||
'cv' => 0,
|
||||
'cx' => 0,
|
||||
'cy' => 0,
|
||||
'cz' => 0,
|
||||
'de' => 0,
|
||||
'dj' => 0,
|
||||
'dk' => 0,
|
||||
'dm' => 0,
|
||||
'do' => 0,
|
||||
'dz' => 0,
|
||||
'ec' => 0,
|
||||
'ee' => 0,
|
||||
'eg' => 0,
|
||||
'er' => 0,
|
||||
'es' => 0,
|
||||
'et' => 0,
|
||||
'fi' => 0,
|
||||
'fj' => 0,
|
||||
'fk' => 0,
|
||||
'fm' => 0,
|
||||
'fo' => 0,
|
||||
'fr' => 0,
|
||||
'ga' => 0,
|
||||
'gb' => 0,
|
||||
'gd' => 0,
|
||||
'ge' => 0,
|
||||
'gf' => 0,
|
||||
'gh' => 0,
|
||||
'gi' => 0,
|
||||
'gl' => 0,
|
||||
'gm' => 0,
|
||||
'gn' => 0,
|
||||
'gp' => 0,
|
||||
'gq' => 0,
|
||||
'gr' => 0,
|
||||
'gt' => 0,
|
||||
'gu' => 0,
|
||||
'gw' => 0,
|
||||
'gy' => 0,
|
||||
'hk' => 0,
|
||||
'hn' => 0,
|
||||
'hr' => 0,
|
||||
'ht' => 0,
|
||||
'hu' => 0,
|
||||
'id' => 0,
|
||||
'ie' => 0,
|
||||
'il' => 0,
|
||||
'in' => 0,
|
||||
'io' => 0,
|
||||
'iq' => 0,
|
||||
'ir' => 0,
|
||||
'is' => 0,
|
||||
'it' => 0,
|
||||
'jm' => 0,
|
||||
'jo' => 0,
|
||||
'jp' => 0,
|
||||
'ke' => 0,
|
||||
'kg' => 0,
|
||||
'kh' => 0,
|
||||
'ki' => 0,
|
||||
'km' => 0,
|
||||
'kn' => 0,
|
||||
'kp' => 0,
|
||||
'kr' => 0,
|
||||
'kw' => 0,
|
||||
'ky' => 0,
|
||||
'kz' => 0,
|
||||
'la' => 0,
|
||||
'lb' => 0,
|
||||
'lc' => 0,
|
||||
'li' => 0,
|
||||
'lk' => 0,
|
||||
'lr' => 0,
|
||||
'ls' => 0,
|
||||
'lt' => 0,
|
||||
'lu' => 0,
|
||||
'lv' => 0,
|
||||
'ly' => 0,
|
||||
'ma' => 0,
|
||||
'mc' => 0,
|
||||
'md' => 0,
|
||||
'me' => 0,
|
||||
'mg' => 0,
|
||||
'mh' => 0,
|
||||
'mk' => 0,
|
||||
'ml' => 0,
|
||||
'mm' => 0,
|
||||
'mn' => 0,
|
||||
'mo' => 0,
|
||||
'mp' => 0,
|
||||
'mq' => 0,
|
||||
'mr' => 0,
|
||||
'ms' => 0,
|
||||
'mt' => 0,
|
||||
'mu' => 0,
|
||||
'mv' => 0,
|
||||
'mw' => 0,
|
||||
'mx' => 0,
|
||||
'my' => 0,
|
||||
'mz' => 0,
|
||||
'na' => 0,
|
||||
'nc' => 0,
|
||||
'ne' => 0,
|
||||
'nf' => 0,
|
||||
'ng' => 0,
|
||||
'ni' => 0,
|
||||
'nl' => 0,
|
||||
'no' => 0,
|
||||
'np' => 0,
|
||||
'nr' => 0,
|
||||
'nu' => 0,
|
||||
'nz' => 0,
|
||||
'om' => 0,
|
||||
'pa' => 0,
|
||||
'pe' => 0,
|
||||
'pf' => 0,
|
||||
'pg' => 0,
|
||||
'ph' => 0,
|
||||
'pk' => 0,
|
||||
'pl' => 0,
|
||||
'pm' => 0,
|
||||
'pr' => 0,
|
||||
'ps' => 0,
|
||||
'pt' => 0,
|
||||
'pw' => 0,
|
||||
'py' => 0,
|
||||
'qa' => 0,
|
||||
'ro' => 0,
|
||||
'rs' => 0,
|
||||
'ru' => 0,
|
||||
'rw' => 0,
|
||||
'sa' => 0,
|
||||
'sb' => 0,
|
||||
'sc' => 0,
|
||||
'sd' => 0,
|
||||
'se' => 0,
|
||||
'sg' => 0,
|
||||
'sh' => 0,
|
||||
'si' => 0,
|
||||
'sk' => 0,
|
||||
'sl' => 0,
|
||||
'sm' => 0,
|
||||
'sn' => 0,
|
||||
'so' => 0,
|
||||
'sr' => 0,
|
||||
'ss' => 0,
|
||||
'st' => 0,
|
||||
'sv' => 0,
|
||||
'sy' => 0,
|
||||
'sz' => 0,
|
||||
'tc' => 0,
|
||||
'td' => 0,
|
||||
'tg' => 0,
|
||||
'th' => 0,
|
||||
'tj' => 0,
|
||||
'tk' => 0,
|
||||
'tm' => 0,
|
||||
'tn' => 0,
|
||||
'to' => 0,
|
||||
'tp' => 0,
|
||||
'tr' => 0,
|
||||
'tt' => 0,
|
||||
'tv' => 0,
|
||||
'tw' => 0,
|
||||
'tz' => 0,
|
||||
'ua' => 0,
|
||||
'ug' => 0,
|
||||
'us' => 0,
|
||||
'uy' => 0,
|
||||
'uz' => 0,
|
||||
'va' => 0,
|
||||
'vc' => 0,
|
||||
've' => 0,
|
||||
'vg' => 0,
|
||||
'vi' => 0,
|
||||
'vn' => 0,
|
||||
'vu' => 0,
|
||||
'wf' => 0,
|
||||
'ws' => 0,
|
||||
'ye' => 0,
|
||||
'yt' => 0,
|
||||
'za' => 0,
|
||||
'zm' => 0,
|
||||
'zw' => 0,
|
||||
),
|
||||
'hide_single_cc' => 0,
|
||||
),
|
||||
'default_country' => 'af',
|
||||
'enable_country_level_validation' => 1,
|
||||
'enable_default_country' => 0,
|
||||
'enable_extension' => 0,
|
||||
'entity_translation_sync' => FALSE,
|
||||
'user_register_form' => FALSE,
|
||||
),
|
||||
'widget' => array(
|
||||
'active' => 0,
|
||||
'module' => 'cck_phone',
|
||||
'settings' => array(
|
||||
'size' => 15,
|
||||
),
|
||||
'type' => 'phone_number',
|
||||
'weight' => 12,
|
||||
),
|
||||
);
|
||||
|
||||
// Exported field_instance: 'node-showroom-field_tode_showroom'.
|
||||
$field_instances['node-showroom-field_tode_showroom'] = array(
|
||||
'bundle' => 'showroom',
|
||||
'deleted' => 0,
|
||||
'description' => '',
|
||||
'display' => array(
|
||||
'bookmark' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'cardbig' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'cardfull' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'cardmedium' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'cardsmall' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'default' => array(
|
||||
'label' => 'above',
|
||||
'module' => 'taxonomy',
|
||||
'settings' => array(),
|
||||
'type' => 'taxonomy_term_reference_link',
|
||||
'weight' => 1,
|
||||
),
|
||||
'homeblock' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
'teaser' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
),
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_tode_showroom',
|
||||
'label' => 'Showroom',
|
||||
'required' => 0,
|
||||
'settings' => array(
|
||||
'entity_translation_sync' => FALSE,
|
||||
'user_register_form' => FALSE,
|
||||
),
|
||||
'widget' => array(
|
||||
'active' => 1,
|
||||
'module' => 'tode',
|
||||
'settings' => array(
|
||||
'choose_term_parent' => 0,
|
||||
'maxlength' => 255,
|
||||
'redirect_node_to_term' => 0,
|
||||
'redirect_term_to_node' => 1,
|
||||
'show_create_tode' => 0,
|
||||
'show_term_form' => 0,
|
||||
'size' => 60,
|
||||
),
|
||||
'type' => 'tode',
|
||||
'weight' => 1,
|
||||
),
|
||||
);
|
||||
|
||||
// Exported field_instance: 'taxonomy_term-showroom-description_field'.
|
||||
$field_instances['taxonomy_term-showroom-description_field'] = array(
|
||||
'bundle' => 'showroom',
|
||||
@ -86,10 +984,49 @@ function showroom_field_default_field_instances() {
|
||||
),
|
||||
);
|
||||
|
||||
// Exported field_instance: 'user-user-field_showroom'.
|
||||
$field_instances['user-user-field_showroom'] = array(
|
||||
'bundle' => 'user',
|
||||
'default_value' => NULL,
|
||||
'deleted' => 0,
|
||||
'description' => '',
|
||||
'display' => array(
|
||||
'default' => array(
|
||||
'label' => 'above',
|
||||
'module' => 'taxonomy',
|
||||
'settings' => array(),
|
||||
'type' => 'taxonomy_term_reference_link',
|
||||
'weight' => 2,
|
||||
),
|
||||
),
|
||||
'entity_type' => 'user',
|
||||
'field_name' => 'field_showroom',
|
||||
'label' => 'Showroom',
|
||||
'required' => 0,
|
||||
'settings' => array(
|
||||
'entity_translation_sync' => FALSE,
|
||||
'user_register_form' => 1,
|
||||
),
|
||||
'widget' => array(
|
||||
'active' => 1,
|
||||
'module' => 'options',
|
||||
'settings' => array(
|
||||
'content_taxonomy_opt_groups' => 0,
|
||||
),
|
||||
'type' => 'options_select',
|
||||
'weight' => 3,
|
||||
),
|
||||
);
|
||||
|
||||
// Translatables
|
||||
// Included for use with string extractors like potx.
|
||||
t('Adresse');
|
||||
t('Body');
|
||||
t('Description');
|
||||
t('Email');
|
||||
t('Nom');
|
||||
t('Phone');
|
||||
t('Showroom');
|
||||
|
||||
return $field_instances;
|
||||
}
|
||||
|
@ -12,3 +12,21 @@ function showroom_ctools_plugin_api($module = NULL, $api = NULL) {
|
||||
return array("version" => "1");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_info().
|
||||
*/
|
||||
function showroom_node_info() {
|
||||
$items = array(
|
||||
'showroom' => array(
|
||||
'name' => t('Showroom'),
|
||||
'base' => 'node_content',
|
||||
'description' => '',
|
||||
'has_title' => '1',
|
||||
'title_label' => t('Name'),
|
||||
'help' => '',
|
||||
),
|
||||
);
|
||||
drupal_alter('node_info', $items);
|
||||
return $items;
|
||||
}
|
||||
|
@ -10,20 +10,166 @@
|
||||
function showroom_user_default_permissions() {
|
||||
$permissions = array();
|
||||
|
||||
// Exported permission: 'assign Showroom role'.
|
||||
$permissions['assign Showroom role'] = array(
|
||||
'name' => 'assign Showroom role',
|
||||
'roles' => array(
|
||||
'administrator' => 'administrator',
|
||||
'root' => 'root',
|
||||
),
|
||||
'module' => 'role_delegation',
|
||||
);
|
||||
|
||||
// Exported permission: 'create field_showroom'.
|
||||
$permissions['create field_showroom'] = array(
|
||||
'name' => 'create field_showroom',
|
||||
'roles' => array(
|
||||
'administrator' => 'administrator',
|
||||
'root' => 'root',
|
||||
),
|
||||
'module' => 'field_permissions',
|
||||
);
|
||||
|
||||
// Exported permission: 'create field_tode_showroom'.
|
||||
$permissions['create field_tode_showroom'] = array(
|
||||
'name' => 'create field_tode_showroom',
|
||||
'roles' => array(
|
||||
'administrator' => 'administrator',
|
||||
'root' => 'root',
|
||||
),
|
||||
'module' => 'field_permissions',
|
||||
);
|
||||
|
||||
// Exported permission: 'create showroom content'.
|
||||
$permissions['create showroom content'] = array(
|
||||
'name' => 'create showroom content',
|
||||
'roles' => array(
|
||||
'administrator' => 'administrator',
|
||||
),
|
||||
'module' => 'node',
|
||||
);
|
||||
|
||||
// Exported permission: 'delete any showroom content'.
|
||||
$permissions['delete any showroom content'] = array(
|
||||
'name' => 'delete any showroom content',
|
||||
'roles' => array(
|
||||
'administrator' => 'administrator',
|
||||
),
|
||||
'module' => 'node',
|
||||
);
|
||||
|
||||
// Exported permission: 'delete own showroom content'.
|
||||
$permissions['delete own showroom content'] = array(
|
||||
'name' => 'delete own showroom content',
|
||||
'roles' => array(
|
||||
'administrator' => 'administrator',
|
||||
),
|
||||
'module' => 'node',
|
||||
);
|
||||
|
||||
// Exported permission: 'delete terms in showroom'.
|
||||
$permissions['delete terms in showroom'] = array(
|
||||
'name' => 'delete terms in showroom',
|
||||
'roles' => array(),
|
||||
'roles' => array(
|
||||
'administrator' => 'administrator',
|
||||
),
|
||||
'module' => 'taxonomy',
|
||||
);
|
||||
|
||||
// Exported permission: 'delete users with role 15'.
|
||||
$permissions['delete users with role 15'] = array(
|
||||
'name' => 'delete users with role 15',
|
||||
'roles' => array(
|
||||
'administrator' => 'administrator',
|
||||
'root' => 'root',
|
||||
),
|
||||
'module' => 'administerusersbyrole',
|
||||
);
|
||||
|
||||
// Exported permission: 'edit any showroom content'.
|
||||
$permissions['edit any showroom content'] = array(
|
||||
'name' => 'edit any showroom content',
|
||||
'roles' => array(
|
||||
'administrator' => 'administrator',
|
||||
),
|
||||
'module' => 'node',
|
||||
);
|
||||
|
||||
// Exported permission: 'edit field_showroom'.
|
||||
$permissions['edit field_showroom'] = array(
|
||||
'name' => 'edit field_showroom',
|
||||
'roles' => array(
|
||||
'administrator' => 'administrator',
|
||||
'root' => 'root',
|
||||
),
|
||||
'module' => 'field_permissions',
|
||||
);
|
||||
|
||||
// Exported permission: 'edit field_tode_showroom'.
|
||||
$permissions['edit field_tode_showroom'] = array(
|
||||
'name' => 'edit field_tode_showroom',
|
||||
'roles' => array(
|
||||
'administrator' => 'administrator',
|
||||
'root' => 'root',
|
||||
),
|
||||
'module' => 'field_permissions',
|
||||
);
|
||||
|
||||
// Exported permission: 'edit own field_showroom'.
|
||||
$permissions['edit own field_showroom'] = array(
|
||||
'name' => 'edit own field_showroom',
|
||||
'roles' => array(
|
||||
'administrator' => 'administrator',
|
||||
'root' => 'root',
|
||||
),
|
||||
'module' => 'field_permissions',
|
||||
);
|
||||
|
||||
// Exported permission: 'edit own field_tode_showroom'.
|
||||
$permissions['edit own field_tode_showroom'] = array(
|
||||
'name' => 'edit own field_tode_showroom',
|
||||
'roles' => array(
|
||||
'administrator' => 'administrator',
|
||||
'root' => 'root',
|
||||
),
|
||||
'module' => 'field_permissions',
|
||||
);
|
||||
|
||||
// Exported permission: 'edit own showroom content'.
|
||||
$permissions['edit own showroom content'] = array(
|
||||
'name' => 'edit own showroom content',
|
||||
'roles' => array(
|
||||
'administrator' => 'administrator',
|
||||
),
|
||||
'module' => 'node',
|
||||
);
|
||||
|
||||
// Exported permission: 'edit terms in showroom'.
|
||||
$permissions['edit terms in showroom'] = array(
|
||||
'name' => 'edit terms in showroom',
|
||||
'roles' => array(),
|
||||
'roles' => array(
|
||||
'administrator' => 'administrator',
|
||||
),
|
||||
'module' => 'taxonomy',
|
||||
);
|
||||
|
||||
// Exported permission: 'edit users with role 15'.
|
||||
$permissions['edit users with role 15'] = array(
|
||||
'name' => 'edit users with role 15',
|
||||
'roles' => array(
|
||||
'administrator' => 'administrator',
|
||||
'root' => 'root',
|
||||
),
|
||||
'module' => 'administerusersbyrole',
|
||||
);
|
||||
|
||||
// Exported permission: 'enter showroom revision log entry'.
|
||||
$permissions['enter showroom revision log entry'] = array(
|
||||
'name' => 'enter showroom revision log entry',
|
||||
'roles' => array(),
|
||||
'module' => 'override_node_options',
|
||||
);
|
||||
|
||||
// Exported permission: 'merge showroom terms'.
|
||||
$permissions['merge showroom terms'] = array(
|
||||
'name' => 'merge showroom terms',
|
||||
@ -31,5 +177,95 @@ function showroom_user_default_permissions() {
|
||||
'module' => 'term_merge',
|
||||
);
|
||||
|
||||
// Exported permission: 'override showroom authored by option'.
|
||||
$permissions['override showroom authored by option'] = array(
|
||||
'name' => 'override showroom authored by option',
|
||||
'roles' => array(),
|
||||
'module' => 'override_node_options',
|
||||
);
|
||||
|
||||
// Exported permission: 'override showroom authored on option'.
|
||||
$permissions['override showroom authored on option'] = array(
|
||||
'name' => 'override showroom authored on option',
|
||||
'roles' => array(),
|
||||
'module' => 'override_node_options',
|
||||
);
|
||||
|
||||
// Exported permission: 'override showroom promote to front page option'.
|
||||
$permissions['override showroom promote to front page option'] = array(
|
||||
'name' => 'override showroom promote to front page option',
|
||||
'roles' => array(),
|
||||
'module' => 'override_node_options',
|
||||
);
|
||||
|
||||
// Exported permission: 'override showroom published option'.
|
||||
$permissions['override showroom published option'] = array(
|
||||
'name' => 'override showroom published option',
|
||||
'roles' => array(),
|
||||
'module' => 'override_node_options',
|
||||
);
|
||||
|
||||
// Exported permission: 'override showroom revision option'.
|
||||
$permissions['override showroom revision option'] = array(
|
||||
'name' => 'override showroom revision option',
|
||||
'roles' => array(),
|
||||
'module' => 'override_node_options',
|
||||
);
|
||||
|
||||
// Exported permission: 'override showroom sticky option'.
|
||||
$permissions['override showroom sticky option'] = array(
|
||||
'name' => 'override showroom sticky option',
|
||||
'roles' => array(),
|
||||
'module' => 'override_node_options',
|
||||
);
|
||||
|
||||
// Exported permission: 'show showroom title'.
|
||||
$permissions['show showroom title'] = array(
|
||||
'name' => 'show showroom title',
|
||||
'roles' => array(),
|
||||
'module' => 'materio_page_title',
|
||||
);
|
||||
|
||||
// Exported permission: 'view field_showroom'.
|
||||
$permissions['view field_showroom'] = array(
|
||||
'name' => 'view field_showroom',
|
||||
'roles' => array(
|
||||
'Showroom' => 'Showroom',
|
||||
'administrator' => 'administrator',
|
||||
'root' => 'root',
|
||||
),
|
||||
'module' => 'field_permissions',
|
||||
);
|
||||
|
||||
// Exported permission: 'view field_tode_showroom'.
|
||||
$permissions['view field_tode_showroom'] = array(
|
||||
'name' => 'view field_tode_showroom',
|
||||
'roles' => array(
|
||||
'administrator' => 'administrator',
|
||||
'root' => 'root',
|
||||
),
|
||||
'module' => 'field_permissions',
|
||||
);
|
||||
|
||||
// Exported permission: 'view own field_showroom'.
|
||||
$permissions['view own field_showroom'] = array(
|
||||
'name' => 'view own field_showroom',
|
||||
'roles' => array(
|
||||
'administrator' => 'administrator',
|
||||
'root' => 'root',
|
||||
),
|
||||
'module' => 'field_permissions',
|
||||
);
|
||||
|
||||
// Exported permission: 'view own field_tode_showroom'.
|
||||
$permissions['view own field_tode_showroom'] = array(
|
||||
'name' => 'view own field_tode_showroom',
|
||||
'roles' => array(
|
||||
'administrator' => 'administrator',
|
||||
'root' => 'root',
|
||||
),
|
||||
'module' => 'field_permissions',
|
||||
);
|
||||
|
||||
return $permissions;
|
||||
}
|
||||
|
@ -10,22 +10,10 @@
|
||||
function showroom_user_default_roles() {
|
||||
$roles = array();
|
||||
|
||||
// Exported role: Translator CN.
|
||||
$roles['Translator CN'] = array(
|
||||
'name' => 'Translator CN',
|
||||
'weight' => 12,
|
||||
);
|
||||
|
||||
// Exported role: Translator EN.
|
||||
$roles['Translator EN'] = array(
|
||||
'name' => 'Translator EN',
|
||||
'weight' => 10,
|
||||
);
|
||||
|
||||
// Exported role: Translator FR.
|
||||
$roles['Translator FR'] = array(
|
||||
'name' => 'Translator FR',
|
||||
'weight' => 11,
|
||||
// Exported role: Showroom.
|
||||
$roles['Showroom'] = array(
|
||||
'name' => 'Showroom',
|
||||
'weight' => 13,
|
||||
);
|
||||
|
||||
return $roles;
|
||||
|
@ -1,24 +1,105 @@
|
||||
name = Showroom
|
||||
core = 7.x
|
||||
package = Materio
|
||||
dependencies[] = addressfield
|
||||
dependencies[] = administerusersbyrole
|
||||
dependencies[] = cck_phone
|
||||
dependencies[] = ctools
|
||||
dependencies[] = email
|
||||
dependencies[] = features
|
||||
dependencies[] = field_permissions
|
||||
dependencies[] = materio_content_types
|
||||
dependencies[] = materio_page_title
|
||||
dependencies[] = materio_subscriptions
|
||||
dependencies[] = metatag
|
||||
dependencies[] = node
|
||||
dependencies[] = options
|
||||
dependencies[] = override_node_options
|
||||
dependencies[] = role_delegation
|
||||
dependencies[] = rules
|
||||
dependencies[] = strongarm
|
||||
dependencies[] = taxonomy
|
||||
dependencies[] = taxonomy_access
|
||||
dependencies[] = term_merge
|
||||
dependencies[] = text
|
||||
dependencies[] = tode
|
||||
features[ctools][] = strongarm:strongarm:1
|
||||
features[features_api][] = api:2
|
||||
features[field_base][] = description_field
|
||||
features[field_base][] = field_showroom
|
||||
features[field_base][] = field_tode_showroom
|
||||
features[field_instance][] = node-showroom-body
|
||||
features[field_instance][] = node-showroom-field_public_address
|
||||
features[field_instance][] = node-showroom-field_public_email
|
||||
features[field_instance][] = node-showroom-field_public_phone
|
||||
features[field_instance][] = node-showroom-field_tode_showroom
|
||||
features[field_instance][] = taxonomy_term-showroom-description_field
|
||||
features[field_instance][] = taxonomy_term-showroom-name_field
|
||||
features[field_instance][] = user-user-field_showroom
|
||||
features[node][] = showroom
|
||||
features[rules_config][] = rules_auto_tag_news_with_showroom
|
||||
features[taxonomy][] = showroom
|
||||
features[user_permission][] = assign Showroom role
|
||||
features[user_permission][] = create field_showroom
|
||||
features[user_permission][] = create field_tode_showroom
|
||||
features[user_permission][] = create showroom content
|
||||
features[user_permission][] = delete any showroom content
|
||||
features[user_permission][] = delete own showroom content
|
||||
features[user_permission][] = delete terms in showroom
|
||||
features[user_permission][] = delete users with role 15
|
||||
features[user_permission][] = edit any showroom content
|
||||
features[user_permission][] = edit field_showroom
|
||||
features[user_permission][] = edit field_tode_showroom
|
||||
features[user_permission][] = edit own field_showroom
|
||||
features[user_permission][] = edit own field_tode_showroom
|
||||
features[user_permission][] = edit own showroom content
|
||||
features[user_permission][] = edit terms in showroom
|
||||
features[user_permission][] = edit users with role 15
|
||||
features[user_permission][] = enter showroom revision log entry
|
||||
features[user_permission][] = merge showroom terms
|
||||
features[user_role][] = Translator CN
|
||||
features[user_role][] = Translator EN
|
||||
features[user_role][] = Translator FR
|
||||
features[user_permission][] = override showroom authored by option
|
||||
features[user_permission][] = override showroom authored on option
|
||||
features[user_permission][] = override showroom promote to front page option
|
||||
features[user_permission][] = override showroom published option
|
||||
features[user_permission][] = override showroom revision option
|
||||
features[user_permission][] = override showroom sticky option
|
||||
features[user_permission][] = show showroom title
|
||||
features[user_permission][] = view field_showroom
|
||||
features[user_permission][] = view field_tode_showroom
|
||||
features[user_permission][] = view own field_showroom
|
||||
features[user_permission][] = view own field_tode_showroom
|
||||
features[user_role][] = Showroom
|
||||
features[variable][] = additional_settings__active_tab_showroom
|
||||
features[variable][] = ant_pattern_showroom
|
||||
features[variable][] = ant_php_showroom
|
||||
features[variable][] = ant_showroom
|
||||
features[variable][] = date_popup_authored_enabled_showroom
|
||||
features[variable][] = date_popup_authored_format_showroom
|
||||
features[variable][] = date_popup_authored_year_range_showroom
|
||||
features[variable][] = diff_enable_revisions_page_node_showroom
|
||||
features[variable][] = diff_show_preview_changes_node_showroom
|
||||
features[variable][] = diff_view_mode_preview_node_showroom
|
||||
features[variable][] = entity_translation_hide_translation_links_showroom
|
||||
features[variable][] = entity_translation_node_metadata_showroom
|
||||
features[variable][] = field_bundle_settings_node__showroom
|
||||
features[variable][] = i18n_node_extended_showroom
|
||||
features[variable][] = i18n_node_options_showroom
|
||||
features[variable][] = language_content_type_showroom
|
||||
features[variable][] = menu_options_showroom
|
||||
features[variable][] = menu_parent_showroom
|
||||
features[variable][] = metatag_enable_node__showroom
|
||||
features[variable][] = metatag_enable_taxonomy_term__showroom
|
||||
features[variable][] = node_options_showroom
|
||||
features[variable][] = node_preview_showroom
|
||||
features[variable][] = node_submitted_showroom
|
||||
features[variable][] = nodeformscols_field_placements_showroom_default
|
||||
features[variable][] = print_html_display_comment_showroom
|
||||
features[variable][] = print_html_display_showroom
|
||||
features[variable][] = print_html_display_urllist_showroom
|
||||
features[variable][] = save_continue_showroom
|
||||
features[variable][] = simplenews_content_type_showroom
|
||||
features[variable][] = unique_field_comp_showroom
|
||||
features[variable][] = unique_field_fields_showroom
|
||||
features[variable][] = unique_field_scope_showroom
|
||||
features[variable][] = unique_field_show_matches_showroom
|
||||
project path = sites/all/modules/features
|
||||
|
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* showroom.rules_defaults.inc
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_default_rules_configuration().
|
||||
*/
|
||||
function showroom_default_rules_configuration() {
|
||||
$items = array();
|
||||
$items['rules_auto_tag_news_with_showroom'] = entity_import('rules_config', '{ "rules_auto_tag_news_with_showroom" : {
|
||||
"LABEL" : "auto tag news with showroom",
|
||||
"PLUGIN" : "reaction rule",
|
||||
"REQUIRES" : [ "rules" ],
|
||||
"ON" : [ "node_presave" ],
|
||||
"IF" : [
|
||||
{ "node_is_of_type" : { "node" : [ "node" ], "type" : { "value" : { "breve" : "breve" } } } },
|
||||
{ "user_has_role" : { "account" : [ "node:author" ], "roles" : { "value" : { "15" : "15" } } } }
|
||||
],
|
||||
"DO" : [
|
||||
{ "data_set" : {
|
||||
"data" : [ "node:field-showroom" ],
|
||||
"value" : [ "node:author:field-showroom" ]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}');
|
||||
return $items;
|
||||
}
|
336
sites/all/modules/features/showroom/showroom.strongarm.inc
Normal file
336
sites/all/modules/features/showroom/showroom.strongarm.inc
Normal file
@ -0,0 +1,336 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* showroom.strongarm.inc
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_strongarm().
|
||||
*/
|
||||
function showroom_strongarm() {
|
||||
$export = array();
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'additional_settings__active_tab_showroom';
|
||||
$strongarm->value = 'edit-auto-nodetitle';
|
||||
$export['additional_settings__active_tab_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'ant_pattern_showroom';
|
||||
$strongarm->value = '<?php
|
||||
$items = field_get_items(\'node\', $node, \'field_tode_showroom\');
|
||||
return t($items[0][\'name\']);
|
||||
?>
|
||||
';
|
||||
$export['ant_pattern_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'ant_php_showroom';
|
||||
$strongarm->value = 0;
|
||||
$export['ant_php_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'ant_showroom';
|
||||
$strongarm->value = '1';
|
||||
$export['ant_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'date_popup_authored_enabled_showroom';
|
||||
$strongarm->value = 1;
|
||||
$export['date_popup_authored_enabled_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'date_popup_authored_format_showroom';
|
||||
$strongarm->value = 'Y-m-d H:i';
|
||||
$export['date_popup_authored_format_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'date_popup_authored_year_range_showroom';
|
||||
$strongarm->value = '3';
|
||||
$export['date_popup_authored_year_range_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'diff_enable_revisions_page_node_showroom';
|
||||
$strongarm->value = 1;
|
||||
$export['diff_enable_revisions_page_node_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'diff_show_preview_changes_node_showroom';
|
||||
$strongarm->value = 1;
|
||||
$export['diff_show_preview_changes_node_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'diff_view_mode_preview_node_showroom';
|
||||
$strongarm->value = 'full';
|
||||
$export['diff_view_mode_preview_node_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'entity_translation_hide_translation_links_showroom';
|
||||
$strongarm->value = 0;
|
||||
$export['entity_translation_hide_translation_links_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'entity_translation_node_metadata_showroom';
|
||||
$strongarm->value = '0';
|
||||
$export['entity_translation_node_metadata_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'field_bundle_settings_node__showroom';
|
||||
$strongarm->value = array(
|
||||
'view_modes' => array(),
|
||||
'extra_fields' => array(
|
||||
'form' => array(
|
||||
'metatags' => array(
|
||||
'weight' => '6',
|
||||
),
|
||||
'title' => array(
|
||||
'weight' => '0',
|
||||
),
|
||||
'path' => array(
|
||||
'weight' => '3',
|
||||
),
|
||||
'redirect' => array(
|
||||
'weight' => '4',
|
||||
),
|
||||
'language' => array(
|
||||
'weight' => '2',
|
||||
),
|
||||
),
|
||||
'display' => array(),
|
||||
),
|
||||
);
|
||||
$export['field_bundle_settings_node__showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'i18n_node_extended_showroom';
|
||||
$strongarm->value = 1;
|
||||
$export['i18n_node_extended_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'i18n_node_options_showroom';
|
||||
$strongarm->value = array();
|
||||
$export['i18n_node_options_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'language_content_type_showroom';
|
||||
$strongarm->value = '4';
|
||||
$export['language_content_type_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'menu_options_showroom';
|
||||
$strongarm->value = array();
|
||||
$export['menu_options_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'menu_parent_showroom';
|
||||
$strongarm->value = 'main-menu:0';
|
||||
$export['menu_parent_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'metatag_enable_node__showroom';
|
||||
$strongarm->value = TRUE;
|
||||
$export['metatag_enable_node__showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'metatag_enable_taxonomy_term__showroom';
|
||||
$strongarm->value = TRUE;
|
||||
$export['metatag_enable_taxonomy_term__showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'nodeformscols_field_placements_showroom_default';
|
||||
$strongarm->value = array(
|
||||
'additional_settings' => array(
|
||||
'region' => 'main',
|
||||
'weight' => '5',
|
||||
'has_required' => FALSE,
|
||||
'title' => 'Onglets verticaux',
|
||||
'hidden' => 0,
|
||||
),
|
||||
'actions' => array(
|
||||
'region' => 'right',
|
||||
'weight' => '2',
|
||||
'has_required' => FALSE,
|
||||
'title' => 'Enregistrer',
|
||||
'hidden' => 0,
|
||||
),
|
||||
'entity_translation_entity_form_language_update' => array(
|
||||
'region' => 'right',
|
||||
'weight' => '1',
|
||||
'has_required' => FALSE,
|
||||
'title' => NULL,
|
||||
'hidden' => 0,
|
||||
),
|
||||
'language' => array(
|
||||
'region' => 'right',
|
||||
'weight' => '0',
|
||||
'has_required' => FALSE,
|
||||
'title' => 'Langue',
|
||||
'hidden' => 0,
|
||||
),
|
||||
'body' => array(
|
||||
'region' => 'main',
|
||||
'weight' => '1',
|
||||
'has_required' => FALSE,
|
||||
'title' => 'Body',
|
||||
'hidden' => 0,
|
||||
),
|
||||
'field_tode_showroom' => array(
|
||||
'region' => 'main',
|
||||
'weight' => '0',
|
||||
'has_required' => FALSE,
|
||||
'title' => 'Showroom',
|
||||
'hidden' => 0,
|
||||
),
|
||||
'field_public_address' => array(
|
||||
'region' => 'main',
|
||||
'weight' => '4',
|
||||
'has_required' => TRUE,
|
||||
'title' => 'Adresse',
|
||||
),
|
||||
'field_public_email' => array(
|
||||
'region' => 'main',
|
||||
'weight' => '2',
|
||||
'has_required' => FALSE,
|
||||
'title' => 'Email',
|
||||
'hidden' => 0,
|
||||
),
|
||||
'field_public_phone' => array(
|
||||
'region' => 'main',
|
||||
'weight' => '3',
|
||||
'has_required' => FALSE,
|
||||
'title' => 'Phone',
|
||||
'hidden' => 0,
|
||||
),
|
||||
);
|
||||
$export['nodeformscols_field_placements_showroom_default'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'node_options_showroom';
|
||||
$strongarm->value = array(
|
||||
0 => 'status',
|
||||
);
|
||||
$export['node_options_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'node_preview_showroom';
|
||||
$strongarm->value = '0';
|
||||
$export['node_preview_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'node_submitted_showroom';
|
||||
$strongarm->value = 0;
|
||||
$export['node_submitted_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'print_html_display_comment_showroom';
|
||||
$strongarm->value = 0;
|
||||
$export['print_html_display_comment_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'print_html_display_showroom';
|
||||
$strongarm->value = 0;
|
||||
$export['print_html_display_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'print_html_display_urllist_showroom';
|
||||
$strongarm->value = 0;
|
||||
$export['print_html_display_urllist_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'save_continue_showroom';
|
||||
$strongarm->value = 'Enregistrer et ajouter les champs';
|
||||
$export['save_continue_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'simplenews_content_type_showroom';
|
||||
$strongarm->value = 0;
|
||||
$export['simplenews_content_type_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'unique_field_comp_showroom';
|
||||
$strongarm->value = 'each';
|
||||
$export['unique_field_comp_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'unique_field_fields_showroom';
|
||||
$strongarm->value = array();
|
||||
$export['unique_field_fields_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'unique_field_scope_showroom';
|
||||
$strongarm->value = 'type';
|
||||
$export['unique_field_scope_showroom'] = $strongarm;
|
||||
|
||||
$strongarm = new stdClass();
|
||||
$strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */
|
||||
$strongarm->api_version = 1;
|
||||
$strongarm->name = 'unique_field_show_matches_showroom';
|
||||
$strongarm->value = array();
|
||||
$export['unique_field_show_matches_showroom'] = $strongarm;
|
||||
|
||||
return $export;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user