From 34d33889877ef7eabe06ff2fd4d786aaa74d41b8 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Feb 2015 22:36:10 -0500 Subject: [PATCH 1/5] removed application_form and commiting debug_a_application --- sites/all/modules/application_form/application_form.module | 7 ------- .../debug_a_application.features.field_base.inc} | 7 +++++-- .../debug_a_application.features.field_instance.inc} | 4 ++-- .../debug_a_application.features.inc} | 4 ++-- .../debug_a_application.info} | 7 +++---- .../modules/debug_a_application/debug_a_application.module | 7 +++++++ 6 files changed, 19 insertions(+), 17 deletions(-) delete mode 100644 sites/all/modules/application_form/application_form.module rename sites/all/modules/{application_form/application_form.features.field_base.inc => debug_a_application/debug_a_application.features.field_base.inc} (97%) rename sites/all/modules/{application_form/application_form.features.field_instance.inc => debug_a_application/debug_a_application.features.field_instance.inc} (99%) rename sites/all/modules/{application_form/application_form.features.inc => debug_a_application/debug_a_application.features.inc} (95%) rename sites/all/modules/{application_form/application_form.info => debug_a_application/debug_a_application.info} (93%) create mode 100644 sites/all/modules/debug_a_application/debug_a_application.module diff --git a/sites/all/modules/application_form/application_form.module b/sites/all/modules/application_form/application_form.module deleted file mode 100644 index 175cddb..0000000 --- a/sites/all/modules/application_form/application_form.module +++ /dev/null @@ -1,7 +0,0 @@ - 0, 'entity_types' => array(), 'field_name' => 'field_status', + 'field_permissions' => array( + 'type' => 1, + ), 'foreign keys' => array(), 'indexes' => array( 'value' => array( diff --git a/sites/all/modules/application_form/application_form.features.field_instance.inc b/sites/all/modules/debug_a_application/debug_a_application.features.field_instance.inc similarity index 99% rename from sites/all/modules/application_form/application_form.features.field_instance.inc rename to sites/all/modules/debug_a_application/debug_a_application.features.field_instance.inc index 682934a..2aba17a 100644 --- a/sites/all/modules/application_form/application_form.features.field_instance.inc +++ b/sites/all/modules/debug_a_application/debug_a_application.features.field_instance.inc @@ -1,13 +1,13 @@ Date: Sat, 7 Feb 2015 12:26:40 -0500 Subject: [PATCH 2/5] committing field permissions module --- .../modules/field_permissions/CHANGELOG.txt | 27 ++ .../all/modules/field_permissions/LICENSE.txt | 339 ++++++++++++++ .../all/modules/field_permissions/README.txt | 84 ++++ .../field_permissions.admin.css | 74 +++ .../field_permissions.admin.inc | 426 ++++++++++++++++++ .../field_permissions.admin.js | 63 +++ .../field_permissions/field_permissions.info | 15 + .../field_permissions.install | 127 ++++++ .../field_permissions.module | 262 +++++++++++ .../field_permissions/field_permissions.test | 339 ++++++++++++++ .../images/field_permissions.status-off.png | Bin 0 -> 655 bytes .../images/field_permissions.status-on.png | Bin 0 -> 537 bytes 12 files changed, 1756 insertions(+) create mode 100644 sites/all/modules/field_permissions/CHANGELOG.txt create mode 100644 sites/all/modules/field_permissions/LICENSE.txt create mode 100644 sites/all/modules/field_permissions/README.txt create mode 100644 sites/all/modules/field_permissions/field_permissions.admin.css create mode 100644 sites/all/modules/field_permissions/field_permissions.admin.inc create mode 100644 sites/all/modules/field_permissions/field_permissions.admin.js create mode 100644 sites/all/modules/field_permissions/field_permissions.info create mode 100644 sites/all/modules/field_permissions/field_permissions.install create mode 100644 sites/all/modules/field_permissions/field_permissions.module create mode 100644 sites/all/modules/field_permissions/field_permissions.test create mode 100644 sites/all/modules/field_permissions/images/field_permissions.status-off.png create mode 100644 sites/all/modules/field_permissions/images/field_permissions.status-on.png diff --git a/sites/all/modules/field_permissions/CHANGELOG.txt b/sites/all/modules/field_permissions/CHANGELOG.txt new file mode 100644 index 0000000..bfac63b --- /dev/null +++ b/sites/all/modules/field_permissions/CHANGELOG.txt @@ -0,0 +1,27 @@ +7.x-1.0-beta1 +============== +- #1312596 by Rob Loach: Clean up the module file structure. +- #1307312 by Rob Loach: Remove troubleshooting interface as we now have tests. +- #1230284 by zhgenti, David_Rothstein | dboulet: Use form_load_include() + instead of module_load_include() to fix form submits. +- #1306780 by David_Rothstein: Private fields should allow administrators view + access. +- #1298966 by David_Rothstein: Fix static caching in tests. +- #1298966 by Gabor Hojtsy: Initial tests. +- #1279712 by David_Rothstein, Jeff Noyes, Stellina McKinney, Gabor Hojtsy: + Revamp Field Permissions user interface to make it more intuitive. +- #1141330 by David_Rothstein: Fix Field Permissions support with Views. +- #1073284 by joelstein, Rob Loach: Administrator permissions for new fields. + + +7.x-1.0-alpha1 +============== +- #1063162 by jide, Rob Loach: Field Permissions not accessible for some fields. +- #965110 by Danic: Move Field Permissions UI to Reports. +- #965094 by Danic, Rob Loach: Group Title and Description in modules page. +- #1043522 by erikwebb: Permissions administration link wrong on Edit Field page. +- Small documentation changes. +- Added support for create field permission. +- Every permission type can be enabled independently. +- Sync code base from 6.x-1.0 release. +- Fix node revisions table name. diff --git a/sites/all/modules/field_permissions/LICENSE.txt b/sites/all/modules/field_permissions/LICENSE.txt new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/sites/all/modules/field_permissions/LICENSE.txt @@ -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. + + + Copyright (C) + + 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. + + , 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. diff --git a/sites/all/modules/field_permissions/README.txt b/sites/all/modules/field_permissions/README.txt new file mode 100644 index 0000000..d5903cf --- /dev/null +++ b/sites/all/modules/field_permissions/README.txt @@ -0,0 +1,84 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Field Permissions module +;; +;; Original author: markus_petrux (http://drupal.org/user/39593) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +CONTENTS OF THIS FILE +===================== +* OVERVIEW +* USAGE +* REQUIREMENTS +* INSTALLATION + + +OVERVIEW +======== + +The Field Permissions module allows site administrators to set field-level +permissions for fields that are attached to any kind of entity (such as nodes +or users). + +Permissions can be set for editing or viewing the field (either in all +contexts, or only when it is attached to an entity owned by the current user). +Permissions can also be set for editing the field while creating a new entity. + +Permissions for each field are not created by default. Instead, administrators +can enable these permissions explicitly for the fields where this feature is +needed. + + +USAGE +===== + +Once Field Permissions module is installed, you need to edit the field settings +form to enable permissions for each field where you need this feature. You can +choose from three options: + + * Public (author and administrators can edit, everyone can view) + * Private (only author and administrators can edit and view) + * Custom permissions + +The default value ("Public") does not impose any field-level access control, +meaning that permissions are inherited from the entity view or edit +permissions. For example, users who are allowed to view a particular node that +the field is attached to will also be able to view the field. + +"Private" provides quick and easy access to a commonly used form of field +access control. + +Finally, if "Custom permissions" is chosen, a standard permissions matrix will +be revealed allowing you full flexibility to assign the following permissions +to any role on your site: + + * Create own value for field FIELD + * Edit own value for field FIELD + * Edit anyone's value for field FIELD + * View own value for field FIELD + * View anyone's value for field FIELD + +These permissions will also be available on the standard permissions page at +Administer -> People -> Permissions. + + +INSTALLATION +============ + +1) Copy all contents of this package to your modules directory preserving + subdirectory structure. + +2) Go to Administer -> Modules to install module. If the (Drupal core) Field UI + module is not enabled, do so. + +3) Review the settings of your fields. You will find a new option labelled + "Field visibility and permissions" that allows you to control access to the + field. + +4) If you chose the setting labelled "Custom permissions", you will be able to + set this field's permissions for any role on your site directly from the + field edit form, or later on by going to the Administer -> People -> + Permissions page. + +5) Get an overview of the Field Permissions at: + Administer -> Reports -> Field list -> Permissions + diff --git a/sites/all/modules/field_permissions/field_permissions.admin.css b/sites/all/modules/field_permissions/field_permissions.admin.css new file mode 100644 index 0000000..e618507 --- /dev/null +++ b/sites/all/modules/field_permissions/field_permissions.admin.css @@ -0,0 +1,74 @@ + +/* Table cells. */ +.field-permissions-cell, +.field-permissions-header { + text-align: center; +} + +/* Status icons. */ +.field-permissions-status-on { + display: inline-block; + width: 16px; + height: 16px; + background: url(images/field_permissions.status-on.png) no-repeat 0 0; +} +.field-permissions-status-off { + display: inline-block; + width: 16px; + height: 16px; + background: url(images/field_permissions.status-off.png) no-repeat 0 0; +} + +/* Quick tooltips behavior. */ +html.js .field-permissions-tooltip { + display: none; +} +#field-permissions-tooltip { + display: none; + padding: 1em 2em 1em 1em; + color: #444; + background-color: #f0f0f0; + border: 1px solid #aaa; + + /* CSS3 properties not supported by all browsers. */ + -webkit-box-shadow: 2px 2px 2px #ccc; + -khtml-box-shadow: 2px 2px 2px #ccc; + -icab-box-shadow: 2px 2px 2px #ccc; + -moz-box-shadow: 2px 2px 2px #ccc; + -o-box-shadow: 2px 2px 2px #ccc; + box-shadow: 2px 2px 2px #ccc; + -webkit-border-radius: 5px; + -khtml-border-radius: 5px; + -icab-border-radius: 5px; + -moz-border-radius: 5px; + -o-border-radius: 5px; + border-radius: 5px; +} +.field-permissions-tooltip .item-list, +#field-permissions-tooltip .item-list { + text-align: left; +} +.field-permissions-tooltip h3, +#field-permissions-tooltip h3 { + font-size: 1.2em; + font-weight: bold; +} + +/** + * Administration on the field settings page. + */ + +/** + * Do not display the hide/show descriptions link above the permissions matrix. + */ +#field-ui-field-edit-form .compact-link { + display: none; +} + +/** + * Indent the matrix and make it appear inline with the corresponding radio button. + */ +#field-ui-field-edit-form table#permissions { + margin-left: 1.5em; + width: 98%; +} diff --git a/sites/all/modules/field_permissions/field_permissions.admin.inc b/sites/all/modules/field_permissions/field_permissions.admin.inc new file mode 100644 index 0000000..fde3730 --- /dev/null +++ b/sites/all/modules/field_permissions/field_permissions.admin.inc @@ -0,0 +1,426 @@ + array( + 'label' => t('Create field'), + 'title' => t('Create own value for field %field', array('%field' => $field_label)), + ), + 'edit own' => array( + 'label' => t('Edit own field'), + 'title' => t('Edit own value for field %field', array('%field' => $field_label)), + ), + 'edit' => array( + 'label' => t('Edit field'), + 'title' => t("Edit anyone's value for field %field", array('%field' => $field_label)), + ), + 'view own' => array( + 'label' => t('View own field'), + 'title' => t('View own value for field %field', array('%field' => $field_label)), + ), + 'view' => array( + 'label' => t('View field'), + 'title' => t("View anyone's value for field %field", array('%field' => $field_label)), + ), + ); +} + +/** + * Returns field permissions in a format suitable for use in hook_permission(). + * + * @param $field + * The field to return permissions for. + * @param $label + * (optional) The human readable name of the field to use when constructing + * permission names; for example, this might be the label of one of the + * corresponding field instances. If not provided, an appropriate label will + * be automatically derived from all the field's instances. + * + * @return + * An array of permission information, suitable for use in hook_permission(). + */ +function field_permissions_list_field_permissions($field, $label = NULL) { + $description = ''; + + // If there is no preferred label, construct one from all the instance + // labels. + if (!isset($label)) { + $labels = array(); + foreach ($field['bundles'] as $entity_type => $bundles) { + foreach ($bundles as $bundle_name) { + $instance = field_info_instance($entity_type, $field['field_name'], $bundle_name); + $labels[] = $instance['label']; + } + } + // If all the instances have the same label, just use that. Otherwise, use + // the field name (with the full list of instance labels as the permission + // description). + $labels = array_unique($labels); + if (count($labels) == 1) { + $label = array_shift($labels); + } + else { + $label = $field['field_name']; + $description = t('This field appears as: %instances', array('%instances' => implode(', ', $labels))); + } + } + + $permissions = array(); + foreach (field_permissions_list($label) as $permission_type => $permission_info) { + $permission = $permission_type . ' ' . $field['field_name']; + $permissions[$permission] = array( + 'title' => $permission_info['title'], + 'description' => $description, + ); + } + + return $permissions; +} + +/** + * Implementation of hook_permission(). + */ +function _field_permissions_permission() { + $perms = array( + 'administer field permissions' => array( + 'title' => t('Administer field permissions'), + 'description' => t('Manage field permissions and field permissions settings.'), + 'restrict access' => TRUE, + ), + 'access private fields' => array( + 'title' => t("Access other users' private fields"), + 'description' => t('View and edit the stored values of all private fields.'), + 'restrict access' => TRUE, + ), + ); + + foreach (field_info_fields() as $field) { + if (isset($field['field_permissions']['type']) && $field['field_permissions']['type'] == FIELD_PERMISSIONS_CUSTOM) { + $perms += field_permissions_list_field_permissions($field); + } + } + + return $perms; +} + +/** + * Alter the field settings form. + */ +function _field_permissions_field_settings_form_alter(&$form, $form_state, $form_id) { + // Put the field permissions extensions at the top of the field settings + // fieldset. + $form['field']['field_permissions'] = array( + '#weight' => -10, + '#access' => user_access('administer field permissions'), + ); + + $form['field']['field_permissions']['type'] = array( + '#title' => t('Field visibility and permissions'), + '#type' => 'radios', + '#options' => array( + FIELD_PERMISSIONS_PUBLIC => t('Public (author and administrators can edit, everyone can view)'), + FIELD_PERMISSIONS_PRIVATE => t('Private (only author and administrators can edit and view)'), + FIELD_PERMISSIONS_CUSTOM => t('Custom permissions'), + ), + '#default_value' => isset($form['#field']['field_permissions']['type']) ? $form['#field']['field_permissions']['type'] : FIELD_PERMISSIONS_PUBLIC, + ); + + // Add the container in which the field permissions matrix will be displayed. + // (and make it so that it is only visible when custom permissions are being + // used). + $form['field']['field_permissions']['permissions'] = array( + '#type' => 'container', + '#states' => array( + 'visible' => array( + // We must cast this to a string until http://drupal.org/node/879580 is + // fixed. + ':input[name="field[field_permissions][type]"]' => array('value' => (string) FIELD_PERMISSIONS_CUSTOM), + ), + ), + // Custom styling for the permissions matrix on the field settings page. + '#attached' => array( + 'css' => array(drupal_get_path('module', 'field_permissions') . '/field_permissions.admin.css'), + ), + ); + + // Add the field permissions matrix itself. Wait until the #pre_render stage + // to move it to the above container, to avoid having the permissions data + // saved as part of the field record. + $form['field_permissions']['#tree'] = TRUE; + $form['field_permissions']['#access'] = user_access('administer field permissions'); + $form['field_permissions']['permissions'] = field_permissions_permissions_matrix($form['#field'], $form['#instance']); + $form['#pre_render'][] = '_field_permissions_field_settings_form_pre_render'; + + // Add a submit handler to process the field permissions settings. Note that + // it is important for this to run *after* the main field UI submit handler + // (which saves the field itself), since when a new field is being created, + // our submit handler will try to assign any new custom permissions + // immediately, and our hook_permission() implementation relies on the field + // info being up-to-date in order for that to work correctly. + $form['#submit'][] = '_field_permissions_field_settings_form_submit'; +} + +/** + * Returns a field permissions matrix that can be inserted into a form. + * + * The matrix's display is based on that of Drupal's default permissions page. + * + * Note that this matrix must be accompanied by an appropriate submit handler + * (attached to the top level of the form) in order for the permissions in it + * to actually be saved. For an example submit handler, see + * _field_permissions_field_settings_form_submit(). + * + * @param $field + * The field whose permissions will be displayed in the matrix. + * @param $instance + * The field instance for which the permissions will be displayed. Although + * the permissions are per-field rather than per-instance, the instance label + * will be used to display an appropriate human-readable name for each + * permission. + * + * @return + * A form array defining the permissions matrix. + * + * @see user_admin_permissions() + * @see _field_permissions_field_settings_form_submit() + */ +function field_permissions_permissions_matrix($field, $instance) { + // This function primarily contains a simplified version of the code from + // user_admin_permissions(). + $form['#theme'] = 'user_admin_permissions'; + $options = array(); + $status = array(); + + // Retrieve all role names for use in the submit handler. + $role_names = user_roles(); + $form['role_names'] = array( + '#type' => 'value', + '#value' => $role_names, + ); + + // Retrieve the permissions for each role, and the field permissions we will + // be assigning here. + $role_permissions = user_role_permissions($role_names); + $field_permissions = field_permissions_list_field_permissions($field, $instance['label']); + + // Determine if it is safe to reset the default values for this field's + // permissions. If this is a new field (never saved with field permission + // data before), or if it's an existing field that is not currently using + // custom permissions and doesn't have any previously-saved ones already in + // the database, then it will be safe to reset them. + $reset_permissions_defaults = FALSE; + if (!isset($field['field_permissions']['type'])) { + $reset_permissions_defaults = TRUE; + } + elseif ($field['field_permissions']['type'] != FIELD_PERMISSIONS_CUSTOM) { + $all_assigned_permissions = call_user_func_array('array_merge_recursive', $role_permissions); + $assigned_field_permissions = array_intersect_key($all_assigned_permissions, $field_permissions); + $reset_permissions_defaults = empty($assigned_field_permissions); + } + // Store this information on the form so that other modules can use it (for + // example, if they want to set default permissions for other roles besides + // the admin role which we use it for below). + $form['#field_permissions_are_new'] = $reset_permissions_defaults; + + // Go through each field permission we will display. + foreach ($field_permissions as $permission => $info) { + // Display the name of the permission as a form item. + $form['permission'][$permission] = array( + '#type' => 'item', + '#markup' => $info['title'], + ); + // Save it to be displayed as one of the role checkboxes. + $options[$permission] = ''; + // If we are in a situation where we can reset the field permissions + // defaults, we do so by pre-checking the admin role's checkbox for this + // permission. + if ($reset_permissions_defaults) { + if (($admin_rid = variable_get('user_admin_role', 0)) && isset($role_names[$admin_rid])) { + $status[$admin_rid][] = $permission; + } + // For fields attached to users, we also pre-check the anonymous user's + // checkbox for the permission to create the field, since that is the + // most common way in which new user entities are created. + if ($instance['entity_type'] == 'user' && $permission == 'create ' . $field['field_name']) { + $status[DRUPAL_ANONYMOUS_RID][] = $permission; + } + } + // Otherwise (e.g., for fields with custom permissions already saved), + // determine whether the permission is already assigned and check each + // checkbox accordingly. + else { + foreach ($role_names as $rid => $name) { + if (isset($role_permissions[$rid][$permission])) { + $status[$rid][] = $permission; + } + } + } + } + + // Build the checkboxes for each role. + foreach ($role_names as $rid => $name) { + $form['checkboxes'][$rid] = array( + '#type' => 'checkboxes', + '#options' => $options, + '#default_value' => isset($status[$rid]) ? $status[$rid] : array(), + '#attributes' => array('class' => array('rid-' . $rid)), + ); + $form['role_names'][$rid] = array('#markup' => check_plain($name), '#tree' => TRUE); + } + + // Attach the default permissions page JavaScript. + $form['#attached']['js'][] = drupal_get_path('module', 'user') . '/user.permissions.js'; + + // Attach our custom JavaScript for the permission matrix. + $form['#attached']['js'][] = drupal_get_path('module', 'field_permissions') . '/field_permissions.admin.js'; + + return $form; +} + +/** + * Pre-render function for the permissions matrix on the field settings form. + */ +function _field_permissions_field_settings_form_pre_render($form) { + // Move the permissions matrix to its final location. + $form['field']['field_permissions']['permissions']['matrix'] = $form['field_permissions']['permissions']; + unset($form['field_permissions']); + return $form; +} + +/** + * Form callback; Submit handler for the Field Settings form. + */ +function _field_permissions_field_settings_form_submit($form, &$form_state) { + // Save the field permissions when appropriate to do so. + $new_field_permissions_type = $form_state['values']['field']['field_permissions']['type']; + if ($new_field_permissions_type == FIELD_PERMISSIONS_CUSTOM && isset($form_state['values']['field_permissions']['permissions'])) { + $field_permissions = $form_state['values']['field_permissions']['permissions']; + foreach ($field_permissions['role_names'] as $rid => $name) { + user_role_change_permissions($rid, $field_permissions['checkboxes'][$rid]); + } + } + + // We must clear the page and block caches whenever the field permission type + // setting has changed (because users may now be allowed to see a different + // set of fields). For similar reasons, we must clear these caches whenever + // custom field permissions are being used, since those may have changed too; + // see user_admin_permissions_submit(). + if (!isset($form['#field']['field_permissions']['type']) || $new_field_permissions_type != $form['#field']['field_permissions']['type'] || $new_field_permissions_type == FIELD_PERMISSIONS_CUSTOM) { + cache_clear_all(); + } +} + +/** + * Menu callback; Field permissions overview. + */ +function field_permissions_overview() { + drupal_add_css(drupal_get_path('module', 'field_permissions') .'/field_permissions.admin.css'); + + $headers = array(t('Field name'), t('Field type'), t('Entity type'), t('Used in')); + foreach (field_permissions_list() as $permission_type => $permission_info) { + $headers[] = array('data' => $permission_info['label'], 'class' => 'field-permissions-header'); + } + $destination = drupal_get_destination(); + + // Load list of field instances, types and bundles in the system. + $instances = field_info_instances(); + $field_types = field_info_field_types(); + $bundles = field_info_bundles(); + + // Retrieve the permissions for each role. + $role_permissions = user_role_permissions(user_roles()); + + // Based on field_ui_fields_list() in field_ui.admin.inc. + $rows = array(); + foreach ($instances as $obj_type => $type_bundles) { + foreach ($type_bundles as $bundle => $bundle_instances) { + foreach ($bundle_instances as $field_name => $instance) { + // Each field will have a row in the table. + $field = field_info_field($field_name); + $admin_path = _field_ui_bundle_admin_path($obj_type, $bundle); + $rows[$field_name]['data'][0] = $field['locked'] ? t('@field_name (Locked)', array('@field_name' => $field_name)) : $field_name; + $rows[$field_name]['data'][1] = t($field_types[$field['type']]['label']); + $rows[$field_name]['data'][2] = $obj_type; + $rows[$field_name]['data'][3][] = l($bundles[$obj_type][$bundle]['label'], $admin_path . '/fields/'. $field_name, array( + 'query' => $destination, + 'fragment' => 'edit-field-field-permissions-type', + )); + $rows[$field_name]['class'] = $field['locked'] ? array('menu-disabled') : array(''); + + // Append field permissions information to the report. + $type = isset($field['field_permissions']['type']) ? $field['field_permissions']['type'] : FIELD_PERMISSIONS_PUBLIC; + foreach (array_keys(field_permissions_list_field_permissions($field)) as $index => $permission) { + // Put together the data value for the cell. + $data = ''; + $full_colspan = FALSE; + if ($type == FIELD_PERMISSIONS_PUBLIC) { + $data = t('Public field (author and administrators can edit, everyone can view)'); + $full_colspan = TRUE; + } + elseif ($type == FIELD_PERMISSIONS_PRIVATE) { + $data = t('Private field (only author and administrators can edit and view)'); + $full_colspan = TRUE; + } + else { + // This is a field with custom permissions. Link the field to the + // appropriate row of the permissions page, and theme it based on + // whether all users have access. + $all_users_have_access = isset($role_permissions[DRUPAL_ANONYMOUS_RID][$permission]) && isset($role_permissions[DRUPAL_AUTHENTICATED_RID][$permission]); + $status_class = $all_users_have_access ? 'field-permissions-status-on' : 'field-permissions-status-off'; + $title = $all_users_have_access ? t('All users have this permission') : t('Not all users have this permission'); + $data = l('', 'admin/people/permissions', array( + 'attributes' => array( + 'class' => array('field-permissions-status', $status_class), + 'title' => $title, + ), + 'query' => $destination, + 'fragment' => drupal_html_class("edit $permission"), + )); + } + + // Construct the cell. + $rows[$field_name]['data'][4 + $index] = array( + 'data' => $data, + 'class' => array('field-permissions-cell'), + ); + if ($full_colspan) { + $rows[$field_name]['data'][4 + $index]['colspan'] = 5; + break; + } + } + } + } + } + foreach ($rows as $field_name => $cell) { + $rows[$field_name]['data'][3] = implode(', ', $cell['data'][3]); + } + if (empty($rows)) { + $output = t('No fields have been defined for any content type yet.'); + } + else { + // Sort rows by field name. + ksort($rows); + + // Allow external modules alter the table headers and rows. + foreach (module_implements('field_permissions_overview_alter') as $module) { + $function = $module .'_field_permissions_overview_alter'; + $function($headers, $rows); + } + + $output = theme('table', array('header' => $headers, 'rows' => $rows)); + } + return $output; +} diff --git a/sites/all/modules/field_permissions/field_permissions.admin.js b/sites/all/modules/field_permissions/field_permissions.admin.js new file mode 100644 index 0000000..19aae57 --- /dev/null +++ b/sites/all/modules/field_permissions/field_permissions.admin.js @@ -0,0 +1,63 @@ +(function ($) { + +Drupal.behaviors.fieldPermissionsSettings = { + attach: function (context) { + // For user fields, we want the "Create own value for field X" permission + // row to only be displayed when it's meaningful (i.e., when the "Display + // on user registration form" checkbox is checked). + var $user_register_form_checkbox, $required_field_checkbox, $create_permission_row; + $user_register_form_checkbox = $('.form-item-instance-settings-user-register-form .form-checkbox', context); + if ($user_register_form_checkbox.length) { + // The "Required field" checkbox can cause the user registration checkbox + // to change, so we need it also. + $required_field_checkbox = $('.form-item-instance-required .form-checkbox', context); + if ($required_field_checkbox.length) { + // Get the permissions table row corresponding to the "Create own value + // for field X" permission. The theme_user_admin_permissions() function + // does not give us a good way to directly detect which row contains + // the create permissions, so we have rely on the fact that it will be + // the first row. + $create_permission_row = $('table#permissions tbody tr', context).filter(':first'); + new Drupal.fieldPermissions.HideCreatePermission($user_register_form_checkbox, $required_field_checkbox, $create_permission_row); + } + } + } +}; + +Drupal.fieldPermissions = {}; + +/** + * Constructor for the HideCreatePermission object. + * + * This object hides and shows the "Create own value for field X" permission + * for user fields when it is appropriate to do so, depending on the state of + * the "Display on user registration form" and "Required field" checkboxes. + */ +Drupal.fieldPermissions.HideCreatePermission = function ($user_register_form_checkbox, $required_field_checkbox, $create_permission_row) { + this.$user_register_form_checkbox = $user_register_form_checkbox; + this.$create_permission_row = $create_permission_row; + // Start off by making sure the create permission row has the correct + // visibility. + this.setCreatePermissionVisibility(); + // Set the row's visibility again whenever the user registration checkbox + // changes, or when the required field checkbox (which controls it) changes. + $user_register_form_checkbox.bind('change', $.proxy(this.setCreatePermissionVisibility, this)); + $required_field_checkbox.bind('change', $.proxy(this.setCreatePermissionVisibility, this)); +}; + +/** + * Set the correct visibility of the "Create own value for field X" permission. + */ +Drupal.fieldPermissions.HideCreatePermission.prototype.setCreatePermissionVisibility = function () { + // Granting permissions for "Create own value for field X" only makes sense + // when the field is configured to appear on the user registration form, so + // only show the row in the permissions table then. + if (this.$user_register_form_checkbox.is(':checked')) { + this.$create_permission_row.show(); + } + else { + this.$create_permission_row.hide(); + } +}; + +})(jQuery); diff --git a/sites/all/modules/field_permissions/field_permissions.info b/sites/all/modules/field_permissions/field_permissions.info new file mode 100644 index 0000000..cdb9f17 --- /dev/null +++ b/sites/all/modules/field_permissions/field_permissions.info @@ -0,0 +1,15 @@ +name = Field Permissions +description = Set field-level permissions to create, update or view fields. +package = Fields +core = 7.x +files[] = field_permissions.module +files[] = field_permissions.admin.inc +files[] = field_permissions.test +configure = admin/reports/fields/permissions + +; Information added by drupal.org packaging script on 2012-01-25 +version = "7.x-1.0-beta2" +core = "7.x" +project = "field_permissions" +datestamp = "1327510549" + diff --git a/sites/all/modules/field_permissions/field_permissions.install b/sites/all/modules/field_permissions/field_permissions.install new file mode 100644 index 0000000..2e3e198 --- /dev/null +++ b/sites/all/modules/field_permissions/field_permissions.install @@ -0,0 +1,127 @@ +fields(array('weight' => 50)) + ->condition('name', 'field_permissions') + ->execute(); +} + +/** + * Sets a larger weight for the module so that the Field Permissions become available. + */ +function field_permissions_update_7000(&$sandbox) { + db_update('system') + ->fields(array('weight' => 50)) + ->condition('name', 'field_permissions') + ->execute(); +} + +/** + * Migrate field permission settings to the new system (public/private/custom). + */ +function field_permissions_update_7001() { + foreach (field_info_fields() as $field_name => $field) { + // If the field has any field permissions enabled, it will be using custom + // permissions under the new system and needs to be converted. Otherwise, + // it is a public field (the default) and can be ignored. + if (!empty($field['settings']['field_permissions']) && array_filter($field['settings']['field_permissions'])) { + // Set the type to FIELD_PERMISSIONS_CUSTOM. (The module may be disabled + // when this update function runs, so we need to use the numeric value + // rather than relying on the constant being defined.) + $field['field_permissions']['type'] = 2; + + $field_permissions = $field['settings']['field_permissions']; + $permissions_by_operation = array( + // View-related permissions. + array( + 'view' => "view $field_name", + 'view own' => "view own $field_name", + ), + // Edit-related permissions. + array( + 'create' => "create $field_name", + 'edit' => "edit $field_name", + 'edit own' => "edit own $field_name", + ), + ); + + // Loop through each type of operation (view or edit). + foreach ($permissions_by_operation as $permissions) { + $actions = array_keys($permissions); + // If none of the related permissions were enabled, all users were + // allowed to perform the relevant actions on this field, so we need to + // assign permissions here to preserve that behavior. + $has_enabled_permissions = (bool) array_filter(array_intersect_key($field_permissions, array_flip($actions))); + if (!$has_enabled_permissions) { + _update_7000_user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, $permissions, 'field_permissions'); + _update_7000_user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, $permissions, 'field_permissions'); + } + // Otherwise, for each permission that was disabled, no users should be + // allowed to perform that action; therefore, make sure to unassign any + // (stale) permissions that they may have. + else { + foreach ($actions as $action) { + if (empty($field_permissions[$action])) { + if ($action != 'create') { + $permission = $permissions[$action]; + $rids = array_keys(user_roles(FALSE, $permission)); + foreach ($rids as $rid) { + user_role_revoke_permissions($rid, array($permission)); + } + } + // The 'create' action needs special handling, since previously, + // if create permissions were not enabled the code would have + // fallen back on checking edit permissions. Now, though, create + // permissions are always enabled (and always checked when an + // entity is being created). Therefore, we need to figure out + // what the fallback would have been and assign new create + // permissions based on that. + else { + $rids_with_create_access = array(); + // The first fallback is edit permissions; if those are + // enabled, any role with edit permission would have been + // granted access. + if (!empty($field_permissions['edit'])) { + $rids_with_create_access = array_keys(user_roles(FALSE, $permissions['edit'])); + } + // The final fallback is 'edit own' permissions; if those are + // enabled, any role with 'edit own' permission would have been + // granted access. (It is additionally required that the entity + // being checked is owned by the current user, but in the case + // of nodes being created that will always be the case anyway, + // and nodes are the only entities we need to support for the + // D6-to-D7 upgrade.) + if (!empty($field_permissions['edit own'])) { + $rids_with_create_access = array_unique(array_merge($rids_with_create_access, array_keys(user_roles(FALSE, $permissions['edit own'])))); + } + // Assign create permissions to all the relevant roles. + foreach ($rids_with_create_access as $rid) { + _update_7000_user_role_grant_permissions($rid, array($permissions['create']), 'field_permissions'); + } + } + } + } + } + } + } + + // Remove the old field permissions settings if necessary, and save the + // field. + if (isset($field['settings']['field_permissions'])) { + // We can't unset this or field_update_field() will automatically add it + // back (using the prior field data), so do the next best thing. + $field['settings']['field_permissions'] = NULL; + field_update_field($field); + } + } +} diff --git a/sites/all/modules/field_permissions/field_permissions.module b/sites/all/modules/field_permissions/field_permissions.module new file mode 100644 index 0000000..bc4d1f5 --- /dev/null +++ b/sites/all/modules/field_permissions/field_permissions.module @@ -0,0 +1,262 @@ +' . t('Set field-level permissions to edit or view CCK fields in any node, edit field during node creation, and edit or view permissions for nodes owned by the current user.') . '

'; + + // Help for the Field Permissions overview page. + case 'admin/reports/fields/permissions': + return '

' . t('Report and troubleshoot field permissions.') . '

'; + } +} + +/** + * Implements hook_menu(). + */ +function field_permissions_menu() { + $items['admin/reports/fields/list'] = array( + 'title' => 'List', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10, + ); + $items['admin/reports/fields/permissions'] = array( + 'title' => 'Permissions', + 'description' => 'Report and troubleshoot field permissions.', + 'page callback' => 'field_permissions_overview', + 'access arguments' => array('administer field permissions'), + 'file' => 'field_permissions.admin.inc', + 'type' => MENU_LOCAL_TASK, + 'weight' => 0, + ); + return $items; +} + +/** + * Implementation of hook_permission(). + */ +function field_permissions_permission() { + module_load_include('inc', 'field_permissions', 'field_permissions.admin'); + return _field_permissions_permission(); +} + +/** + * Implements of hook_form_FORM_ID_alter(). + */ +function field_permissions_form_field_ui_field_edit_form_alter(&$form, &$form_state, $form_id) { + // Injects the Field Permissions settings on the Edit field tab. + form_load_include($form_state, 'inc', 'field_permissions', 'field_permissions.admin'); + return _field_permissions_field_settings_form_alter($form, $form_state, $form_id); +} + +/** + * Implementation of hook_field_access(). + * + * @param $op + * The operation to be performed. Possible values: + * - 'edit' + * - 'view' + * @param $field + * The field on which the operation is to be performed. + * @param $entity_type + * The type of entity; e.g. 'node' or 'user'. + * @param $entity + * The entity on which the operation is to be performed. + * @param $account + * The account to check. + * + * @return + * FALSE if the operation is not allowed. + * Note when field_access() is invoked, access is granted unless one + * implementation of hook_field_access() explicitly returns FALSE. + * + * @see field_access() + */ +function field_permissions_field_access($op, $field, $entity_type, $entity, $account) { + // Ignore the request if permissions have not been enabled for this field. + if (!isset($field['field_permissions']['type']) || $field['field_permissions']['type'] == FIELD_PERMISSIONS_PUBLIC) { + return; + } + // If the field is private, then only the author (and administrators with the + // 'access private fields' permissions) can view and edit it. + elseif ($field['field_permissions']['type'] == FIELD_PERMISSIONS_PRIVATE) { + if (isset($entity)) { + return _field_permissions_entity_is_owned_by_account($entity, $account) || user_access('access private fields', $account); + } + // If the entity does not exist, we must check if there is access to any + // entity; see comments in field_permissions_empty_entity_access(). In this + // case that will always be true, since private fields are always editable + // by their authors and in theory any user account can be the author of + // some entity on the site. + else { + return TRUE; + } + } + // Otherwise, check access by permission. + elseif ($field['field_permissions']['type'] == FIELD_PERMISSIONS_CUSTOM) { + if (!isset($entity)) { + return field_permissions_empty_entity_access($op, $field['field_name'], $account); + } + elseif ($op == 'view') { + return _field_permissions_field_view_access($field['field_name'], $entity_type, $entity, $account); + } + elseif ($op == 'edit') { + return _field_permissions_field_edit_access($field['field_name'], $entity_type, $entity, $account); + } + } +} + +/** + * Determines custom field permissions access when the entity is unknown. + * + * When a module calls field_access() without providing an entity (which the + * API allows it to do), it is doing so in order to check generic access to the + * field. Therefore, we should only deny access if we know that there is no + * entity anywhere on the site for which the user has access to the provided + * field. + * + * For example, Views calls field_access('view') without providing the entity, + * in order to determine if the field can be included in the query itself. So + * we only want to return FALSE if we know that there are no entities for which + * access will be granted. Later on, Views will invoke field_access('view') + * again, indirectly, when rendering the fields using field_view_field(), and + * at that point the entity will be passed along so we can do our normal checks + * on it. + * + * As another example, the FileField Sources module uses field_access('edit') + * as a menu access callback for the IMCE file browser and does not pass along + * the entity. So we must return TRUE here if there is any entity for which the + * user is allowed to edit the field (otherwise the user would not have access + * to the IMCE file browser interface when editing the fields they do have + * permission to edit). + * + * @param $op + * The operation to be performed ('view' or 'edit'). + * @param $field_name + * The name of the field whose access is being checked. + * @param $account + * The user account whose access is being checked. + * + * @return + * TRUE if access should be allowed, or FALSE if it shouln't. + */ +function field_permissions_empty_entity_access($op, $field_name, $account) { + $all_permissions['view'] = array( + 'view ' . $field_name, + 'view own ' . $field_name, + ); + $all_permissions['edit'] = array( + 'create ' . $field_name, + 'edit ' . $field_name, + 'edit own ' . $field_name, + ); + + // If there's any scenario where the user might have permission to perform + // the operation on the field, return TRUE. + if (isset($all_permissions[$op])) { + foreach ($all_permissions[$op] as $permission) { + if (user_access($permission, $account)) { + return TRUE; + } + } + } + + return FALSE; +} + +/** + * Implementation of hook_field_access('view'). + */ +function _field_permissions_field_view_access($field_name, $entity_type, $entity, $account) { + // Check if user has access to view this field in any entity. + if (user_access('view ' . $field_name, $account)) { + return TRUE; + } + + // If the user has permission to view entities that they own, return TRUE if + // they own this entity or FALSE if they don't. + if (user_access('view own ' . $field_name, $account)) { + return _field_permissions_entity_is_owned_by_account($entity, $account); + } + + return FALSE; +} + +/** + * Implementation of hook_field_access('edit'). + */ +function _field_permissions_field_edit_access($field_name, $entity_type, $entity, $account) { + // If this is a new entity, check if the user has access to edit the field on + // entity creation. + if (isset($entity->is_new)) { + // Some entities provide an "is_new" property. If that is present, respect + // whatever it's set to. + $is_new = $entity->is_new; + } + else { + // Otherwise, try to find out if the entity is new by checking its ID. Note + // that checking empty() rather than !isset() is important here, to deal + // with the case of entities that store "0" as their ID while the final + // entity is in the process of being created (user accounts are a good + // example of this). + list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity); + $is_new = empty($id); + } + if ($is_new) { + return user_access('create ' . $field_name, $account); + } + + // Check if user has access to edit this field in any entity. + if (user_access('edit ' . $field_name, $account)) { + return TRUE; + } + + // If the user has permission to edit entities that they own, return TRUE if + // they own this entity or FALSE if they don't. + if (user_access('edit own ' . $field_name, $account)) { + return _field_permissions_entity_is_owned_by_account($entity, $account); + } + + return FALSE; +} + +/** + * Returns TRUE if an entity is owned by a user account, FALSE otherwise. + */ +function _field_permissions_entity_is_owned_by_account($entity, $account) { + // Try to get the uid of the entity owner from the entity itself. If it's not + // set (for example, if the entity type does not store a uid or does not have + // a concept of "ownership"), we need to assume that the provided user + // account does not own it. + return isset($entity->uid) && $entity->uid == $account->uid; +} diff --git a/sites/all/modules/field_permissions/field_permissions.test b/sites/all/modules/field_permissions/field_permissions.test new file mode 100644 index 0000000..201fa46 --- /dev/null +++ b/sites/all/modules/field_permissions/field_permissions.test @@ -0,0 +1,339 @@ + 'Field permissions functionality', + 'description' => 'Test field permissions.', + 'group' => 'Field permissions' + ); + } + + function setUp() { + parent::setUp('field_ui', 'field_permissions'); + + // Create test user. + $admin_permissions = array('access content', 'administer nodes', 'bypass node access', 'administer content types', 'administer taxonomy', 'administer permissions', 'create page content'); + $this->limited_user = $this->drupalCreateUser($admin_permissions); + $all_rids = array_keys($this->limited_user->roles); + sort($all_rids); + $this->limited_rid = array_pop($all_rids); + + $admin_permissions[] = 'administer field permissions'; + $admin_permissions[] = 'administer users'; + $this->admin_user = $this->drupalCreateUser($admin_permissions); + $all_rids = array_keys($this->admin_user->roles); + sort($all_rids); + $this->admin_rid = array_pop($all_rids); + + $this->drupalLogin($this->limited_user); + } + + function testPermissionsUI() { + // This depends on a page node type with a body field, standard install. + // Could alternatively extend field_ui.test classes, but would be much + // slower to run. Tradeoffs. + $field_info = array( + 'admin_path' => 'admin/structure/types/manage/page/fields/body', + 'machine_name' => 'body', + 'add_path' => 'node/add/page', + 'name' => 'Body', + 'form_field' => 'body[und][0][value]', + 'value' => $this->randomName(), + ); + + // Check if we can see the field on the entity creation form. + $this->drupalGet($field_info['add_path']); + $this->assertText($field_info['name']); + + // Admin users cannot access field permissions without specifically being + // granted the permission to do so. + $this->drupalGet($field_info['admin_path']); + $this->assertNoText(t('Field visibility and permissions')); + + // Switch to admin user who can see the field permissions UI. + $this->drupalGet('user/logout'); + $this->drupalLogin($this->admin_user); + $this->drupalGet($field_info['admin_path']); + $this->assertText(t('Field visibility and permissions')); + + // == PUBLIC FIELD ========================================================= + + $this->assertFieldChecked('edit-field-field-permissions-type-0'); + + // Although simpletest could create a node for us, we are doing this directly + // to ensure we have full control over the process. Given that we work with + // field permissions. + $this->drupalGet('user/logout'); + $this->drupalLogin($this->limited_user); + $node1_values = array( + 'title' => $this->randomName(), + $field_info['form_field'] => $field_info['value'], + ); + $this->drupalPost($field_info['add_path'], $node1_values, t('Save')); + $this->assertText($node1_values['title']); + $this->assertText($field_info['value']); + $url = $this->getUrl(); + $nid1 = preg_replace('!^.*node/(\d+)$!', '\1', $url); + + // Switch to admin user to check we can see the body. + $this->drupalGet('user/logout'); + $this->drupalLogin($this->admin_user); + $this->drupalGet('node/' . $nid1); + $this->assertText($node1_values['title']); + $this->assertText($field_info['value']); + + // And we can edit the title and body. + $this->drupalGet('node/' . $nid1 . '/edit'); + $this->assertText('Title'); + $this->assertText($node1_values['title']); + $this->assertText($field_info['name']); + $this->assertText($field_info['value']); + + // == PRIVATE FIELD ======================================================== + + // Switch to admin user to set field to private. + $edit = array( + 'field[field_permissions][type]' => 1, + ); + $this->drupalPost($field_info['admin_path'], $edit, t('Save settings')); + + // Now we should not have access to see or edit this field. + $this->drupalGet('node/' . $nid1); + $this->assertText($node1_values['title']); + $this->assertNoText($field_info['value']); + $this->drupalGet($field_info['add_path']); + $this->assertText('Title'); + $this->assertText($field_info['name']); + $this->drupalGet('node/' . $nid1 . '/edit'); + $this->assertText('Title'); + $this->assertNoText($field_info['name']); + $this->assertNoText($field_info['value']); + + // Grant this user the Drupal core administrator role. This will give them + // the 'access private fields' permission (tested here), and it also means + // that when custom field permissions are created later on in this test, + // the admin user will automatically get those permissions granted also. + $user_admin_rid = variable_get('user_admin_role', 0); + $edit = array( + "roles[$user_admin_rid]" => TRUE, + ); + $this->drupalPost('user/' . $this->admin_user->uid . '/edit', $edit, t('Save')); + + // Now we should have access to see or submit or edit this field again. + $this->drupalGet('node/' . $nid1); + $this->assertText($node1_values['title']); + $this->assertText($field_info['value']); + $this->drupalGet($field_info['add_path']); + $this->assertText('Title'); + $this->assertText($field_info['name']); + $this->drupalGet('node/' . $nid1 . '/edit'); + $this->assertText('Title'); + $this->assertText($field_info['name']); + $this->assertText($field_info['value']); + + // == CUSTOM PERMISSIONS =================================================== + + // Introduce body creation permission. + $edit = array( + 'field[field_permissions][type]' => 2, + ); + $this->drupalPost($field_info['admin_path'], $edit, t('Save settings')); + $this->drupalGet($field_info['admin_path']); + $this->assertRaw(t('Create own value for field %field', array('%field' => $field_info['name']))); + $this->assertRaw(t('Edit own value for field %field', array('%field' => $field_info['name']))); + $this->assertRaw(t("Edit anyone's value for field %field", array('%field' => $field_info['name']))); + $this->assertRaw(t('View own value for field %field', array('%field' => $field_info['name']))); + $this->assertRaw(t("View anyone's value for field %field", array('%field' => $field_info['name']))); + + // See if we have that exposed on the permissions UI as well now. + $this->drupalGet('admin/people/permissions'); + $this->assertText(t('Field Permissions')); + $this->assertRaw(t('Create own value for field %field', array('%field' => $field_info['name']))); + $this->assertRaw(t('Edit own value for field %field', array('%field' => $field_info['name']))); + $this->assertRaw(t("Edit anyone's value for field %field", array('%field' => $field_info['name']))); + $this->assertRaw(t('View own value for field %field', array('%field' => $field_info['name']))); + $this->assertRaw(t("View anyone's value for field %field", array('%field' => $field_info['name']))); + + // == CREATE =============================================================== + + // The admin user should have been automatically granted the create + // permission, but the limited user shouldn't have it yet. + $this->assertUserHasPermission($this->admin_user, 'create ' . $field_info['machine_name'], t('Admin user does have "create @field" permission.', array('@field' => $field_info['machine_name']))); + $this->assertUserDoesNotHavePermission($this->limited_user, 'create ' . $field_info['machine_name'], t('Limited user does not have "create @field" permission.', array('@field' => $field_info['machine_name']))); + + // Should not see the field on the entity creation form anymore for limited_user. + $this->drupalGet('user/logout'); + $this->drupalLogin($this->limited_user); + $this->drupalGet($field_info['add_path']); + $this->assertNoText($field_info['name']); + + // Grant body creation permission to limited users too. + $edit = array( + $this->limited_rid .'[create '. $field_info['machine_name'] .']' => TRUE, + ); + $this->drupalPost('admin/people/permissions', $edit, t('Save permissions')); + $this->assertUserHasPermission($this->admin_user, 'create ' . $field_info['machine_name'], t('Admin user does have "create @field" permission.', array('@field' => $field_info['machine_name']))); + $this->assertUserHasPermission($this->limited_user, 'create ' . $field_info['machine_name'], t('Limited user does have "create @field" permission.', array('@field' => $field_info['machine_name']))); + + // Should see the field again on the entity creation form. + $this->drupalGet($field_info['add_path']); + $this->assertText($field_info['name']); + + // Although simpletest could create a node for us, we are doing this directly + // to ensure we have full control over the process. Given that we work with + // field permissions. + $node2_values = array( + 'title' => $this->randomName(), + $field_info['form_field'] => $field_info['value'], + ); + $this->drupalPost($field_info['add_path'], $node2_values, t('Save')); + $this->assertText($node2_values['title']); + // The body will not yet be visible to this user. + $this->assertNoText($field_info['value']); + $url = $this->getUrl(); + $nid2 = preg_replace('!^.*node/(\d+)$!', '\1', $url); + + // Switch to admin user and prove she has access to body. + $this->drupalGet('user/logout'); + $this->drupalLogin($this->admin_user); + $this->drupalGet('node/' . $nid2); + $this->assertText($node2_values['title']); + $this->assertText($field_info['value']); + + // == VIEW ================================================================= + + // Grant body view permission to limited users too. + $edit = array( + $this->limited_rid .'[view '. $field_info['machine_name'] .']' => TRUE, + ); + $this->drupalPost('admin/people/permissions', $edit, t('Save permissions')); + $this->assertUserHasPermission($this->admin_user, 'view ' . $field_info['machine_name'], t('Admin user does have "view @field" permission.', array('@field' => $field_info['machine_name']))); + $this->assertUserHasPermission($this->limited_user, 'view ' . $field_info['machine_name'], t('Limited user does have "view @field" permission.', array('@field' => $field_info['machine_name']))); + + // Limited user can now see the field. + $this->drupalGet('user/logout'); + $this->drupalLogin($this->limited_user); + $this->drupalGet('node/' . $nid2); + $this->assertText($node2_values['title']); + $this->assertText($field_info['value']); + + // == EDIT ================================================================= + + // We still don't have access to edit our field. + $this->drupalGet('node/' . $nid2 . '/edit'); + $this->assertNoText($field_info['value']); + + // Switch to admin user to configure edit permissions. + $this->drupalGet('user/logout'); + $this->drupalLogin($this->admin_user); + + // Ensure the editing screen now has the body. + $this->drupalGet('node/' . $nid2 . '/edit'); + $this->assertText($field_info['value']); + + // Grant body editing permission for the limited role. + $edit = array( + $this->limited_rid .'[edit '. $field_info['machine_name'] .']' => TRUE, + ); + $this->drupalPost('admin/people/permissions', $edit, t('Save permissions')); + $this->assertUserHasPermission($this->admin_user, 'edit ' . $field_info['machine_name'], t('Admin user does have "edit @field" permission.', array('@field' => $field_info['machine_name']))); + $this->assertUserHasPermission($this->limited_user, 'edit ' . $field_info['machine_name'], t('Limited user does have "edit @field" permission.', array('@field' => $field_info['machine_name']))); + + // Ensure the editing screen still has the body. + $this->drupalGet('node/' . $nid2 . '/edit'); + $this->assertText($field_info['value']); + + // Switch to limited user to check that we can edit body now. + $this->drupalGet('user/logout'); + $this->drupalLogin($this->limited_user); + $this->drupalGet('node/' . $nid2 . '/edit'); + $this->assertText($field_info['value']); + } + + function testUserFields() { + // Create a field attached to users and make it appear on the user + // registration form with (default) custom permissions. + $this->drupalLogin($this->admin_user); + $label = 'Field attached to users'; + $edit = array( + 'fields[_add_new_field][label]' => $label, + 'fields[_add_new_field][field_name]' => 'attached_to_users', + 'fields[_add_new_field][type]' => 'text', + 'fields[_add_new_field][widget_type]' => 'text_textfield', + ); + $this->drupalPost('admin/config/people/accounts/fields', $edit, t('Save')); + $this->drupalPost(NULL, array(), t('Save field settings')); + $edit = array( + 'field[field_permissions][type]' => 2, + 'instance[settings][user_register_form]' => TRUE, + ); + $this->drupalPost(NULL, $edit, t('Save settings')); + + // Log out, go to the registration form and make sure the field appears + // there for anonymous users. + $this->drupalLogout(); + $this->drupalGet('user/register'); + $this->assertText($label); + + // Log in and make sure the user does not have access to edit the field + // (i.e., there are only default permissions to create it). + $this->drupalLogin($this->limited_user); + $this->drupalGet('user/' . $this->limited_user->uid . '/edit'); + $this->assertResponse(200); + $this->assertNoText($label); + } + + /** + * Asserts that a user account has a permission. + */ + protected function assertUserHasPermission($account, $permission, $message) { + $this->_assertUserPermissionState($account, $permission, $message, TRUE); + } + + /** + * Asserts that a user account does not have a permission. + */ + protected function assertUserDoesNotHavePermission($account, $permission, $message) { + $this->_assertUserPermissionState($account, $permission, $message, FALSE); + } + + /** + * Helper function for asserting user permissions. + */ + protected function _assertUserPermissionState($account, $permission, $message, $should_have_permission) { + // We need to clear static caches since the tests may have recently changed + // the permissions via the UI (i.e., in a different thread than the one + // running the tests). + drupal_static_reset('user_access'); + drupal_static_reset('user_role_permissions'); + + // Load the full user account, since we may have been provided an out of + // date pseudo-account of the kind SimpleTest uses (e.g. as returned by + // drupalCreateUser()), rather than an up to date object that actually + // contains the full list of roles this user has been assigned. + $full_account = user_load($account->uid); + + // Now check the permission. + $has_permission = user_access($permission, $full_account); + if ($should_have_permission) { + $this->assertTrue($has_permission, $message); + } + else { + $this->assertFalse($has_permission, $message); + } + } +} diff --git a/sites/all/modules/field_permissions/images/field_permissions.status-off.png b/sites/all/modules/field_permissions/images/field_permissions.status-off.png new file mode 100644 index 0000000000000000000000000000000000000000..1514d51a3cf1b67e1c5b9ada36f1fd474e2d214a GIT binary patch literal 655 zcmV;A0&x9_P)uEoyT++I zn$b9r%cFfhHe2K68PkBu*@^<$y+7xQ$wJ~;c5aBx$R=xq*41Wo zhwQus_VOgm0hughj}MhOvs#{>Vg09Y8WxjWUJY5YW zJ?&8eG!59Cz=|E%Ns@013KLWOLV)CObIIj_5{>{#k%TEAMs_GbdDV`x-iYsGH z#=Z{USAQA>NY(}X7=3{K8#Hs{AQG2a)rMyf zFQK~pm1x3+7!nu%-M`k}``c>^00{o_1pjWJUTfl8mg=3qGEl8H@}^@w`VUx0_$uy4 z2FhRqKX}xI*?Tv1DJd8z#F#0c%*~rM30HE1@2o5m~}ZyoWhqv>ql{V z1ZGE0lgcoK^lx+eqc*rAX1Ky;Xx3U%u#zG!m-;eD1Qsn@kf3|F9qz~|95=&g3(7!X zB}JAT>RU;a%vaNOGnJ%e1=K6eAh43c(QN8RQ6~GP%O}Jju$~Ld*%`mO1p Date: Sat, 7 Feb 2015 12:46:05 -0500 Subject: [PATCH 3/5] updated debug_a_application form to include field permission --- .../debug_a_application.features.field_base.inc | 2 +- sites/all/modules/debug_a_application/debug_a_application.info | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sites/all/modules/debug_a_application/debug_a_application.features.field_base.inc b/sites/all/modules/debug_a_application/debug_a_application.features.field_base.inc index 6dfebef..acb166f 100644 --- a/sites/all/modules/debug_a_application/debug_a_application.features.field_base.inc +++ b/sites/all/modules/debug_a_application/debug_a_application.features.field_base.inc @@ -320,7 +320,7 @@ function debug_a_application_field_default_field_bases() { 'entity_types' => array(), 'field_name' => 'field_status', 'field_permissions' => array( - 'type' => 1, + 'type' => 2, ), 'foreign keys' => array(), 'indexes' => array( diff --git a/sites/all/modules/debug_a_application/debug_a_application.info b/sites/all/modules/debug_a_application/debug_a_application.info index add5977..ff9cd59 100644 --- a/sites/all/modules/debug_a_application/debug_a_application.info +++ b/sites/all/modules/debug_a_application/debug_a_application.info @@ -1,12 +1,13 @@ name = Debug_A_application core = 7.x package = Features -version = 7.x-4.1 +version = 7.x-4.2 project = debug_a_application dependencies[] = email dependencies[] = entity dependencies[] = entityform dependencies[] = features +dependencies[] = field_permissions dependencies[] = list dependencies[] = options dependencies[] = text From ca0683f9eb0bb85a4cbf247ff41850739d661fbb Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 16 Mar 2015 08:39:09 -0400 Subject: [PATCH 4/5] updated entityform module --- .../modules/custom/module-name/da_kewan.info | 5 ++ .../custom/module-name/da_kewan.install | 1 + .../custom/module-name/da_kewan.module | 1 + sites/all/modules/entityform/entityform.info | 6 +- .../all/modules/entityform/entityform.install | 21 +++++ .../all/modules/entityform/entityform.module | 76 ++++++++++++++----- .../entityform_anonymous.info | 6 +- .../entityform_notifications.info | 6 +- .../entityform_test/entityform_test.info | 6 +- 9 files changed, 97 insertions(+), 31 deletions(-) create mode 100644 sites/all/modules/custom/module-name/da_kewan.info create mode 100644 sites/all/modules/custom/module-name/da_kewan.install create mode 100644 sites/all/modules/custom/module-name/da_kewan.module diff --git a/sites/all/modules/custom/module-name/da_kewan.info b/sites/all/modules/custom/module-name/da_kewan.info new file mode 100644 index 0000000..f2be7bb --- /dev/null +++ b/sites/all/modules/custom/module-name/da_kewan.info @@ -0,0 +1,5 @@ +name = Debugacademy +description = Automatic updates for debugacademy. +core = 7.x + + diff --git a/sites/all/modules/custom/module-name/da_kewan.install b/sites/all/modules/custom/module-name/da_kewan.install new file mode 100644 index 0000000..a814366 --- /dev/null +++ b/sites/all/modules/custom/module-name/da_kewan.install @@ -0,0 +1 @@ +fetchCol(); + $result = db_query("SELECT mlid, link_path FROM {menu_links} WHERE router_path = 'eform/submit/%'", array(), array('fetch' => PDO::FETCH_ASSOC)); + foreach ($result as $m) { + $link_parts = explode('/', $m['link_path']); + $entityform_type = str_replace('-', '_', $link_parts[2]); + if (!in_array($entityform_type, $entityform_types)) { + $message = t('Deleted old entityform type menu links.'); + menu_link_delete($m['mlid']); + } + + } + return $message; +} diff --git a/sites/all/modules/entityform/entityform.module b/sites/all/modules/entityform/entityform.module index 76bc6d6..da1b988 100644 --- a/sites/all/modules/entityform/entityform.module +++ b/sites/all/modules/entityform/entityform.module @@ -1301,8 +1301,11 @@ class EntityformTypeController extends EntityAPIControllerExportable { } else { if ($values['is_new']) { - $values['data']['submissions_view'] = 'default'; - $values['data']['user_submissions_view'] = 'default'; + // Don't override values even if is_new. Features will send values in for checking status. + $values['data'] += array( + 'submissions_view' => 'default', + 'user_submissions_view' => 'default', + ); } } $entityform_type = parent::create($values); @@ -1396,6 +1399,15 @@ class EntityformTypeController extends EntityAPIControllerExportable { } } } + // Delete all menu module links that point to this entityform type. + $submit_paths = array(); + foreach ($entities as $id => $entity) { + $submit_paths[] = _entityform_type_get_submit_url($entity->type); + } + $result = db_query("SELECT mlid FROM {menu_links} WHERE link_path IN (:path) AND module = 'entityform'", array(':path' => $submit_paths), array('fetch' => PDO::FETCH_ASSOC)); + foreach ($result as $m) { + menu_link_delete($m['mlid']); + } parent::delete($ids, $transaction); // Clear field info caches such that any changes to extra fields get @@ -1448,34 +1460,60 @@ function _entityform_type_get_path_types($type) { * 2. All Fields will added if the if the show_display_id starts with "autofields_ */ function entityform_views_pre_view(&$view, &$display_id, &$args) { - if ($view->base_table == 'entityform' && strpos($display_id, 'autofields_') === 0) { - if (empty($view->display[$display_id]->entityform_settings['autofields'])) { - $type = $view->args[0]; - _entityform_view_add_all_fields($view, $display_id, $type); - } + if ($view->base_table == 'entityform') { + $view_mode = _entityform_get_view_mode_for_view($view, $display_id); + if ($view_mode && empty($view->display[$display_id]->entityform_settings['autofields'])) { + // We have to have the Entityform Type as the first argument to this View to get this to work. + if ($type = $view->args[0]) { + _entityform_view_add_all_fields($view, $display_id, $type, $view_mode); + } + } } return; } +/** + * Get the Entity View Mode to use of adding field to a View. + * + * + * Current the display_id must have the 1 of 2 patterns + * 1. autofields_[TYPE]_[optional_extra] + * 2. autofields_vm__[VIEW_MODE] + * @param $view + * @param string $display_id + * @return string + */ +function _entityform_get_view_mode_for_view($view, $display_id = '') { + // Old method hardcoded display ids to view modes. + $display_id_parts = explode('_', $display_id); + if ($display_id_parts[0] == 'autofields') { + switch ($display_id_parts[1]) { + case 'csv': + case 'xml': + return 'download'; + break; + case 'table': + return 'table'; + break; + case 'vm'; + //autofield_vm__[VIEW_MODE] + $display_id_viewmode_parts = explode('__', $display_id); + return $display_id_viewmode_parts[1]; + break; + default: + return 'default'; + } + } + return ''; +} /** * Add automatically add all the fields for a Bundle to a View */ -function _entityform_view_add_all_fields(&$view, $display_id, $bundle_name) { +function _entityform_view_add_all_fields(&$view, $display_id, $bundle_name, $view_mode) { $instances = field_info_instances('entityform', $bundle_name); $view_mode_settings = field_view_mode_settings('entityform', $bundle_name); // when adding autofields to view let view modes determine which fields should be include and in what order - switch ($display_id) { - case 'autofields_csv': - case 'autofields_xml': - $view_mode = 'download'; - break; - case 'autofields_table': - $view_mode = 'table'; - break; - default: - $view_mode = 'default'; - } $autofields = array(); foreach ($instances as $instance) { if (!empty($view_mode_settings[$view_mode]['custom_settings']) && isset($instance['display'][$view_mode])) { diff --git a/sites/all/modules/entityform/entityform_anonymous/entityform_anonymous.info b/sites/all/modules/entityform/entityform_anonymous/entityform_anonymous.info index 2149e67..1314436 100644 --- a/sites/all/modules/entityform/entityform_anonymous/entityform_anonymous.info +++ b/sites/all/modules/entityform/entityform_anonymous/entityform_anonymous.info @@ -5,9 +5,9 @@ package = Entityforms dependencies[] = session_api dependencies[] = entityform -; Information added by Drupal.org packaging script on 2014-10-21 -version = "7.x-2.0-rc1" +; Information added by Drupal.org packaging script on 2015-01-27 +version = "7.x-2.0-rc1+4-dev" core = "7.x" project = "entityform" -datestamp = "1413913852" +datestamp = "1422387029" diff --git a/sites/all/modules/entityform/entityform_notifications/entityform_notifications.info b/sites/all/modules/entityform/entityform_notifications/entityform_notifications.info index a3a4de0..2d2948f 100644 --- a/sites/all/modules/entityform/entityform_notifications/entityform_notifications.info +++ b/sites/all/modules/entityform/entityform_notifications/entityform_notifications.info @@ -9,9 +9,9 @@ dependencies[] = entity_rules dependencies[] = entity2text dependencies[] = rules -; Information added by Drupal.org packaging script on 2014-10-21 -version = "7.x-2.0-rc1" +; Information added by Drupal.org packaging script on 2015-01-27 +version = "7.x-2.0-rc1+4-dev" core = "7.x" project = "entityform" -datestamp = "1413913852" +datestamp = "1422387029" diff --git a/sites/all/modules/entityform/entityform_test/entityform_test.info b/sites/all/modules/entityform/entityform_test/entityform_test.info index 222b37f..52d6875 100644 --- a/sites/all/modules/entityform/entityform_test/entityform_test.info +++ b/sites/all/modules/entityform/entityform_test/entityform_test.info @@ -11,9 +11,9 @@ features[entityform_type][] = simpletest_entityform features[features_api][] = api:1 features[field][] = entityform-simpletest_entityform-field_text -; Information added by Drupal.org packaging script on 2014-10-21 -version = "7.x-2.0-rc1" +; Information added by Drupal.org packaging script on 2015-01-27 +version = "7.x-2.0-rc1+4-dev" core = "7.x" project = "entityform" -datestamp = "1413913852" +datestamp = "1422387029" From c45ca63bd777b9fdcf85b27f3e9c05093c658f7e Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 16 Mar 2015 08:44:26 -0400 Subject: [PATCH 5/5] corrected hidden option on status --- ...my_applicationform.features.field_base.inc | 345 ++++++++++++++ ...pplicationform.features.field_instance.inc | 427 ++++++++++++++++++ .../debugacademy_applicationform.features.inc | 61 +++ .../debugacademy_applicationform.info | 38 ++ .../debugacademy_applicationform.module | 7 + 5 files changed, 878 insertions(+) create mode 100644 sites/all/modules/debugacademy_applicationform/debugacademy_applicationform.features.field_base.inc create mode 100644 sites/all/modules/debugacademy_applicationform/debugacademy_applicationform.features.field_instance.inc create mode 100644 sites/all/modules/debugacademy_applicationform/debugacademy_applicationform.features.inc create mode 100644 sites/all/modules/debugacademy_applicationform/debugacademy_applicationform.info create mode 100644 sites/all/modules/debugacademy_applicationform/debugacademy_applicationform.module diff --git a/sites/all/modules/debugacademy_applicationform/debugacademy_applicationform.features.field_base.inc b/sites/all/modules/debugacademy_applicationform/debugacademy_applicationform.features.field_base.inc new file mode 100644 index 0000000..0935b7c --- /dev/null +++ b/sites/all/modules/debugacademy_applicationform/debugacademy_applicationform.features.field_base.inc @@ -0,0 +1,345 @@ + 1, + 'cardinality' => 1, + 'deleted' => 0, + 'entity_types' => array(), + 'field_name' => 'field_additional_time', + 'foreign keys' => array(), + 'indexes' => array( + 'value' => array( + 0 => 'value', + ), + ), + 'locked' => 0, + 'module' => 'list', + 'settings' => array( + 'allowed_values' => array( + '0-2 hrs/week' => '0-2 hrs/week', + '3-5 hrs/week' => '3-5 hrs/week', + '5-8 hrs/week' => '5-8 hrs/week', + '10+ hrs/week' => '10+ hrs/week', + ), + 'allowed_values_function' => '', + ), + 'translatable' => 0, + 'type' => 'list_text', + ); + + // Exported field_base: 'field_background' + $field_bases['field_background'] = array( + 'active' => 1, + 'cardinality' => 1, + 'deleted' => 0, + 'entity_types' => array(), + 'field_name' => 'field_background', + 'foreign keys' => array( + 'format' => array( + 'columns' => array( + 'format' => 'format', + ), + 'table' => 'filter_format', + ), + ), + 'indexes' => array( + 'format' => array( + 0 => 'format', + ), + ), + 'locked' => 0, + 'module' => 'text', + 'settings' => array( + 'max_length' => 255, + ), + 'translatable' => 0, + 'type' => 'text', + ); + + // Exported field_base: 'field_class_time' + $field_bases['field_class_time'] = array( + 'active' => 1, + 'cardinality' => -1, + 'deleted' => 0, + 'entity_types' => array(), + 'field_name' => 'field_class_time', + 'foreign keys' => array(), + 'indexes' => array( + 'value' => array( + 0 => 'value', + ), + ), + 'locked' => 0, + 'module' => 'list', + 'settings' => array( + 'allowed_values' => array( + 'Monday evening' => 'Monday evening', + 'Tuesday evening' => 'Tuesday evening', + 'Wednesday evening' => 'Wednesday evening', + 'Thursday evening' => 'Thursday evening', + 'Friday evening' => 'Friday evening', + 'Saturday morning' => 'Saturday morning', + 'Sunday morning' => 'Sunday morning', + ), + 'allowed_values_function' => '', + ), + 'translatable' => 0, + 'type' => 'list_text', + ); + + // Exported field_base: 'field_email' + $field_bases['field_email'] = array( + 'active' => 1, + 'cardinality' => 1, + 'deleted' => 0, + 'entity_types' => array(), + 'field_name' => 'field_email', + 'foreign keys' => array(), + 'indexes' => array(), + 'locked' => 0, + 'module' => 'email', + 'settings' => array(), + 'translatable' => 0, + 'type' => 'email', + ); + + // Exported field_base: 'field_expectation' + $field_bases['field_expectation'] = array( + 'active' => 1, + 'cardinality' => 1, + 'deleted' => 0, + 'entity_types' => array(), + 'field_name' => 'field_expectation', + 'foreign keys' => array( + 'format' => array( + 'columns' => array( + 'format' => 'format', + ), + 'table' => 'filter_format', + ), + ), + 'indexes' => array( + 'format' => array( + 0 => 'format', + ), + ), + 'locked' => 0, + 'module' => 'text', + 'settings' => array( + 'max_length' => 255, + ), + 'translatable' => 0, + 'type' => 'text', + ); + + // Exported field_base: 'field_interest' + $field_bases['field_interest'] = array( + 'active' => 1, + 'cardinality' => 1, + 'deleted' => 0, + 'entity_types' => array(), + 'field_name' => 'field_interest', + 'foreign keys' => array(), + 'indexes' => array( + 'value' => array( + 0 => 'value', + ), + ), + 'locked' => 0, + 'module' => 'list', + 'settings' => array( + 'allowed_values' => array( + 'Front-end' => 'Front-end', + 'Back-end' => 'Back-end', + 'Undecided' => 'Undecided', + 'I don\'t know the difference' => 'I don\'t know the difference', + ), + 'allowed_values_function' => '', + ), + 'translatable' => 0, + 'type' => 'list_text', + ); + + // Exported field_base: 'field_job_title' + $field_bases['field_job_title'] = array( + 'active' => 1, + 'cardinality' => 1, + 'deleted' => 0, + 'entity_types' => array(), + 'field_name' => 'field_job_title', + 'foreign keys' => array( + 'format' => array( + 'columns' => array( + 'format' => 'format', + ), + 'table' => 'filter_format', + ), + ), + 'indexes' => array( + 'format' => array( + 0 => 'format', + ), + ), + 'locked' => 0, + 'module' => 'text', + 'settings' => array( + 'max_length' => 255, + ), + 'translatable' => 0, + 'type' => 'text', + ); + + // Exported field_base: 'field_name' + $field_bases['field_name'] = array( + 'active' => 1, + 'cardinality' => 1, + 'deleted' => 0, + 'entity_types' => array(), + 'field_name' => 'field_name', + 'foreign keys' => array( + 'format' => array( + 'columns' => array( + 'format' => 'format', + ), + 'table' => 'filter_format', + ), + ), + 'indexes' => array( + 'format' => array( + 0 => 'format', + ), + ), + 'locked' => 0, + 'module' => 'text', + 'settings' => array( + 'max_length' => 255, + ), + 'translatable' => 0, + 'type' => 'text', + ); + + // Exported field_base: 'field_operating' + $field_bases['field_operating'] = array( + 'active' => 1, + 'cardinality' => 1, + 'deleted' => 0, + 'entity_types' => array(), + 'field_name' => 'field_operating', + 'foreign keys' => array(), + 'indexes' => array( + 'value' => array( + 0 => 'value', + ), + ), + 'locked' => 0, + 'module' => 'list', + 'settings' => array( + 'allowed_values' => array( + 'Mac OS' => 'Mac OS', + 'Linux' => 'Linux', + 'Windows' => 'Windows', + ), + 'allowed_values_function' => '', + ), + 'translatable' => 0, + 'type' => 'list_text', + ); + + // Exported field_base: 'field_reason' + $field_bases['field_reason'] = array( + 'active' => 1, + 'cardinality' => 1, + 'deleted' => 0, + 'entity_types' => array(), + 'field_name' => 'field_reason', + 'foreign keys' => array(), + 'indexes' => array( + 'value' => array( + 0 => 'value', + ), + ), + 'locked' => 0, + 'module' => 'list', + 'settings' => array( + 'allowed_values' => array( + 'career' => 'To begin a career as a software developer', + 'website' => 'To build a website/ application I have in mind', + 'resume' => 'More skills are great for my resume', + ), + 'allowed_values_function' => '', + ), + 'translatable' => 0, + 'type' => 'list_text', + ); + + // Exported field_base: 'field_salary' + $field_bases['field_salary'] = array( + 'active' => 1, + 'cardinality' => 1, + 'deleted' => 0, + 'entity_types' => array(), + 'field_name' => 'field_salary', + 'foreign keys' => array( + 'format' => array( + 'columns' => array( + 'format' => 'format', + ), + 'table' => 'filter_format', + ), + ), + 'indexes' => array( + 'format' => array( + 0 => 'format', + ), + ), + 'locked' => 0, + 'module' => 'text', + 'settings' => array( + 'max_length' => 255, + ), + 'translatable' => 0, + 'type' => 'text', + ); + + // Exported field_base: 'field_status' + $field_bases['field_status'] = array( + 'active' => 1, + 'cardinality' => 1, + 'deleted' => 0, + 'entity_types' => array(), + 'field_name' => 'field_status', + 'field_permissions' => array( + 'type' => 2, + ), + 'foreign keys' => array(), + 'indexes' => array( + 'value' => array( + 0 => 'value', + ), + ), + 'locked' => 0, + 'module' => 'list', + 'settings' => array( + 'allowed_values' => array( + 'Accepted' => 'Accepted', + 'Rejected' => 'Rejected', + ), + 'allowed_values_function' => '', + ), + 'translatable' => 0, + 'type' => 'list_text', + ); + + return $field_bases; +} diff --git a/sites/all/modules/debugacademy_applicationform/debugacademy_applicationform.features.field_instance.inc b/sites/all/modules/debugacademy_applicationform/debugacademy_applicationform.features.field_instance.inc new file mode 100644 index 0000000..846d7d6 --- /dev/null +++ b/sites/all/modules/debugacademy_applicationform/debugacademy_applicationform.features.field_instance.inc @@ -0,0 +1,427 @@ + 'application', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => 'How much additional time are you willing to spend outside of class?', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'list', + 'settings' => array(), + 'type' => 'list_default', + 'weight' => 9, + ), + ), + 'entity_type' => 'entityform', + 'field_name' => 'field_additional_time', + 'label' => 'Additional Time', + 'required' => 1, + 'settings' => array( + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'options', + 'settings' => array(), + 'type' => 'options_select', + 'weight' => 10, + ), + ); + + // Exported field_instance: 'entityform-application-field_background' + $field_instances['entityform-application-field_background'] = array( + 'bundle' => 'application', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => 'List any technical/programming background you have.', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'text', + 'settings' => array(), + 'type' => 'text_default', + 'weight' => 4, + ), + ), + 'entity_type' => 'entityform', + 'field_name' => 'field_background', + 'label' => 'Background', + 'required' => 1, + 'settings' => array( + 'text_processing' => 0, + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'text', + 'settings' => array( + 'size' => 60, + ), + 'type' => 'text_textfield', + 'weight' => 5, + ), + ); + + // Exported field_instance: 'entityform-application-field_class_time' + $field_instances['entityform-application-field_class_time'] = array( + 'bundle' => 'application', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => 'Check all of the times that you could be free to attend class', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'list', + 'settings' => array(), + 'type' => 'list_default', + 'weight' => 10, + ), + ), + 'entity_type' => 'entityform', + 'field_name' => 'field_class_time', + 'label' => 'Class Times', + 'required' => 1, + 'settings' => array( + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'options', + 'settings' => array(), + 'type' => 'options_buttons', + 'weight' => 11, + ), + ); + + // Exported field_instance: 'entityform-application-field_email' + $field_instances['entityform-application-field_email'] = array( + 'bundle' => 'application', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => '', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'email', + 'settings' => array(), + 'type' => 'email_default', + 'weight' => 1, + ), + ), + 'entity_type' => 'entityform', + 'field_name' => 'field_email', + 'label' => 'Email', + 'required' => 1, + 'settings' => array( + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'email', + 'settings' => array( + 'size' => 60, + ), + 'type' => 'email_textfield', + 'weight' => 2, + ), + ); + + // Exported field_instance: 'entityform-application-field_expectation' + $field_instances['entityform-application-field_expectation'] = array( + 'bundle' => 'application', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => 'What are you expecting/hoping to learn from this class?', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'text', + 'settings' => array(), + 'type' => 'text_default', + 'weight' => 3, + ), + ), + 'entity_type' => 'entityform', + 'field_name' => 'field_expectation', + 'label' => 'Expectation ', + 'required' => 1, + 'settings' => array( + 'text_processing' => 0, + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'text', + 'settings' => array( + 'size' => 60, + ), + 'type' => 'text_textfield', + 'weight' => 4, + ), + ); + + // Exported field_instance: 'entityform-application-field_interest' + $field_instances['entityform-application-field_interest'] = array( + 'bundle' => 'application', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => '', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'list', + 'settings' => array(), + 'type' => 'list_default', + 'weight' => 5, + ), + ), + 'entity_type' => 'entityform', + 'field_name' => 'field_interest', + 'label' => 'Interest', + 'required' => 1, + 'settings' => array( + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'options', + 'settings' => array(), + 'type' => 'options_select', + 'weight' => 6, + ), + ); + + // Exported field_instance: 'entityform-application-field_job_title' + $field_instances['entityform-application-field_job_title'] = array( + 'bundle' => 'application', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => 'Current job title', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'text', + 'settings' => array(), + 'type' => 'text_default', + 'weight' => 7, + ), + ), + 'entity_type' => 'entityform', + 'field_name' => 'field_job_title', + 'label' => 'Job Title ', + 'required' => 1, + 'settings' => array( + 'text_processing' => 0, + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'text', + 'settings' => array( + 'size' => 60, + ), + 'type' => 'text_textfield', + 'weight' => 8, + ), + ); + + // Exported field_instance: 'entityform-application-field_name' + $field_instances['entityform-application-field_name'] = array( + 'bundle' => 'application', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => 'First Name Last Name ', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'text', + 'settings' => array(), + 'type' => 'text_default', + 'weight' => 0, + ), + ), + 'entity_type' => 'entityform', + 'field_name' => 'field_name', + 'label' => 'Name', + 'required' => 1, + 'settings' => array( + 'text_processing' => 0, + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'text', + 'settings' => array( + 'size' => 60, + ), + 'type' => 'text_textfield', + 'weight' => 1, + ), + ); + + // Exported field_instance: 'entityform-application-field_operating' + $field_instances['entityform-application-field_operating'] = array( + 'bundle' => 'application', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => 'Which operating system does the laptop you will bring to class use?', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'list', + 'settings' => array(), + 'type' => 'list_default', + 'weight' => 6, + ), + ), + 'entity_type' => 'entityform', + 'field_name' => 'field_operating', + 'label' => 'Operating', + 'required' => 1, + 'settings' => array( + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'options', + 'settings' => array(), + 'type' => 'options_buttons', + 'weight' => 7, + ), + ); + + // Exported field_instance: 'entityform-application-field_reason' + $field_instances['entityform-application-field_reason'] = array( + 'bundle' => 'application', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => 'Why do you want to take this class?', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'list', + 'settings' => array(), + 'type' => 'list_default', + 'weight' => 2, + ), + ), + 'entity_type' => 'entityform', + 'field_name' => 'field_reason', + 'label' => 'Reason', + 'required' => 1, + 'settings' => array( + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'options', + 'settings' => array(), + 'type' => 'options_select', + 'weight' => 3, + ), + ); + + // Exported field_instance: 'entityform-application-field_salary' + $field_instances['entityform-application-field_salary'] = array( + 'bundle' => 'application', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => '* Current salary will remain confidential', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'text', + 'settings' => array(), + 'type' => 'text_default', + 'weight' => 8, + ), + ), + 'entity_type' => 'entityform', + 'field_name' => 'field_salary', + 'label' => 'Current Salary', + 'required' => 0, + 'settings' => array( + 'text_processing' => 0, + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'text', + 'settings' => array( + 'size' => 60, + ), + 'type' => 'text_textfield', + 'weight' => 9, + ), + ); + + // Exported field_instance: 'entityform-application-field_status' + $field_instances['entityform-application-field_status'] = array( + 'bundle' => 'application', + 'default_value' => NULL, + 'deleted' => 0, + 'description' => 'STAFF ONLY', + 'display' => array( + 'default' => array( + 'label' => 'hidden', + 'settings' => array(), + 'type' => 'hidden', + 'weight' => 11, + ), + ), + 'entity_type' => 'entityform', + 'field_name' => 'field_status', + 'label' => 'Status', + 'required' => 0, + 'settings' => array( + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'options', + 'settings' => array(), + 'type' => 'options_buttons', + 'weight' => 12, + ), + ); + + // Translatables + // Included for use with string extractors like potx. + t('* Current salary will remain confidential'); + t('Additional Time'); + t('Background'); + t('Check all of the times that you could be free to attend class'); + t('Class Times'); + t('Current Salary'); + t('Current job title'); + t('Email'); + t('Expectation '); + t('First Name Last Name '); + t('How much additional time are you willing to spend outside of class?'); + t('Interest'); + t('Job Title '); + t('List any technical/programming background you have.'); + t('Name'); + t('Operating'); + t('Reason'); + t('STAFF ONLY'); + t('Status'); + t('What are you expecting/hoping to learn from this class?'); + t('Which operating system does the laptop you will bring to class use?'); + t('Why do you want to take this class?'); + + return $field_instances; +} diff --git a/sites/all/modules/debugacademy_applicationform/debugacademy_applicationform.features.inc b/sites/all/modules/debugacademy_applicationform/debugacademy_applicationform.features.inc new file mode 100644 index 0000000..0fae47a --- /dev/null +++ b/sites/all/modules/debugacademy_applicationform/debugacademy_applicationform.features.inc @@ -0,0 +1,61 @@ +