Showroom feature

This commit is contained in:
Bachir Soussi Chiadmi 2016-11-06 19:40:18 +01:00
parent e8cadc31e1
commit 7abf64be00
22 changed files with 7962 additions and 21 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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".
* @}
*/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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