home v2 update
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
|
||||
Menu attributes 7.x-1.0-rc3, 2014-07-05
|
||||
------------------------------------
|
||||
- #2185403 by juanjo_dv: Fixed Localizable options for link target.
|
||||
- 80 char coding standards
|
||||
- #1488960 by andrewmacpherson, michaek | JamesRobertson: Added Attributes for LI element.
|
||||
- #1627806 by d.clarke | clavigne: Added Move Attributes into its own fieldset within the Menu settings area.
|
||||
- #1894772 by amateescu, alberto56: Fixed hook_menu_attribute_info() API example.
|
||||
- #1909564 by opi: Fixed Typo in menu_attributes_menu_attribute_info() comment.
|
||||
- #1761804 by osopolar, quicksketch: Do not add empty classes produced by leading, trailing or double spaces.
|
||||
- #1077426 by cweagans: Followup: Fix permission checks.
|
||||
- #1886014 by Berdir: Fixed Argument 2 passed to _menu_attributes_form_alter() must be an array, null given.
|
||||
|
||||
Menu attributes 7.x-1.0-rc2, 2011-10-07
|
||||
----------------------------------------
|
||||
- #1151594 by amateescu: Fix hook_form_alter() fatal error by checking the correct form element.
|
||||
- #1077426 by Kevin Quillen, amateescu and Dave Reid: Added permissions.
|
||||
- #863670 by amateescu: Add hook documentation in menu_attributes.api.php
|
||||
- #863654 by amateescu and Dave Reid: Add vertical tabs summaries.
|
||||
- #863658 by amateescu: Write Simpletests and enable automated testing.
|
||||
- #1266456 by amateescu and davereid: Menu attributes does not accept 0 as an access key.
|
||||
- #1200928 by dalin, amateescu: Fixed menu link edit form does not save values for existing menu links since $form['options']['#value']['attributes'] is defined.
|
||||
- #1200932 by dalin, amateescu: Fixed $form['options'] should not get overwritten.
|
||||
|
||||
Menu attributes 7.x-1.0-rc1, 2011-05-02
|
||||
----------------------------------------
|
||||
- Unify _menu_attributes_form_alter() to not clobber any other attributes or options in the link data.
|
||||
- #1132782: Added update function to fix any menu links that had the class attribute saved as a string rather than an array.
|
||||
- #1144502: Fixed attribute configuration not showing up on menu settings page.
|
||||
- Stripping CVS keywords.
|
||||
- #994402 by das-peter, Dave Reid: Fixed Prevent error in menu_attributes_menu_link_alter() if an attribute is not a string.
|
||||
- by Dave Reid: Use hook_form_node_form_alter() instead of hook_form_alter().
|
||||
- by Dave Reid: Store class values as an array rather than a string.
|
||||
|
||||
Menu attributes 7.x-1.0-beta1, 2010-07-24
|
||||
------------------------------------------
|
||||
- by Dave Reid: Moved the description element handling back into menu_attributes_form_menu_edit_item_alter() and improved display of attribute form elements.
|
||||
- #783590 by Dave Reid: Ported to Drupal 7.
|
339
sites/all/modules/contrib/admin/menu_attributes/LICENSE.txt
Normal file
339
sites/all/modules/contrib/admin/menu_attributes/LICENSE.txt
Normal file
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Documentation for Menu Attributes API.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Inform the menu_attributes module about custom attributes.
|
||||
*
|
||||
* @return
|
||||
* An array of attributes to be controlled by Menu Attributes, keyed by
|
||||
* attribute name. Each attribute record should be an array with the following
|
||||
* key/value pairs:
|
||||
* - label: The human-readable name of the attribute.
|
||||
* - description: The attribute description.
|
||||
* - form: A Form API array. Some default values for this array are provided
|
||||
* in menu_attributes_get_menu_attribute_info().
|
||||
* - scope: An array of scope options, MENU_ATTRIBUTES_LINK or
|
||||
* MENU_ATTRIBUTES_ITEM or both. If no scope is provided, both will
|
||||
* be assumed.
|
||||
*
|
||||
* @see menu_attributes_menu_attribute_info()
|
||||
* @see menu_attributes_get_menu_attribute_info()
|
||||
*/
|
||||
function hook_menu_attribute_info() {
|
||||
// Add a Tabindex attribute.
|
||||
$info['tabindex'] = array(
|
||||
'label' => t('Tabindex'),
|
||||
'description' => t('Specifies the tab order for the link.'),
|
||||
'form' => array(
|
||||
'#maxlength' => 3,
|
||||
'#size' => 2,
|
||||
),
|
||||
'scope' => array(MENU_ATTRIBUTES_LINK),
|
||||
);
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter the list of menu item attributes.
|
||||
*
|
||||
* @param $attributes
|
||||
* An array of attributes to be controlled by Menu Attributes, keyed by
|
||||
* attribute name.
|
||||
*
|
||||
* @see hook_menu_attribute_info()
|
||||
* @see menu_attributes_get_menu_attribute_info()
|
||||
*/
|
||||
function hook_menu_attribute_info_alter(array &$attributes) {
|
||||
// Remove the Access Key attribute.
|
||||
unset($attributes['accesskey']);
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
name = Menu attributes
|
||||
description = "Allows administrators to specify custom attributes for menu items."
|
||||
dependencies[] = menu
|
||||
core = 7.x
|
||||
configure = admin/structure/menu/settings
|
||||
|
||||
files[] = menu_attributes.test
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-01-02
|
||||
version = "7.x-1.0-rc3+1-dev"
|
||||
core = "7.x"
|
||||
project = "menu_attributes"
|
||||
datestamp = "1420231982"
|
||||
|
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install, update and uninstall functions for the menu_attributes module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_install().
|
||||
*/
|
||||
function menu_attributes_install() {
|
||||
db_update('system')
|
||||
->fields(array(
|
||||
'weight' => 10,
|
||||
))
|
||||
->condition('type', 'module')
|
||||
->condition('name', 'menu_attributes')
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_uninstall().
|
||||
*/
|
||||
function menu_attributes_uninstall() {
|
||||
drupal_load('module', 'menu_attributes');
|
||||
$attributes = menu_attributes_menu_attribute_info();
|
||||
foreach (array_keys($attributes) as $attribute) {
|
||||
variable_del("menu_attributes_{$attribute}_enable");
|
||||
variable_del("menu_attributes_{$attribute}_default");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the module weight.
|
||||
*/
|
||||
function menu_attributes_update_1() {
|
||||
db_update('system')
|
||||
->fields(array(
|
||||
'weight' => 10,
|
||||
))
|
||||
->condition('type', 'module')
|
||||
->condition('name', 'menu_attributes')
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix any menu links that had the class attribute saved as an string.
|
||||
*/
|
||||
function menu_attributes_update_7000(&$sandbox) {
|
||||
if (!isset($sandbox['progress'])) {
|
||||
$sandbox['progress'] = 0;
|
||||
$sandbox['current_mlid'] = 0;
|
||||
// Only count links that possibly have a key class with a string value in
|
||||
// its serialized options array.
|
||||
$sandbox['max'] = db_query("SELECT COUNT(DISTINCT mlid) FROM {menu_links} WHERE options LIKE '%s:5:\"class\";s:%'")->fetchField();
|
||||
}
|
||||
|
||||
// Process twenty links at a time.
|
||||
$limit = 20;
|
||||
|
||||
$links = db_query_range("SELECT mlid, options FROM {menu_links} WHERE mlid > :mlid AND options LIKE '%s:5:\"class\";s:%' ORDER BY mlid", 0, $limit, array(':mlid' => $sandbox['current_mlid']))->fetchAllKeyed();
|
||||
foreach ($links as $mlid => $options) {
|
||||
$options = unserialize($options);
|
||||
|
||||
if (isset($options['attributes']['class']) && is_string($options['attributes']['class'])) {
|
||||
// Convert classes to an array.
|
||||
$options['attributes']['class'] = explode(' ', $options['attributes']['class']);
|
||||
db_update('menu_links')
|
||||
->fields(array(
|
||||
'options' => serialize($options),
|
||||
))
|
||||
->condition('mlid', $mlid)
|
||||
->execute();
|
||||
}
|
||||
|
||||
$sandbox['progress']++;
|
||||
$sandbox['current_mlid'] = $mlid;
|
||||
}
|
||||
|
||||
$sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']);
|
||||
|
||||
// To display a message to the user when the update is completed, return it.
|
||||
// If you do not want to display a completion message, simply return nothing.
|
||||
return t('All menu links with non-array value for class attribute have been fixed.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Grant the 'administer menu attributes' permission to roles that currently
|
||||
* have the 'administer menu' permission.
|
||||
*/
|
||||
function menu_attributes_update_7001() {
|
||||
$roles = user_roles(FALSE, 'administer menu');
|
||||
foreach ($roles as $rid => $role) {
|
||||
user_role_grant_permissions($rid, array('administer menu attributes'));
|
||||
}
|
||||
|
||||
return t("Every role with the 'administer menu' permission has also received the 'administer menu attributes' permission.");
|
||||
}
|
@@ -0,0 +1,119 @@
|
||||
(function ($) {
|
||||
|
||||
/**
|
||||
* Provide the summary information for the menu attributes vertical tabs.
|
||||
*/
|
||||
Drupal.behaviors.menuAttributesOptionsSummary = {
|
||||
attach: function (context) {
|
||||
// Menu item title.
|
||||
$('fieldset#edit-title', context).drupalSetSummary(function (context) {
|
||||
if (!$('input[type="checkbox"]:checked', context).val()) {
|
||||
return Drupal.t('Disabled');
|
||||
}
|
||||
var value = $('.form-textarea', context).val();
|
||||
if (!value) {
|
||||
return Drupal.t('No title');
|
||||
}
|
||||
else {
|
||||
return Drupal.checkPlain(value);
|
||||
}
|
||||
});
|
||||
|
||||
// Menu item ID.
|
||||
$('fieldset#edit-id', context).drupalSetSummary(function (context) {
|
||||
if (!$('input[type="checkbox"]:checked', context).val()) {
|
||||
return Drupal.t('Disabled');
|
||||
}
|
||||
var value = $('.form-text', context).val();
|
||||
if (!value) {
|
||||
return Drupal.t('No ID');
|
||||
}
|
||||
else {
|
||||
return Drupal.checkPlain(value);
|
||||
}
|
||||
});
|
||||
|
||||
// Menu item name.
|
||||
$('fieldset#edit-name', context).drupalSetSummary(function (context) {
|
||||
if (!$('input[type="checkbox"]:checked', context).val()) {
|
||||
return Drupal.t('Disabled');
|
||||
}
|
||||
var value = $('.form-text', context).val();
|
||||
if (!value) {
|
||||
return Drupal.t('No name');
|
||||
}
|
||||
else {
|
||||
return Drupal.checkPlain(value);
|
||||
}
|
||||
});
|
||||
|
||||
// Menu item relationship.
|
||||
$('fieldset#edit-rel', context).drupalSetSummary(function (context) {
|
||||
if (!$('input[type="checkbox"]:checked', context).val()) {
|
||||
return Drupal.t('Disabled');
|
||||
}
|
||||
var value = $('.form-text', context).val();
|
||||
if (!value) {
|
||||
return Drupal.t('No relationship');
|
||||
}
|
||||
else {
|
||||
return Drupal.checkPlain(value);
|
||||
}
|
||||
});
|
||||
|
||||
// Menu item classes.
|
||||
$('fieldset#edit-class', context).drupalSetSummary(function (context) {
|
||||
if (!$('input[type="checkbox"]:checked', context).val()) {
|
||||
return Drupal.t('Disabled');
|
||||
}
|
||||
var value = $('.form-text', context).val();
|
||||
if (!value) {
|
||||
return Drupal.t('No classes');
|
||||
}
|
||||
else {
|
||||
return Drupal.checkPlain(value.replace(/\s/g, ', '));
|
||||
}
|
||||
});
|
||||
|
||||
// Menu item style.
|
||||
$('fieldset#edit-style', context).drupalSetSummary(function (context) {
|
||||
if (!$('input[type="checkbox"]:checked', context).val()) {
|
||||
return Drupal.t('Disabled');
|
||||
}
|
||||
var value = $('.form-text', context).val();
|
||||
if (!value) {
|
||||
return Drupal.t('No style');
|
||||
}
|
||||
else {
|
||||
return Drupal.checkPlain(value);
|
||||
}
|
||||
});
|
||||
|
||||
// Menu item target.
|
||||
$('fieldset#edit-target', context).drupalSetSummary(function (context) {
|
||||
if (!$('input[type="checkbox"]:checked', context).val()) {
|
||||
return Drupal.t('Disabled');
|
||||
}
|
||||
|
||||
var value = $('.form-select option:selected', context).text();
|
||||
return Drupal.checkPlain(value);
|
||||
});
|
||||
|
||||
// Menu item access key.
|
||||
$('fieldset#edit-accesskey', context).drupalSetSummary(function (context) {
|
||||
if (!$('input[type="checkbox"]:checked', context).val()) {
|
||||
return Drupal.t('Disabled');
|
||||
}
|
||||
var value = $('.form-text', context).val();
|
||||
if (!value) {
|
||||
return Drupal.t('No access key');
|
||||
}
|
||||
else {
|
||||
return Drupal.checkPlain(value);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
@@ -0,0 +1,353 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Alters the menu item form to allow the administrator to specify additional
|
||||
* attributes for the menu link
|
||||
*/
|
||||
|
||||
define('MENU_ATTRIBUTES_LINK', 'attributes');
|
||||
define('MENU_ATTRIBUTES_ITEM', 'item_attributes');
|
||||
|
||||
/**
|
||||
* Implements hook_permission().
|
||||
*/
|
||||
function menu_attributes_permission() {
|
||||
return array(
|
||||
'administer menu attributes' => array(
|
||||
'title' => t('Administer menu attributes'),
|
||||
'description' => t('Administer menu attributes.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_menu_link_alter().
|
||||
*/
|
||||
function menu_attributes_menu_link_alter(&$item, $menu) {
|
||||
if (isset($item['options']['attributes']) && is_array($item['options']['attributes'])) {
|
||||
// Filter out blank attributes.
|
||||
foreach ($item['options']['attributes'] as $key => $value) {
|
||||
if ((is_array($value) && empty($value)) || is_string($value) && !drupal_strlen($value)) {
|
||||
unset($item['options']['attributes'][$key]);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert classes to an array.
|
||||
if (isset($item['options']['attributes']['class']) && is_string($item['options']['attributes']['class'])) {
|
||||
$item['options']['attributes']['class'] = array_filter(explode(' ', $item['options']['attributes']['class']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_menu_attribute_info().
|
||||
*/
|
||||
function menu_attributes_menu_attribute_info() {
|
||||
$info['title'] = array(
|
||||
'label' => t('Title'),
|
||||
'description' => t('The description displayed when hovering over the link.'),
|
||||
'form' => array(
|
||||
'#type' => 'textarea',
|
||||
'#rows' => 2,
|
||||
),
|
||||
'scope' => array(MENU_ATTRIBUTES_LINK),
|
||||
);
|
||||
$info['id'] = array(
|
||||
'label' => t('ID'),
|
||||
'description' => t('Specifies a unique ID for the link.'),
|
||||
'scope' => array(MENU_ATTRIBUTES_LINK, MENU_ATTRIBUTES_ITEM),
|
||||
);
|
||||
$info['name'] = array(
|
||||
'label' => t('Name'),
|
||||
'scope' => array(MENU_ATTRIBUTES_LINK),
|
||||
);
|
||||
$info['rel'] = array(
|
||||
'label' => t('Relationship'),
|
||||
'description' => t("Specifies the relationship between the current page and the link. Enter 'nofollow' here to nofollow this link."),
|
||||
'scope' => array(MENU_ATTRIBUTES_LINK),
|
||||
);
|
||||
$info['class'] = array(
|
||||
'label' => t('Classes'),
|
||||
'description' => t('Enter additional classes to be added to the link.'),
|
||||
'scope' => array(MENU_ATTRIBUTES_LINK, MENU_ATTRIBUTES_ITEM),
|
||||
);
|
||||
$info['style'] = array(
|
||||
'label' => t('Style'),
|
||||
'description' => t('Enter additional styles to be applied to the link.'),
|
||||
'scope' => array(MENU_ATTRIBUTES_LINK, MENU_ATTRIBUTES_ITEM),
|
||||
);
|
||||
$info['target'] = array(
|
||||
'label' => t('Target'),
|
||||
'description' => t('Specifies where to open the link. Using this attribute breaks XHTML validation.'),
|
||||
'form' => array(
|
||||
'#type' => 'select',
|
||||
'#options' => array(
|
||||
'' => t('None (i.e. same window)'),
|
||||
'_blank' => t('New window (_blank)'),
|
||||
'_top' => t('Top window (_top)'),
|
||||
'_self' => t('Same window (_self)'),
|
||||
'_parent' => t('Parent window (_parent)'),
|
||||
),
|
||||
),
|
||||
'scope' => array(MENU_ATTRIBUTES_LINK),
|
||||
);
|
||||
$info['accesskey'] = array(
|
||||
'label' => t('Access Key'),
|
||||
'description' => t('Specifies a <a href="@accesskey">keyboard shortcut</a> to access this link.', array('@accesskey' => url('http://en.wikipedia.org/wiki/Access_keys'))),
|
||||
'form' => array(
|
||||
'#maxlength' => 1,
|
||||
'#size' => 1,
|
||||
),
|
||||
'scope' => array(MENU_ATTRIBUTES_LINK),
|
||||
);
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch an array of menu attributes.
|
||||
*/
|
||||
function menu_attributes_get_menu_attribute_info() {
|
||||
$attributes = module_invoke_all('menu_attribute_info');
|
||||
|
||||
// Merge in default values.
|
||||
foreach ($attributes as $attribute => &$info) {
|
||||
$info += array(
|
||||
'form' => array(),
|
||||
'enabled' => variable_get("menu_attributes_{$attribute}_enable", 1),
|
||||
'default' => '',
|
||||
);
|
||||
$info['form'] += array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => $info['label'],
|
||||
'#description' => isset($info['description']) ? $info['description'] : '',
|
||||
'#default_value' => variable_get("menu_attributes_{$attribute}_default", $info['default']),
|
||||
);
|
||||
}
|
||||
drupal_alter('menu_attribute_info', $attributes);
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_form_FORM_ID_alter().
|
||||
*
|
||||
* Adds menu attribute options to the edit menu item form.
|
||||
*
|
||||
* @see menu_edit_item()
|
||||
* @see _menu_attributes_form_alter()
|
||||
* @see menu_attributes_form_menu_edit_item_submit()
|
||||
*/
|
||||
function menu_attributes_form_menu_edit_item_alter(&$form, $form_state) {
|
||||
$item = $form['original_item']['#value'];
|
||||
_menu_attributes_form_alter($form, $item, $form);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_form_FORM_ID_alter().
|
||||
*
|
||||
* Adds menu attribute options to the node's edit menu item form.
|
||||
*
|
||||
* @see _menu_attributes_form_alter()
|
||||
*/
|
||||
function menu_attributes_form_node_form_alter(&$form, $form_state) {
|
||||
if (isset($form['menu']['link']) && isset($form['#node']->menu)) {
|
||||
$item = $form['#node']->menu;
|
||||
_menu_attributes_form_alter($form['menu']['link'], $item, $form);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the menu attributes to a menu item edit form.
|
||||
*
|
||||
* @param $form
|
||||
* The menu item edit form passed by reference.
|
||||
* @param $item
|
||||
* The optional existing menu item for context.
|
||||
*/
|
||||
function _menu_attributes_form_alter(array &$form, array $item = array(), array &$complete_form) {
|
||||
$form['options']['#tree'] = TRUE;
|
||||
$form['options']['#weight'] = 50;
|
||||
|
||||
// Unset the previous value so that the new values get saved.
|
||||
unset($form['options']['#value']['attributes']);
|
||||
unset($form['options']['#value']['item_attributes']);
|
||||
|
||||
$form['options'][MENU_ATTRIBUTES_LINK] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Menu link attributes'),
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => TRUE,
|
||||
'#tree' => TRUE,
|
||||
);
|
||||
|
||||
$form['options'][MENU_ATTRIBUTES_ITEM] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Menu item attributes'),
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => TRUE,
|
||||
'#tree' => TRUE,
|
||||
);
|
||||
|
||||
$attributes = menu_attributes_get_menu_attribute_info();
|
||||
foreach ($attributes as $attribute => $info) {
|
||||
// If no scope is set, this attribute should be available to both link
|
||||
// and item.
|
||||
if (!isset($info['scope'])) {
|
||||
$info['scope'] = array(MENU_ATTRIBUTES_LINK, MENU_ATTRIBUTES_ITEM);
|
||||
}
|
||||
|
||||
// Define fields for each scope.
|
||||
foreach ($info['scope'] as $group) {
|
||||
// Merge in the proper default value.
|
||||
if (isset($item['options'][$group][$attribute])) {
|
||||
// If the menu link already has this attribute, use it.
|
||||
$info['form']['#default_value'] = $item['options'][$group][$attribute];
|
||||
// Convert the classes array to a string for the form.
|
||||
if ($attribute == 'class' && is_array($info['form']['#default_value'])) {
|
||||
$info['form']['#default_value'] = implode(' ', $info['form']['#default_value']);
|
||||
}
|
||||
}
|
||||
elseif ($item['mlid']) {
|
||||
// If this is an existing link, use the raw default (usually empty).
|
||||
$info['form']['#default_value'] = $info['default'];
|
||||
}
|
||||
$form['options'][$group][$attribute] = $info['form'] + array(
|
||||
'#access' => $info['enabled'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Add form values for the reset of $item['options'] and
|
||||
// $item['options']['attributes'] so the values will carry over during save.
|
||||
foreach ($item['options'] as $key => $value) {
|
||||
if ($key !== 'attributes' && !isset($form['options'][$key])) {
|
||||
$form['options'][$key] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $value,
|
||||
);
|
||||
}
|
||||
}
|
||||
foreach (array(MENU_ATTRIBUTES_LINK, MENU_ATTRIBUTES_ITEM) as $group) {
|
||||
if (isset($item['options'][$group])) {
|
||||
foreach ($item['options'][$group] as $key => $value) {
|
||||
if (!isset($form['options'][$group][$key])) {
|
||||
$form['options'][$group][$key] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $value,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hide the 'description' field since we will be using our own 'title' field.
|
||||
if (isset($form['description'])) {
|
||||
$form['description']['#access'] = FALSE;
|
||||
|
||||
// Because this form uses a special $form['description'] field which is
|
||||
// really the 'title' attribute, we need to add special pre-submit handling
|
||||
// to ensure our field gets saved as the title attribute.
|
||||
array_unshift($complete_form['#submit'], '_menu_attributes_form_submit');
|
||||
}
|
||||
|
||||
// Restrict access to the new form elements.
|
||||
$has_visible_children = (bool) element_get_visible_children($form['options']['attributes']);
|
||||
$user_has_access = user_access('administer menu attributes');
|
||||
$form['options']['attributes']['#access'] = ($has_visible_children && $user_has_access);
|
||||
}
|
||||
|
||||
/**
|
||||
* Form submit handler for menu item links.
|
||||
*
|
||||
* Move the title attributes value into the 'description' value so that it
|
||||
* will get properly saved.
|
||||
*/
|
||||
function _menu_attributes_form_submit($form, &$form_state) {
|
||||
if (isset($form_state['values']['menu']['options']['attributes']['title'])) {
|
||||
$form_state['values']['menu']['description'] = $form_state['values']['menu']['options']['attributes']['title'];
|
||||
}
|
||||
elseif (isset($form_state['values']['options']['attributes']['title'])) {
|
||||
$form_state['values']['description'] = $form_state['values']['options']['attributes']['title'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_form_FORM_ID_alter().
|
||||
*
|
||||
* Alters the menu settings form with our menu attribute settings.
|
||||
*
|
||||
* @see menu_configure_form()
|
||||
*/
|
||||
function menu_attributes_form_menu_configure_alter(&$form, $form_state) {
|
||||
if (!user_access('administer menu attributes')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$form['attributes_title'] = array(
|
||||
'#type' => 'item',
|
||||
'#title' => t('Menu item attribute options'),
|
||||
);
|
||||
$form['attributes_vertical_tabs'] = array(
|
||||
'#type' => 'vertical_tabs',
|
||||
'#attached' => array(
|
||||
'js' => array(drupal_get_path('module', 'menu_attributes') . '/menu_attributes.js'),
|
||||
),
|
||||
);
|
||||
|
||||
$attributes = menu_attributes_get_menu_attribute_info();
|
||||
foreach ($attributes as $attribute => $info) {
|
||||
$form['attributes'][$attribute] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => $info['label'],
|
||||
'#group' => 'attributes_vertical_tabs',
|
||||
'#description' => $info['form']['#description'],
|
||||
);
|
||||
$form['attributes'][$attribute]["menu_attributes_{$attribute}_enable"] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Enable the @attribute attribute.', array('@attribute' => drupal_strtolower($info['label']))),
|
||||
'#default_value' => $info['enabled'],
|
||||
);
|
||||
$form['attributes'][$attribute]["menu_attributes_{$attribute}_default"] = array(
|
||||
'#title' => t('Default'),
|
||||
'#description' => '',
|
||||
'#states' => array(
|
||||
'invisible' => array(
|
||||
'input[name="menu_attributes_' . $attribute . '_enable"]' => array('checked' => FALSE),
|
||||
),
|
||||
),
|
||||
) + $info['form'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements MODULE_preprocess_HOOK().
|
||||
*
|
||||
* Adds appropriate attributes to the list item.
|
||||
*
|
||||
* @see theme_menu_link()
|
||||
*/
|
||||
function menu_attributes_preprocess_menu_link(&$variables) {
|
||||
$options = &$variables['element']['#localized_options'];
|
||||
$attributes = &$variables['element']['#attributes'];
|
||||
|
||||
if (isset($options['item_attributes'])) {
|
||||
foreach ($options['item_attributes'] as $attribute => $value) {
|
||||
if (!empty($value)) {
|
||||
// Class get's special treatment, as it's an array and it should not
|
||||
// replace existing values.
|
||||
if ($attribute == 'class') {
|
||||
$value = explode(' ', $value);
|
||||
if (isset($attributes[$attribute])) {
|
||||
$value = array_merge($attributes[$attribute], $value);
|
||||
}
|
||||
}
|
||||
// Override the attribute.
|
||||
$attributes[$attribute] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up, so we're not passing this to l().
|
||||
unset($options['item_attributes']);
|
||||
}
|
||||
}
|
@@ -0,0 +1,267 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Functionality tests for Menu attributes.
|
||||
*
|
||||
* @ingroup menu_attributes
|
||||
*/
|
||||
|
||||
/**
|
||||
* Helper test class with some added functions for testing.
|
||||
*/
|
||||
class MenuAttributesTestHelper extends DrupalWebTestCase {
|
||||
protected $admin_user;
|
||||
protected $menu_attributes_new;
|
||||
protected $menu_attributes_edit;
|
||||
|
||||
function setUp(array $modules = array()) {
|
||||
$modules[] = 'menu';
|
||||
$modules[] = 'menu_attributes';
|
||||
parent::setUp($modules);
|
||||
|
||||
// Create and login user.
|
||||
$this->admin_user = $this->drupalCreateUser(array(
|
||||
'administer menu attributes',
|
||||
'access administration pages',
|
||||
'administer content types',
|
||||
'administer menu',
|
||||
'create page content',
|
||||
'edit any page content',
|
||||
'delete any page content',
|
||||
));
|
||||
|
||||
$this->menu_attributes_new = array(
|
||||
'title' => $this->randomName(10),
|
||||
'id' => $this->randomName(10),
|
||||
'name' => $this->randomName(10),
|
||||
'rel' => $this->randomName(10),
|
||||
'class' => $this->randomName(10),
|
||||
'style' => $this->randomName(10),
|
||||
'target' => '_top',
|
||||
'accesskey' => $this->randomName(1),
|
||||
);
|
||||
|
||||
$this->menu_attributes_edit = array(
|
||||
'title' => $this->randomName(10),
|
||||
'id' => $this->randomName(10),
|
||||
'name' => $this->randomName(10),
|
||||
'rel' => $this->randomName(10),
|
||||
'class' => $this->randomName(10),
|
||||
'style' => $this->randomName(10),
|
||||
'target' => '_self',
|
||||
'accesskey' => $this->randomName(1),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add or edit a menu link using the menu module UI.
|
||||
*
|
||||
* @param integer $plid Parent menu link id.
|
||||
* @param string $link Link path.
|
||||
* @param string $menu_name Menu name.
|
||||
*
|
||||
* @return array Menu link created.
|
||||
*/
|
||||
function crudMenuLink($mlid = 0, $plid = 0, $link = '<front>', $menu_name = 'navigation') {
|
||||
// View add/edit menu link page.
|
||||
if (empty($mlid)) {
|
||||
$this->drupalGet("admin/structure/menu/manage/$menu_name/add");
|
||||
$menu_attributes = $this->menu_attributes_new;
|
||||
}
|
||||
else {
|
||||
$this->drupalGet("admin/structure/menu/item/$mlid/edit");
|
||||
$menu_attributes = $this->menu_attributes_edit;
|
||||
}
|
||||
$this->assertResponse(200);
|
||||
|
||||
$title = '!link_' . $this->randomName(16);
|
||||
$edit = array(
|
||||
'link_path' => $link,
|
||||
'link_title' => $title,
|
||||
'enabled' => TRUE, // Use this to disable the menu and test.
|
||||
'expanded' => TRUE, // Setting this to true should test whether it works when we do the std_user tests.
|
||||
'parent' => $menu_name . ':' . $plid,
|
||||
'weight' => '0',
|
||||
'options[attributes][title]' => $menu_attributes['title'],
|
||||
'options[attributes][id]' => $menu_attributes['id'],
|
||||
'options[attributes][name]' => $menu_attributes['name'],
|
||||
'options[attributes][rel]' => $menu_attributes['rel'],
|
||||
'options[attributes][class]' => $menu_attributes['class'],
|
||||
'options[attributes][style]' => $menu_attributes['style'],
|
||||
'options[attributes][target]' => $menu_attributes['target'],
|
||||
'options[attributes][accesskey]' => $menu_attributes['accesskey'],
|
||||
);
|
||||
|
||||
// Add menu link.
|
||||
$this->drupalPost(NULL, $edit, t('Save'));
|
||||
|
||||
$item = db_query('SELECT * FROM {menu_links} WHERE link_title = :title', array(':title' => $title))->fetchAssoc();
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
function assertMenuAttributes($form_parent, $action = 'new') {
|
||||
if ($action == 'new') {
|
||||
foreach ($this->menu_attributes_new as $attribute => $value) {
|
||||
$this->assertFieldByName($form_parent . '[' . $attribute . ']', $value, t("'$attribute' attribute correct in edit form."));
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach ($this->menu_attributes_edit as $attribute => $value) {
|
||||
$this->assertFieldByName($form_parent . '[' . $attribute . ']', $value, t("New '$attribute' attribute correct in edit form."));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test basic functionality.
|
||||
*/
|
||||
class MenuAttributesTestCase extends MenuAttributesTestHelper {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Menu attributes',
|
||||
'description' => 'Tests menu attributes functionality.',
|
||||
'group' => 'Menu',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp(array $modules = array()) {
|
||||
parent::setUp($modules);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests menu attributes functionality.
|
||||
*/
|
||||
function testMenuAttributes() {
|
||||
// Login the user.
|
||||
$this->drupalLogin($this->admin_user);
|
||||
|
||||
$menu_name = 'navigation';
|
||||
|
||||
// Add a node to be used as a link for menu links.
|
||||
$node = $this->drupalCreateNode(array('type' => 'page'));
|
||||
|
||||
// Add a menu link.
|
||||
$item = $this->crudMenuLink(0, 0, 'node/' . $node->nid, $menu_name);
|
||||
|
||||
$this->drupalGet('admin/structure/menu/item/' . $item['mlid'] . '/edit');
|
||||
$this->assertMenuAttributes('options[attributes]', 'new');
|
||||
|
||||
// Edit the previously created menu link.
|
||||
$item = $this->crudMenuLink($item['mlid'], 0, 'node/' . $node->nid, $menu_name);
|
||||
|
||||
$this->drupalGet('admin/structure/menu/item/' . $item['mlid'] . '/edit');
|
||||
$this->assertMenuAttributes('options[attributes]', 'edit');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test menu attributes settings for nodes.
|
||||
*/
|
||||
class MenuAttributesNodeTestCase extends MenuAttributesTestHelper {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Menu attributes settings for nodes',
|
||||
'description' => 'Add, edit, and delete a node with menu link.',
|
||||
'group' => 'Menu',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp(array $modules = array()) {
|
||||
parent::setUp($modules);
|
||||
$this->drupalLogin($this->admin_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test creating, editing, deleting menu links via node form widget.
|
||||
*/
|
||||
function testMenuNodeFormWidget() {
|
||||
// Enable Navigation menu as available menu.
|
||||
$edit = array(
|
||||
'menu_options[navigation]' => 1,
|
||||
);
|
||||
$this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
|
||||
// Change default parent item to Navigation menu, so we can assert more
|
||||
// easily.
|
||||
$edit = array(
|
||||
'menu_parent' => 'navigation:0',
|
||||
);
|
||||
$this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
|
||||
|
||||
// Create a node.
|
||||
$node_title = $this->randomName();
|
||||
$language = LANGUAGE_NONE;
|
||||
$edit = array(
|
||||
"title" => $node_title,
|
||||
"body[$language][0][value]" => $this->randomString(),
|
||||
);
|
||||
$this->drupalPost('node/add/page', $edit, t('Save'));
|
||||
$node = $this->drupalGetNodeByTitle($node_title);
|
||||
// Assert that there is no link for the node.
|
||||
$this->drupalGet('');
|
||||
$this->assertNoLink($node_title);
|
||||
|
||||
// Edit the node, enable the menu link setting, but skip the link title.
|
||||
$edit = array(
|
||||
'menu[enabled]' => 1,
|
||||
);
|
||||
$this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
|
||||
// Assert that there is no link for the node.
|
||||
$this->drupalGet('');
|
||||
$this->assertNoLink($node_title);
|
||||
|
||||
// Edit the node and create a menu link with attributes.
|
||||
$edit = array(
|
||||
'menu[enabled]' => 1,
|
||||
'menu[link_title]' => $node_title,
|
||||
'menu[weight]' => 17,
|
||||
'menu[options][attributes][title]' => $this->menu_attributes_new['title'],
|
||||
'menu[options][attributes][id]' => $this->menu_attributes_new['id'],
|
||||
'menu[options][attributes][name]' => $this->menu_attributes_new['name'],
|
||||
'menu[options][attributes][rel]' => $this->menu_attributes_new['rel'],
|
||||
'menu[options][attributes][class]' => $this->menu_attributes_new['class'],
|
||||
'menu[options][attributes][style]' => $this->menu_attributes_new['style'],
|
||||
'menu[options][attributes][target]' => $this->menu_attributes_new['target'],
|
||||
'menu[options][attributes][accesskey]' => $this->menu_attributes_new['accesskey'],
|
||||
);
|
||||
$this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
|
||||
// Assert that the link exists.
|
||||
$this->drupalGet('');
|
||||
$this->assertLink($node_title);
|
||||
|
||||
// Assert that the link attributes exist.
|
||||
$this->drupalGet('node/' . $node->nid . '/edit');
|
||||
$this->assertMenuAttributes('menu[options][attributes]', 'new');
|
||||
|
||||
// Edit the node again and change the menu link attributes.
|
||||
$edit = array(
|
||||
'menu[enabled]' => 1,
|
||||
'menu[link_title]' => $node_title,
|
||||
'menu[weight]' => 17,
|
||||
'menu[options][attributes][title]' => $this->menu_attributes_edit['title'],
|
||||
'menu[options][attributes][id]' => $this->menu_attributes_edit['id'],
|
||||
'menu[options][attributes][name]' => $this->menu_attributes_edit['name'],
|
||||
'menu[options][attributes][rel]' => $this->menu_attributes_edit['rel'],
|
||||
'menu[options][attributes][class]' => $this->menu_attributes_edit['class'],
|
||||
'menu[options][attributes][style]' => $this->menu_attributes_edit['style'],
|
||||
'menu[options][attributes][target]' => $this->menu_attributes_edit['target'],
|
||||
'menu[options][attributes][accesskey]' => $this->menu_attributes_edit['accesskey'],
|
||||
);
|
||||
$this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
|
||||
|
||||
// Assert that the link attributes exist.
|
||||
$this->drupalGet('node/' . $node->nid . '/edit');
|
||||
$this->assertMenuAttributes('menu[options][attributes]', 'edit');
|
||||
|
||||
// Edit the node and remove the menu link.
|
||||
$edit = array(
|
||||
'menu[enabled]' => FALSE,
|
||||
);
|
||||
$this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
|
||||
// Assert that there is no link for the node.
|
||||
$this->drupalGet('');
|
||||
$this->assertNoLink($node_title);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user