diff --git a/www/sites/all/modules/contrib/admin_menu/CHANGELOG.txt b/www/sites/all/modules/contrib/admin_menu/CHANGELOG.txt new file mode 100644 index 0000000..b2dcdfe --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/CHANGELOG.txt @@ -0,0 +1,366 @@ + +Admin Menu 7.x-3.x, xxxx-xx-xx +------------------------------ +#1177202 by das-peter, dereine, sun: Fixed copying and re-injection of child + router items breaks badly. Change them by reference instead. + Requires latest Views 3.x code. +#1212064 by sun: Updated admin_views default views for VBO 3.x. +#1196590 by sun: Fixed errors and notices for admin_views with Views 3. +#1144768 by idlewilder, sun: Fixed devel modules to skip are not displayed. +#1079374 by WillHall: Fixed JS Error: unrecognized expression: [href=/]. +#1114132 by joelstein, sun: Added Field UI to list of developer modules. +#1008380 by bdragon, sun: Updated admin_views for D7. +#1146644 by sun: Fixed PHP 5.3 compability in tests. +#442560 by sun: Fixed 'defer' script attribute breaks Drupal.behaviors in FF3.6. +#1022902 by matglas86, sun: Updated for changed core Toolbar styles. + + +Admin Menu 7.x-3.0-RC1, 2010-01-07 +---------------------------------- +#990774 by sun: Updated for $closure renamed to $page_bottom. +#991906 by johnv, sun: Added configure to .info file. +#947198 by sun: Added hint about disabling Toolbar. +by sun: Updated administrative settings form for D7 UX guidelines. +by sun: Disabled "Rebuild system links" button on settings form. +#420816 by sun, smk-ka: Improved on-demand loading of dynamic paths. +#420816 by tim.plunkett: Fixed dynamic Field UI paths for vocabularies. +#871774 by swentel: Fixed developer modules toggle still uses referer_uri(). +#671760 by sun: Updated for new preprocess defaults. +#731462 by sun: Updated for system_rebuild_theme_data(). +by sun: Re-added a "Rebuild system links" button to settings form. +#420816 by tim.plunkett: Updated taxonomy path map for machine names. +#857688 by sun: Updated for reverted system_settings_form(). +#420816 by smk-ka, sun: Added merging of menu trees containing dynamic paths. +by sun: Fixed tests and minor admin_menu_toolbar styling issues. +by sun: Fixed various styling issues for admin_menu and admin_menu_toolbar. +by sun: Updated for Schema API, DBTNG, coding standards. +by sun: Updated for new admin/modules path. +#701424 by hutch: Updated for new admin/people/people path. +by sun: Removed orphan menu rewrite function. +#667858 by sun: Don't remove the current user from the switch user list. +#631550 by sun: Updated for fixed MENU_VISIBLE_IN_BREADCRUMB behavior. +#658344 by dereine, sun: Updated for removed drupal_session_count(). +by sun: Added separate permission to flush cashes. +by sun: Updated for changed Devel settings form. +by sun: Updated for new {system}.info module data. +#614730 by azriprajwala, sun: Updated for hook_theme() key changes. +by sun: Updated for all theme functions should take a single argument. +by sun: Reverted removal of registry cache flushing option. +#578520 by sun: Fixed destination query parameter is processed wrongly. +#578520 by sun: Updated for $query in url() should always be an array. +by Dave Reid: Updated for PHP 5 date constants. +by sun: Updated for new database API. +by smk-ka: Removed remnants of the registry. Fixed flush admin menu cache + command. +#567618 by smk-ka: Revised test cases. Abstracted out base web test class. +by sun: Updated for removed registry, new admin paths. +#326539 by sun: Updated for class attribute array. +#519782 by sun: Updated for hook_footer() replaced by hook_page_alter(). +#525638 by Razorraser: Updated for admin/build renamed to admin/structure. +by Dave Reid: Updated for hook_permission(). +#482314 by Dave Reid: Updated for node_type_get_types(). +#437506 by yched, Dave Reid: Updated for menu_router_build(). +#376816 by sun: Updated for compatibility for other JavaScript libraries. +#337820 by Dave Reid: Updated for new user/logout path. +#340546 by Dave Reid: Updated for drupal_add_js(). +#340531 by Dave Reid: Updated for module_list(). +#266358 by sun: Updated for drupal_add_css(). +#320526 by yettyn, sun: Updated to UNSTABLE-2 (DBTNG queries, permissions, etc). +by sun: Changed admin_menu_wipe() to admin_menu_flush_caches(). +by sun: Updated content-type edit menu item locations. +by sun: Fixed sess_count() changed to drupal_session_count(). + + +Admin Menu 6.x-3.x, xxxx-xx-xx +------------------------------ +#588936 by fenstrat: Fixed Toolbar shortcuts not visible. +#860390 by Kevin Rogers: Fixed .info file parsing error on uncertain platform. +#551484 by sun: Fixed stale hook_admin_menu_output_alter() docs. + + +Admin Menu 6.x-3.0-ALPHA4, 2010-03-11 +------------------------------------- +#730156 by sun: Fixed Administration views. +by sun: Fixed missing .element-hidden style in D6 for permissions tweak. +#645526 by TravisCarden: Fixed stale local tasks markup after moving them. +#366442 by sun: Added tweak to collapse modules on permissions page. +#655926 by donquixote, sun: Improved performance of delayed mouseout. +#557062 by sun: Fixed admin_menu_toolbar JS/CSS loaded before admin_menu's. +#599462 by sun, koyama: Added background-color to avoid unintentional override. +#601918 by BWPanda: Fixed admin_menu.css overrides admin_menu_toolbar.css. +#586228 by Island Usurper: Fixed for PHP 5.3. +#554124 by Dave Reid: Added missing toolbar.png. +#557062 by Dave Reid: Fixed undefined Drupal.admin error when including + admin_menu_toolbar.js before admin_menu.js. +#511744 by smk-ka, sun: Fixed /admin page links are broken. +by smk-ka: Added missing variables to hook_uninstall(). +#571038 by smk-ka: Removed call to admin_menu_wipe() and cleaned install file. +#552190 by Bartezz: Fixed missing t() for user logout link. + + +Admin Menu 6.x-3.0-ALPHA3, 2009-08-16 +------------------------------------- +#502500 by sun: Added "Create content" menu. +#538714 by sun: Fixed wrong re-parenting in Drupal's menu system. +#550132 by sun: Fixed (temporarily) admin_views menu items. +by sun: Added Administration views sub-module, converting all administrative + listing pages in Drupal core into real, ajaxified, and alterable views. +#547206 by sun: Fixed menu link descriptions lead to mouseover clashes. +#540954 by Rob Loach: Added String Overrides to list of developer modules. +#540762 by Deslack: Added Malay translation. + + +Admin Menu 6.x-3.0-ALPHA2, 2009-08-02 +------------------------------------- +#527908 by sun: Changed theme_admin_menu_links() to use $element['#children']. +#527908 by markus_petrux, sun: Changed admin menu into a renderable array. +#420812 by sun, smk-ka: Added support for hook_js(). +by sun: Fixed destination query string of current page not applied to links. +by sun: Changed Drupal.admin.attachBehaviors() to accept local JS settings. +#276751 by sun: Revamped rendering of menu additions/widgets. +#500866 by sun: Updated for removed t() from getInfo() in tests. +#402058 by sun: Added Administration menu toolbar module. +by markus_petrux, sun: Added API documentation. +#461264 by sun: Added site/domain as CSS class. +#451270 by smk-ka, sun: Changed visual indication for uid1. +by sun: Minor code clean-up. +#490670 by sun: Fixed missing menu after installation/upgrade. +#515718 by joelstein, sun: Added rules_admin module to developer modules list. +#352065 by sun: Added setting to select developer modules to keep enabled. +#511854 by psynaptic: Fixed logout link. +#424960 by markus_petrux, sun: Fixed gzip compression for cached output. +by sun: Fixed opacity of links in sub-menus. +#479922 by sun: Fixed fieldsets not collapsed on admin/build/modules/list*. +#495148 by sun: Fixed MENU_NORMAL_ITEMs do not appear in administration menu. +by sun: Fixed tests for new content-type locations. +#345984 by markus_petrux, sun: Fixed old menu links not removed on upgrade. +#276751 by sun: Major rewrite. Fixed menu items cannot be moved, altered, or + added as well as various performance issues. +by sun: Added variable to allow to disable caching (rewrite). + + +Admin Menu 6.x-3.0-ALPHA1, 2009-06-10 +------------------------------------- +#236657 by sun: Updated for corrected arguments of system_clear_cache_submit(). +#483870 by sun: Fixed compatibility with new Admin module. +#483152 by sun: Fixed admin_menu caches not flushed when clean URLs are toggled. +#479922 by danep: Fixed fieldsets not collapsed on admin/build/modules/list. +#469716 by sun: Fixed wrong AJAX callback URL under various conditions. +#471504 by wulff: Updated Danish translation. +by sun: Fixed admin_menu_suppress() does not suppress margin-top. +#451270 by sun: Added visual indication when working as uid 1. +by Dave Reid: Updated for getInfo() in tests. +#420828 by sun: Added dynamic replacements for cached administration menu. +#420840 by sun: Fixed Drupal.behaviors.adminMenu must be only executed once. +#345984 by markus_petrux, sun: Added client-side caching of administration menu. + Attention: A new era of Drupal user experience starts here. This is the very + first issue of a series of improvements targeting plain awesomeness. +#349169 by sun: Fixed Devel switch user links contain multiple path prefixes. +#345984 by sun: Code clean-up in preparation for client-side caching. +#415196 by psynaptic: Updated for CSS coding standards. +#406672 by mr.j, sun: Fixed "Move local tasks" option leaves stale UL. +by sun: Major code clean-up and sync across 3.x branches. +#349505 by smk-ka, sun: Performance: Added caching of entire menu output. +#315342 by wulff: Added "My account" link (by splitting the "Log out" item). +#384100 by kepol, sun: Fixed content-type items displayed in wrong place. +#373339 by sun: Fixed double-escaped 'Edit ' link titles. +#373372 by sun: Turned procedural JavaScript into admin menu behaviors. +by sun: Fixed admin menu tests (and updated to 6.x for SimpleTest 2.x). +#359158 by nitrospectide, sun: Fixed Devel Themer breaks admin menu. +#365335 by sun: Fixed not all variables removed after uninstall. + + +Admin Menu 6.x-1.3, 2009-01-24 +------------------------------ +#362454 by sun: Fixed Drupal.settings.admin_menu is undefined JS error in some + browsers. + + +Admin Menu 6.x-1.2, 2009-01-20 +------------------------------ +#358697 by sun: Added docs about admin_menu_suppress() to README.txt. +#342684 by darumaki, sun: Added notice about Opera configuration to README.txt. +#350932 by sun: Fixed "Run updates" link repeated per language/site. +#342298 by gustz: Updated Spanish translation. +#346106 by sun: Fixed XHTML-Strict validation for admin menu icon. +#287448 by sun: Fixed unnecessary menu rebuild for users without permission to + use admin menu. +#342002 by AltaVida: Fixed improper test for node/add paths. +#272920 by keith.smith: Changed all text strings throughout the module. +#322731 by sun: Fixed improper use of t() in module install file. +#282030 by sun: Fixed "Run updates" item visible for unprivileged users. +#322877 by sun: Added tweak to move page tabs into administration menu. +#287468 by sun: Fixed module paths directly below "admin" get the wrong parent. +#310423 by sun: Added optional position: fixed configuration setting. +#292657 by smk-ka: Improved rendering performance. +#234149 by yhager, sun: Fixed RTL support for IE. +#323726 by danez1972: Added Spanish translation. +#325057 by sun: Updated README.txt. +#234149 by yhager, levavie, sun: Added RTL support. +#325057 by sun: Added links to flush specific caches. +#324334 by AltaVida: Fixed usernames with spaces not in Devel user switch links. +#319382 by betz: Added Dutch translation. + + +Admin Menu 6.x-1.1, 2008-09-12 +------------------------------ +#295476 by pwolanin, use for icon path to fix front-page path-change + bug and pathauto conflict, add wipe button to admin form. +#301370 by sun: Disabled module fieldset collapsing behavior by default. +#288672 by sun: Fixed JS hover behavior not working in IE. +#290803 by sun: Fixed missing devel_themer in devel modules; added some others. +#286636 by sun: Fixed menus do not drop down in IE6. +#249537 by pwolanin, sun: Added admin_menu_suppress() to allow other modules to + disable the display of admin_menu on certain pages (f.e. popups). +#268211 by sun: Fixed invalid issue queue links for custom modules and + sub-modules of projects. +#261461 by sun: Added FAQ entry for displaying other menus like admin_menu. +#264067 by sun: Added FAQ entry for huge amount of anonymous users displayed. +#280002 by pwolanin: Clean up .test setUp function. +#242377 by sun: Fixed sub-level menu items exceed total document height. + + +Admin Menu 6.x-1.0, 2008-06-26 +------------------------------ +#266308 by sun: Fixed jQuery 1.0.x incompatible selector for collapsing modules. +#268373 by sun: Added hook_update to cleanup for alpha/beta testers. +#268373 by sun: Added menu callback to disable/enable developer modules. +#132524 by pwolanin: Fixed admin_menu links are re-inserted each time menu links + are rebuilt. +by smk-ka: Performance: Use 'defer' attribute for JavaScript to delay execution. +#266099 by sun: Fixed description of "Apply margin-top" configuration setting. +#266308 by sun: Usability: Added Utility module features to collapse module + fieldsets on Modules page. +#251341 by sun: Added docs about display drupal links permission. + + +Admin Menu 6.x-1.0-BETA, 2008-06-08 +----------------------------------- +#132524 by sun: Fixed support for sub-content-types below node/add. +#132524 by pwolanin: Added support for localizable menu links. +#132524 by pwolanin, sun: Fixed menu links adjustments. +#132524 by pwolanin: Added simpletest. +#132524 by pwolanin: Major rewrite to better use Drupal 6 menu system. +#132524 by sun: Moved gettext translation files into translations. +#132524 by sun: Committing pre-alpha code for D6 due to public demand. + + +Admin Menu 5.x-2.x, xxxx-xx-xx +------------------------------ +#246221 by sun: Fixed user counter displays different values than Who's online + block. +#239022 by mikl: Added Danish translation. +#234444 by smk-ka: Fixed admin_menu icon does not respect theme settings. +#198240 by sun: Fixed admin_menu displayed in print output. + + +Admin Menu 5.x-2.4, 2008-02-24 +------------------------------ +#214740 by sun: Regression: Fixed directly applied marginTop not supported by IE. +#214725 by sun: Fixed wrong CSS id in admin_menu.js (missed in 5.x-2.3). + + +Admin Menu 5.x-2.3, 2008-02-24 +------------------------------ +#214725 by sun: Fixed CSS id and classes should not contain underscores. +#209390 by sun: Added note about interaction with user role permissions. +#214740 by jjeff, sun: Added module settings to configure margin-top CSS. +#200737 by sun: Changed admin_menu (fav)icon to use theme setting, if defined. +#203116 by smk-ka: Improved performance of non-cached admin_menu by storing + already processed URLs in the cache. +#224605 by sun: 'Add ' items do not appear without 'administer + nodes' permission. +#210615 by robertgarrigos: Fixed Mozilla Mac: Collapsible fieldsets display + error. + + +Admin Menu 5.x-2.2, 2007-01-08 +------------------------------ +#204884 by jjeff: Usability: Override theme font family declaration. +#204935 by jjeff: Added mouseout delay for hovered menus (yay!). +#193941 by downgang: Fixed margin in IE6 using Garland theme. +#197306 by sun: Fixed 'Run updates' leads to wrong url with clean URLs disabled. +Moved images into sub-folder. +by smk-ka: Fixed icon title for user counter not displayed & coding style. +Fixed user count not displayed without 'administer users' permission. + + +Admin Menu 5.x-2.1, 2007-12-02 +------------------------------ +Fixed adding menu items with negative weight not always working. +Fixed admin_menu_copy_items() is overwriting already existing items. +Fixed display menu item ids in devel settings does not work. + + +Admin Menu 5.x-2.0, 2007-12-02 +------------------------------ +Added devel_admin_menu() for fast access to clear-cache, variable editor and + switch_user. +Added username to logout button. +Added hook_admin_menu() to allow other modules to alter admin_menu. +#194189 by sun: Added counter for current anonymous/authenticated users. +Added Drupal.org project issue queue links for all enabled contrib modules. +#189701 by sun: Changed admin_menu icon to be a menu. +#193925 by sun: Removed obsolete menu slicing code. +#193669 by smk-ka: Moved admin_menu builder functions into include file. + + +Admin Menu 5.x-1.2, 2007-11-18 +------------------------------ +#176969 by smk-ka: Fixed performance issues with path(auto) module by + introducing a menu cache for admin_menu. +#179648 by sun: Inject admin_menu into theme. + Fixes several CSS bugs in various themes and also activation of admin_menu + immediately after installation. +#191213 by Standard: Fixed block info shouldn't contain the word "block". +#187816 by sun: Fixed "Add" not translatable. +#186218 by sun: Fixed admin menu icon too big in Safari. +#182563 by sun: Fixed wrong datatype for array_search in _admin_menu_get_children(). +#183496 by sun: Fixed invalid argument supplied for foreach in admin_menu_copy_items(). + + +Admin Menu 5.x-1.1, 2007-10-10 +------------------------------ +#178876 by sun: Fixed 3rd-level submenus expand without hover over. +#153455 by sun: Fixed add product node sub-elements are empty. +Fixed path_to_theme() call breaking blocks page. +#177582 by sun: Fixed bluebreeze theme compatibility. + + +Admin Menu 5.x-1.0, 2007-09-06 +------------------------------ +#156952 by sun: Fixed admin menu inaccessible due to margins. +#149229 by sun: Fixed admin menu not expanding in IE7. +#172545 by sun: Use opacity instead of -moz-opacity. +#132867 Fixed z-index too low. +- Fixed admin menu block selectors to override any other theme styles. +#155589 by sun: Added permission to access administration menu. +- Fixed a PHP warning when there are no content types defined in the system, as + node/add then has no child menu items. +#155312 by sun: Fixed menu item tooltip clashes. +Added support for custom stylesheets per theme. +Removed 4.7.x compatibility. + + +Admin Menu 4.7-1.3, 2007-03-30 +------------------------------ +#126601 Fixed Users can see inaccessible items. +#121027 Fixed Page not found entries for menu-collapsed.png. + + +Admin Menu 4.7-1.2, 2007-03-04 +------------------------------ +- Fixed menu item adjustments +- Fixed IE / Safari support +- Fixed base_path for IE support +- Added create content options to content management menu + + +Admin Menu 4.7-1.1, 2007-01-24 +------------------------------ +First stable release, compatible to Drupal 4.7.x and 5.x. + + +Admin Menu 4.7-1.0, 2007-01-16 +------------------------------ +Initial release of admin_menu module. Already supporting Drupal 5.0. diff --git a/www/sites/all/modules/contrib/admin_menu/LICENSE.txt b/www/sites/all/modules/contrib/admin_menu/LICENSE.txt new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/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/www/sites/all/modules/contrib/admin_menu/README.txt b/www/sites/all/modules/contrib/admin_menu/README.txt new file mode 100644 index 0000000..136db70 --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/README.txt @@ -0,0 +1,188 @@ + +-- SUMMARY -- + +The Administration menu module displays the entire administrative menu tree (and +most local tasks) in a drop-down menu, providing administrators one- or +two-click access to most pages. Other modules may also add menu links to the +menu using hook_admin_menu_output_alter(). + +For a full description of the module, visit the project page: + http://drupal.org/project/admin_menu + +To submit bug reports and feature suggestions, or to track changes: + http://drupal.org/project/issues/admin_menu + + +-- REQUIREMENTS -- + +None. + + +-- INSTALLATION -- + +* Install as usual, see http://drupal.org/node/895232 for further information. + +* You likely want to disable Toolbar module, since its output clashes with + Administration menu. + + +-- CONFIGURATION -- + +* Configure user permissions in Administration » People » Permissions: + + - Use the administration pages and help (System module) + + The top-level administration categories require this permission to be + accessible. The administration menu will be empty unless this permission is + granted. + + - Access administration menu + + Users in roles with the "Access administration menu" permission will see + the administration menu at the top of each page. + + - Display Drupal links + + Users in roles with the "Display drupal links" permission will receive + links to drupal.org issue queues for all enabled contributed modules. The + issue queue links appear under the administration menu icon. + + Note that the menu items displayed in the administration menu depend on the + actual permissions of the viewing user. For example, the "People" menu item + is not displayed to a user who is not a member of a role with the "Administer + users" permission. + +* Customize the menu settings in Administration » Configuration and modules » + Administration » Administration menu. + +* To prevent administrative menu items from appearing twice, you may hide the + "Management" menu block. + + +-- CUSTOMIZATION -- + +* To override the default administration menu icon, you may: + + 1) Disable it via CSS in your theme: + + body #admin-menu-icon { display: none; } + + 2) Alter the image by overriding the theme function: + + Copy the entire theme_admin_menu_icon() function into your template.php, + rename it to phptemplate_admin_menu_icon() or THEMENAME_admin_menu_icon(), + and customize the output according to your needs. + + Remember that the output of the administration menu is cached. To see changes + from your theme override function, you must clear your site cache (via + the "Flush all caches" link on the menu). + +* To override the font size, add the following line to your theme's stylesheet: + + body #admin-menu { font-size: 10px; } + + +-- TROUBLESHOOTING -- + +* If the menu does not display, check the following: + + - Are the "Access administration menu" and "Use the administration pages and help" + permissions enabled for the appropriate roles? + + - Does html.tpl.php of your theme output the $page_bottom variable? + +* If the menu is rendered behind a Flash movie object, add this property to your + Flash object(s): + + + + See http://drupal.org/node/195386 for further information. + + +-- FAQ -- + +Q: When the administration menu module is enabled, blank space is added to the + bottom of my theme. Why? + +A: This is caused by a long list of links to module issue queues at Drupal.org. + Use Administer >> User management >> Permissions to disable the "display + drupal links" permission for all appropriate roles. Note that since UID 1 + automatically receives all permissions, the list of issue queue links cannot + be disabled for UID 1. + + +Q: After upgrading to 6.x-1.x, the menu disappeared. Why? + +A: You may need to regenerate your menu. Visit + http://example.com/admin/build/modules to regenerate your menu (substitute + your site name for example.com). + + +Q: Can I configure the administration menu module to display another menu (like + the Navigation menu, for instance)? + +A: No. As the name implies, administration menu module is for administrative + menu links only. However, you can copy and paste the contents of + admin_menu.css into your theme's stylesheet and replace #admin-menu with any + other menu block id (#block-menu-1, for example). + + +Q: Sometimes, the user counter displays a lot of anonymous users, but no spike + of users or requests appear in Google Analytics or other tracking tools. + +A: If your site was concurrently spidered by search-engine robots, it may have + a significant number of anonymous users for a short time. Most web tracking + tools like Google Analytics automatically filter out these requests. + + +Q: I enabled "Aggregate and compress CSS files", but admin_menu.css is still + there. Is this normal? + +A: Yes, this is the intended behavior. the administration menu module only loads + its stylesheet as needed (i.e., on page requests by logged-on, administrative + users). + + +Q: Why are sub-menus not visible in Opera? + +A: In the Opera browser preferences under "web pages" there is an option to fit + to width. By disabling this option, sub-menus in the administration menu + should appear. + + +Q: How can the administration menu be hidden on certain pages? + +A: You can suppress it by simply calling the following function in PHP: + + module_invoke('admin_menu', 'suppress'); + + However, this needs to happen as early as possible in the page request, so + placing it in the theming layer (resp. a page template file) is too late. + Ideally, the function is called in hook_init() in a custom module. If you do + not have a custom module, placing it into some conditional code at the top of + template.php may work out, too. + + +-- CONTACT -- + +Current maintainers: +* Daniel F. Kudwien (sun) - http://drupal.org/user/54136 +* Peter Wolanin (pwolanin) - http://drupal.org/user/49851 +* Stefan M. Kudwien (smk-ka) - http://drupal.org/user/48898 +* Dave Reid (Dave Reid) - http://drupal.org/user/53892 + +Major rewrite for Drupal 6 by Peter Wolanin (pwolanin). + +This project has been sponsored by: +* UNLEASHED MIND + Specialized in consulting and planning of Drupal powered sites, UNLEASHED + MIND offers installation, development, theming, customization, and hosting + to get you started. Visit http://www.unleashedmind.com for more information. + +* Lullabot + Friendly Drupal experts providing professional consulting & education + services. Visit http://www.lullabot.com for more information. + +* Acquia + Commercially Supported Drupal. Visit http://acquia.com for more information. + diff --git a/www/sites/all/modules/contrib/admin_menu/admin_devel/admin_devel.info b/www/sites/all/modules/contrib/admin_menu/admin_devel/admin_devel.info new file mode 100644 index 0000000..ab3d641 --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/admin_devel/admin_devel.info @@ -0,0 +1,12 @@ +name = Administration Development tools +description = Administration and debugging functionality for developers and site builders. +package = Administration +core = 7.x +scripts[] = admin_devel.js + +; Information added by Drupal.org packaging script on 2014-12-19 +version = "7.x-3.0-rc5" +core = "7.x" +project = "admin_menu" +datestamp = "1419029284" + diff --git a/www/sites/all/modules/contrib/admin_menu/admin_devel/admin_devel.js b/www/sites/all/modules/contrib/admin_menu/admin_devel/admin_devel.js new file mode 100644 index 0000000..833197a --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/admin_devel/admin_devel.js @@ -0,0 +1,40 @@ +(function($) { + +/** + * jQuery debugging helper. + * + * Invented for Dreditor. + * + * @usage + * $.debug(var [, name]); + * $variable.debug( [name] ); + */ +jQuery.extend({ + debug: function () { + // Setup debug storage in global window. We want to look into it. + window.debug = window.debug || []; + + args = jQuery.makeArray(arguments); + // Determine data source; this is an object for $variable.debug(). + // Also determine the identifier to store data with. + if (typeof this == 'object') { + var name = (args.length ? args[0] : window.debug.length); + var data = this; + } + else { + var name = (args.length > 1 ? args.pop() : window.debug.length); + var data = args[0]; + } + // Store data. + window.debug[name] = data; + // Dump data into Firebug console. + if (typeof console != 'undefined') { + console.log(name, data); + } + return this; + } +}); +// @todo Is this the right way? +jQuery.fn.debug = jQuery.debug; + +})(jQuery); diff --git a/www/sites/all/modules/contrib/admin_menu/admin_devel/admin_devel.module b/www/sites/all/modules/contrib/admin_menu/admin_devel/admin_devel.module new file mode 100644 index 0000000..5884f54 --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/admin_devel/admin_devel.module @@ -0,0 +1,33 @@ + 'submit', + '#value' => t('Rebuild system links'), + '#submit' => array('admin_devel_form_admin_menu_theme_settings_alter_rebuild_submit'), + // @todo Not necessarily ready for mass-consumption yet. + '#access' => FALSE, + ); +} + +/** + * Form submit handler to wipe and rebuild all 'module' = 'system' menu links. + */ +function admin_devel_form_admin_menu_theme_settings_alter_rebuild_submit($form, &$form_state) { + // Delete all auto-generated menu links derived from menu router items. + db_delete('menu_links') + ->condition('module', 'system') + ->execute(); + // Rebuild menu links from current menu router items. + menu_rebuild(); + + drupal_set_message(t('System links derived from menu router paths have been rebuilt.')); +} diff --git a/www/sites/all/modules/contrib/admin_menu/admin_menu-rtl.css b/www/sites/all/modules/contrib/admin_menu/admin_menu-rtl.css new file mode 100644 index 0000000..9414dcf --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/admin_menu-rtl.css @@ -0,0 +1,64 @@ + +#admin-menu { + text-align: right; +} +#admin-menu .dropdown .admin-menu-users a { + background-position: 10% center; + padding-left: 22px; + padding-right: 0; +} +#admin-menu .dropdown .admin-menu-action, +#admin-menu .dropdown .admin-menu-search { + float: left; +} +#admin-menu .dropdown .admin-menu-action a { + border-left: none; + border-right: 1px solid #323232; +} + +/* All lists */ +#admin-menu a { + text-align: right; +} +#admin-menu .dropdown a { + border-left: 1px solid #323232; + border-right: 0; +} +#admin-menu .dropdown .admin-menu-tab a { + border-left: 1px solid #52565E; + border-right: 0; +} +#admin-menu .dropdown li li a { + border-left: 0; +} + +/* All list items */ +#admin-menu .dropdown li { + float: right; +} +#admin-menu .dropdown li li { +} + +/* Second-level lists */ +#admin-menu .dropdown li ul { + left: auto; + right: -999em; +} + +/* Third-and-above-level lists */ +#admin-menu .dropdown li li.expandable ul { + margin-left: 0; + margin-right: 160px; +} + +/* Lists nested under hovered list items */ +#admin-menu .dropdown li.admin-menu-action:hover ul { + left: 0 !important; + right: auto; +} + +/* Second-and-more-level hovering */ +#admin-menu .dropdown li li.expandable { + background-image: url(images/arrow-rtl.png); + background-position: 5px 6px; +} diff --git a/www/sites/all/modules/contrib/admin_menu/admin_menu.admin.js b/www/sites/all/modules/contrib/admin_menu/admin_menu.admin.js new file mode 100644 index 0000000..9ee9f36 --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/admin_menu.admin.js @@ -0,0 +1,62 @@ +(function($) { + +/** + * Live preview of Administration menu components. + */ +Drupal.behaviors.adminMenuLivePreview = { + attach: function (context, settings) { + $('input[name^="admin_menu_components"]', context).once('admin-menu-live-preview') + .change(function () { + var target = $(this).attr('rel'); + $(target).toggle(this.checked); + }) + .trigger('change'); + } +}; + +/** + * Automatically enables required permissions on demand. + * + * Many users do not understand that two permissions are required for the + * administration menu to appear. Since Drupal core provides no facility for + * this, we implement a simple manual confirmation for automatically enabling + * the "other" permission. + */ +Drupal.behaviors.adminMenuPermissionsSetupHelp = { + attach: function (context, settings) { + $('#permissions', context).once('admin-menu-permissions-setup', function () { + // Retrieve matrix/mapping - these need to use the same indexes for the + // same permissions and roles. + var $roles = $(this).find('th:not(:first)'); + var $admin = $(this).find('input[name$="[access administration pages]"]'); + var $menu = $(this).find('input[name$="[access administration menu]"]'); + + // Retrieve the permission label - without description. + var adminPermission = $.trim($admin.eq(0).parents('td').prev().children().get(0).firstChild.textContent); + var menuPermission = $.trim($menu.eq(0).parents('td').prev().children().get(0).firstChild.textContent); + + $admin.each(function (index) { + // Only proceed if both are not enabled already. + if (!(this.checked && $menu[index].checked)) { + // Stack both checkboxes and attach a click event handler to both. + $(this).add($menu[index]).click(function () { + // Do nothing when disabling a permission. + if (this.checked) { + // Figure out which is the other, check whether it still disabled, + // and if so, ask whether to auto-enable it. + var other = (this == $admin[index] ? $menu[index] : $admin[index]); + if (!other.checked && confirm(Drupal.t('Also allow !name role to !permission?', { + '!name': $roles[index].textContent, + '!permission': (this == $admin[index] ? menuPermission : adminPermission) + }))) { + other.checked = 'checked'; + } + } + }); + } + }); + }); + } +}; + +})(jQuery); diff --git a/www/sites/all/modules/contrib/admin_menu/admin_menu.api.php b/www/sites/all/modules/contrib/admin_menu/admin_menu.api.php new file mode 100644 index 0000000..2d212fb --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/admin_menu.api.php @@ -0,0 +1,164 @@ + Content types. + // The key denotes the dynamic path to expand to multiple menu items. + $map['admin/structure/types/manage/%node_type'] = array( + // Link generated items directly to the "Content types" item. + 'parent' => 'admin/structure/types', + // Create expansion arguments for the '%node_type' placeholder. + 'arguments' => array( + array( + '%node_type' => array_keys(node_type_get_types()), + ), + ), + ); + return $map; +} + +/** + * Add to the administration menu content before it is rendered. + * + * Only use this hook to add new data to the menu structure. Use + * hook_admin_menu_output_alter() to *alter* existing data. + * + * @param array $content + * A structured array suitable for drupal_render(), potentially containing: + * - menu: The administrative menu of links below the path 'admin/*'. + * - icon: The icon menu. + * - account: The user account name and log out link. + * - users: The user counter. + * Additionally, these special properties: + * - #components: The actual components contained in $content are configurable + * and depend on the 'admin_menu_components' configuration value. #components + * holds a copy of that for convenience. + * - #complete: A Boolean indicating whether the complete menu should be built, + * ignoring the current configuration in #components. + * Passed by reference. + * + * @see hook_admin_menu_output_alter() + * @see admin_menu_links_menu() + * @see admin_menu_links_icon() + * @see admin_menu_links_user() + * @see theme_admin_menu_links() + */ +function hook_admin_menu_output_build(&$content) { + // In case your implementation provides a configurable component, check + // whether the component should be displayed: + if (empty($content['#components']['shortcut.links']) && !$content['#complete']) { + return; + } + + // Add new top-level item to the menu. + if (isset($content['menu'])) { + $content['menu']['myitem'] = array( + '#title' => t('My item'), + // #attributes are used for list items (LI). + '#attributes' => array('class' => array('mymodule-myitem')), + '#href' => 'mymodule/path', + // #options are passed to l(). + '#options' => array( + 'query' => drupal_get_destination(), + // Apply a class on the link (anchor). + 'attributes' => array('class' => array('myitem-link-anchor')), + ), + // #weight controls the order of links in the resulting item list. + '#weight' => 50, + ); + } + // Add link to the icon menu to manually run cron. + if (isset($content['icon'])) { + $content['icon']['myitem']['cron'] = array( + '#title' => t('Run cron'), + '#access' => user_access('administer site configuration'), + '#href' => 'admin/reports/status/run-cron', + ); + } +} + +/** + * Change the administration menu content before it is rendered. + * + * Only use this hook to alter existing data in the menu structure. Use + * hook_admin_menu_output_build() to *add* new data. + * + * @param array $content + * A structured array suitable for drupal_render(). Passed by reference. + * + * @see hook_admin_menu_output_build() + */ +function hook_admin_menu_output_alter(&$content) { +} + +/** + * Return content to be replace via JS in the cached menu output. + * + * @param bool $complete + * A Boolean indicating whether all available components of the menu will be + * output and the cache will be skipped. + * + * @return array + * An associative array whose keys are jQuery selectors and whose values are + * strings containing the replacement content. + */ +function hook_admin_menu_replacements($complete) { + $items = array(); + // If the complete menu is output, then it is uncached and will contain the + // current counts already. + if (!$complete) { + // Check whether the users count component is enabled. + $components = variable_get('admin_menu_components', array()); + if (!empty($components['admin_menu.users']) && ($user_count = admin_menu_get_user_count())) { + // Replace the counters in the cached menu output with current counts. + $items['.admin-menu-users a'] = $user_count; + } + } + return $items; +} + +/** + * Inform about additional module-specific caches that can be cleared. + * + * Administration menu uses this hook to gather information about available + * caches that can be flushed individually. Each returned item forms a separate + * menu link below the "Flush all caches" link in the icon menu. + * + * @return array + * An associative array whose keys denote internal identifiers for a + * particular caches (which can be freely defined, but should be in a module's + * namespace) and whose values are associative arrays containing: + * - title: The name of the cache, without "cache" suffix. This label is + * output as link text, but also for the "!title cache cleared." + * confirmation message after flushing the cache; make sure it works and + * makes sense to users in both locations. + * - callback: The name of a function to invoke to flush the individual cache. + */ +function hook_admin_menu_cache_info() { + $caches['update'] = array( + 'title' => t('Update data'), + 'callback' => '_update_cache_clear', + ); + return $caches; +} diff --git a/www/sites/all/modules/contrib/admin_menu/admin_menu.color.css b/www/sites/all/modules/contrib/admin_menu/admin_menu.color.css new file mode 100644 index 0000000..ea3ef49 --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/admin_menu.color.css @@ -0,0 +1,45 @@ + +/** + * @file + * Administration menu color override. + */ + +#admin-menu { + background-color: #911; + background-image: url(images/bkg-red.png); +} +#admin-menu li.admin-menu-action a { + border-left-color: #a91f1f; +} + +/* All lists */ +#admin-menu ul a { + border-right-color: #a91f1f; +} +#admin-menu ul li.admin-menu-tab a { + border-right-color: #52565E; +} +#admin-menu li li a { + border-top-color: #801f1f; +} + +/* All list items */ +#admin-menu li li { + background-color: #991f1f; +} + +/* Second-and-more-level hovering */ +#admin-menu li li.expandable { + background-color: #b93f3f; +} +#admin-menu li li:hover { + background-color: #690f0f; +} +#admin-menu li li.expandable:hover a, +#admin-menu li li.expandable:hover li.expandable:hover a { + border-color: #801f1f; +} +#admin-menu li li.expandable:hover li a, +#admin-menu li li.expandable:hover li.expandable:hover li a { + border-color: #801f1f; +} diff --git a/www/sites/all/modules/contrib/admin_menu/admin_menu.css b/www/sites/all/modules/contrib/admin_menu/admin_menu.css new file mode 100644 index 0000000..52ae3ff --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/admin_menu.css @@ -0,0 +1,233 @@ + +/** + * @file + * Administration menu. + * + * Implementation of Sons of Suckerfish Dropdowns. + * + * @see www.htmldog.com/articles/suckerfish + */ + +#admin-menu { + background: #101010 url(images/bkg.png) bottom left repeat-x; + font-size: 9px; + font-family: "lucida grande", tahoma, verdana, arial, sans-serif; + left: 0; + position: absolute; + text-align: left; + top: 0; + width: 100%; +} +#admin-menu-wrapper { + overflow: hidden; +} +#admin-menu .dropdown .admin-menu-icon a { + padding: 1px 8px 4px; +} +#admin-menu .dropdown .admin-menu-icon ul a { + padding: 4px 8px; +} +#admin-menu .dropdown .admin-menu-icon img { + vertical-align: bottom; +} +#admin-menu .dropdown .admin-menu-users a { + background: transparent url(images/icon_users.png) 90% center no-repeat; + padding-right: 22px; +} +#admin-menu .dropdown .admin-menu-action, +#admin-menu .dropdown .admin-menu-search { + float: right; +} +#admin-menu .dropdown .admin-menu-action a { + border-left: 1px solid #323232; + border-right: none; +} +body.admin-menu { + margin-top: 20px !important; +} + +/* All lists */ +#admin-menu, +#admin-menu .dropdown { + line-height: 1.4em; + list-style: none; + margin: 0; + padding: 0; + z-index: 999; +} +#admin-menu .dropdown { + position: static; +} +#admin-menu a, +#admin-menu li > span { + background: transparent none; + border: none; + color: #EEE; + font-weight: normal; + text-align: left; /* LTR */ + text-decoration: none; +} +#admin-menu .dropdown a, +#admin-menu .dropdown li > span { + border-right: 1px solid #323232; /* LTR */ + display: block; + padding: 4px 8px; +} +#admin-menu .dropdown .admin-menu-tab a { + border-right: 1px solid #52565E; /* LTR */ +} +#admin-menu .dropdown li li a { + border-right: none; /* LTR */ + border-top: 1px solid #323232; +} + +/* All list items */ +#admin-menu .dropdown li { + background-image: none; + float: left; /* LTR */ + height: 100%; + list-style-image: none; + list-style-type: none; + margin: 0 !important; + padding: 0; +} +#admin-menu .dropdown .admin-menu-tab { + background: url(images/bkg_tab.png) repeat-x left bottom; + padding-bottom: 1px; +} +#admin-menu .dropdown li li { + background: #202020; + filter: Alpha(opacity=88); + float: none; + opacity: 0.88; + width: 160px; /* Required for Opera */ +} +#admin-menu .dropdown li li li { + filter: Alpha(opacity=100); + opacity: 1; +} + +/* Second-level lists */ +/* Note: We must hide sub-lists or scrollbars might appear (display: none is not read by screen readers). */ +#admin-menu .dropdown li ul { + background: none; + display: none; + left: -999em; /* LTR */ + line-height: 1.2em; + margin: 0; + position: absolute; + width: 160px; +} + +/* Third-and-above-level lists */ +#admin-menu .dropdown li li.expandable ul { + margin: -20px 0 0 160px; /* LTR */ +} + +#admin-menu .dropdown li:hover ul ul, +#admin-menu .dropdown li:hover ul ul ul, +#admin-menu .dropdown li:hover ul ul ul ul, +#admin-menu .dropdown li:hover ul ul ul ul ul { + display: none; + left: -999em; /* LTR */ +} + +/* Lists nested under hovered list items */ +#admin-menu .dropdown li:hover ul, +#admin-menu .dropdown li li:hover ul, +#admin-menu .dropdown li li li:hover ul, +#admin-menu .dropdown li li li li:hover ul, +#admin-menu .dropdown li li li li li:hover ul { + display: block; + left: auto; /* LTR */ +} +#admin-menu .dropdown li.admin-menu-action:hover ul { + right: 0; /* LTR */ +} + +/* Second-and-more-level hovering */ +#admin-menu .dropdown li li.expandable { + background: #45454A url(images/arrow.png) no-repeat 145px 6px; +} +#admin-menu .dropdown li li:hover { + background-color: #111; +} +#admin-menu .dropdown li li:hover a, +#admin-menu .dropdown li li:hover li:hover a, +#admin-menu .dropdown li li:hover li:hover li:hover a { + color: #FFF; +} +#admin-menu .dropdown li li.expandable:hover a, +#admin-menu .dropdown li li.expandable:hover li.expandable:hover a { + border-color: #444; + color: #EEE; +} +#admin-menu .dropdown li li.expandable:hover li a, +#admin-menu .dropdown li li.expandable:hover li.expandable:hover li a { + border-color: #323232; +} +#admin-menu .dropdown li li:hover li a { + color: #EEE; +} + +/* Search form */ +#admin-menu .admin-menu-search .form-item { + margin: 0; + padding: 0; +} +#admin-menu .admin-menu-search input { + background: #fff none center right no-repeat; + border: none; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + font-size: 10px; + margin: 1px 0; + outline: none; + padding: 2px 22px 2px 4px; + width: 158px; +} + +#admin-menu .dropdown .admin-menu-search-results { + display: block !important; + left: auto !important; + top: 100%; +} +#admin-menu .admin-menu-search-results, +#admin-menu .admin-menu-search-results li { + width: 186px; +} + +#admin-menu li.highlight { + background-color: #eee !important; +} +#admin-menu li.highlight > a { + border-color: #ccc !important; + color: #111 !important; +} + +/* #210615: Mozilla on Mac fix */ +html.js fieldset.collapsible div.fieldset-wrapper { + overflow: visible; +} + +/* Hide the menu on print output. */ +@media print { + #admin-menu { + display: none !important; + } + body.admin-menu { + margin-top: 0 !important; + } +} + +/** + * Tweaks permissions, if enabled. + */ +tr.admin-menu-tweak-permissions-processed { + cursor: pointer; + cursor: hand; +} +tr.admin-menu-tweak-permissions-processed td.module { + border-top: 0; +} diff --git a/www/sites/all/modules/contrib/admin_menu/admin_menu.inc b/www/sites/all/modules/contrib/admin_menu/admin_menu.inc new file mode 100644 index 0000000..2eab789 --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/admin_menu.inc @@ -0,0 +1,910 @@ + $data) { + // Convert named placeholders to anonymous placeholders, since the menu + // system stores paths using anonymous placeholders. + $replacements = array_fill_keys(array_keys($data['arguments'][0]), '%'); + $data['parent'] = strtr($data['parent'], $replacements); + $new_map[strtr($path, $replacements)] = $data; + } + $expand_map = $new_map; + unset($new_map); + + // Retrieve dynamic menu link tree for the expansion mappings. + // @todo Skip entire processing if initial $expand_map is empty and directly + // return $tree? + if (!empty($expand_map)) { + $tree_dynamic = admin_menu_tree_dynamic($expand_map); + } + else { + $tree_dynamic = array(); + } + + // Merge local tasks with static menu tree. + $tree = menu_tree_all_data($menu_name); + admin_menu_merge_tree($tree, $tree_dynamic, array()); + + return $tree; +} + +/** + * Load menu link trees for router paths containing dynamic arguments. + * + * @param $expand_map + * An array containing menu router path placeholder expansion argument + * mappings. + * + * @return + * An associative array whose keys are the parent paths of the menu router + * paths given in $expand_map as well as the parent paths of any child link + * deeper down the tree. The parent paths are used in admin_menu_merge_tree() + * to check whether anything needs to be merged. + * + * @see hook_admin_menu_map() + */ +function admin_menu_tree_dynamic(array $expand_map) { + $p_columns = array(); + for ($i = 1; $i <= MENU_MAX_DEPTH; $i++) { + $p_columns[] = 'p' . $i; + } + + // Fetch p* columns for all router paths to expand. + $router_paths = array_keys($expand_map); + $plids = db_select('menu_links', 'ml') + ->fields('ml', $p_columns) + ->condition('router_path', $router_paths) + ->execute() + ->fetchAll(PDO::FETCH_ASSOC); + + // Unlikely, but possible. + if (empty($plids)) { + return array(); + } + + // Use queried plid columns to query sub-trees for the router paths. + $query = db_select('menu_links', 'ml'); + $query->join('menu_router', 'm', 'ml.router_path = m.path'); + $query + ->fields('ml') + ->fields('m', array_diff(drupal_schema_fields_sql('menu_router'), drupal_schema_fields_sql('menu_links'))); + + // The retrieved menu link trees have to be ordered by depth, so parents + // always come before their children for the storage logic below. + foreach ($p_columns as $column) { + $query->orderBy($column, 'ASC'); + } + + $db_or = db_or(); + foreach ($plids as $path_plids) { + $db_and = db_and(); + // plids with value 0 may be ignored. + foreach (array_filter($path_plids) as $column => $plid) { + $db_and->condition($column, $plid); + } + $db_or->condition($db_and); + } + $query->condition($db_or); + $result = $query + ->execute() + ->fetchAllAssoc('mlid', PDO::FETCH_ASSOC); + + // Store dynamic links grouped by parent path for later merging and assign + // placeholder expansion arguments. + $tree_dynamic = array(); + foreach ($result as $mlid => $link) { + // If contained in $expand_map, then this is a (first) parent, and we need + // to store by the defined 'parent' path for later merging, as well as + // provide the expansion map arguments to apply to the dynamic tree. + if (isset($expand_map[$link['path']])) { + $parent_path = $expand_map[$link['path']]['parent']; + $link['expand_map'] = $expand_map[$link['path']]['arguments']; + } + // Otherwise, just store this link keyed by its parent path; the expand_map + // is automatically derived from parent paths. + else { + $parent_path = $result[$link['plid']]['path']; + } + + $tree_dynamic[$parent_path][] = $link; + } + + return $tree_dynamic; +} + +/** + * Walk through the entire menu tree and merge in expanded dynamic menu links. + * + * @param &$tree + * A menu tree structure as returned by menu_tree_all_data(). + * @param $tree_dynamic + * A dynamic menu tree structure as returned by admin_menu_tree_dynamic(). + * @param $expand_map + * An array containing menu router path placeholder expansion argument + * mappings. + * + * @see hook_admin_menu_map() + * @see admin_menu_tree_dynamic() + * @see menu_tree_all_data() + */ +function admin_menu_merge_tree(array &$tree, array $tree_dynamic, array $expand_map) { + foreach ($tree as $key => $data) { + $path = $data['link']['router_path']; + + // Recurse into regular menu tree. + if ($tree[$key]['below']) { + admin_menu_merge_tree($tree[$key]['below'], $tree_dynamic, $expand_map); + } + // Nothing to merge, if this parent path is not in our dynamic tree. + if (!isset($tree_dynamic[$path])) { + continue; + } + + // Add expanded dynamic items. + foreach ($tree_dynamic[$path] as $link) { + // If the dynamic item has custom placeholder expansion parameters set, + // use them, otherwise keep current. + if (isset($link['expand_map'])) { + // If there are currently no expansion parameters, we may use the new + // set immediately. + if (empty($expand_map)) { + $current_expand_map = $link['expand_map']; + } + else { + // Otherwise we need to filter out elements that differ from the + // current set, i.e. that are not in the same path. + $current_expand_map = array(); + foreach ($expand_map as $arguments) { + foreach ($arguments as $placeholder => $value) { + foreach ($link['expand_map'] as $new_arguments) { + // Skip the new argument if it doesn't contain the current + // replacement placeholders or if their values differ. + if (!isset($new_arguments[$placeholder]) || $new_arguments[$placeholder] != $value) { + continue; + } + $current_expand_map[] = $new_arguments; + } + } + } + } + } + else { + $current_expand_map = $expand_map; + } + + // Skip dynamic items without expansion parameters. + if (empty($current_expand_map)) { + continue; + } + + // Expand anonymous to named placeholders. + // @see _menu_load_objects() + $path_args = explode('/', $link['path']); + $load_functions = unserialize($link['load_functions']); + if (is_array($load_functions)) { + foreach ($load_functions as $index => $function) { + if ($function) { + if (is_array($function)) { + list($function,) = each($function); + } + // Add the loader function name minus "_load". + $placeholder = '%' . substr($function, 0, -5); + $path_args[$index] = $placeholder; + } + } + } + $path_dynamic = implode('/', $path_args); + + // Create new menu items using expansion arguments. + foreach ($current_expand_map as $arguments) { + // Create the cartesian product for all arguments and create new + // menu items for each generated combination thereof. + foreach (admin_menu_expand_args($arguments) as $replacements) { + $newpath = strtr($path_dynamic, $replacements); + // Skip this item, if any placeholder could not be replaced. + // Faster than trying to invoke _menu_translate(). + if (strpos($newpath, '%') !== FALSE) { + continue; + } + $map = explode('/', $newpath); + $item = admin_menu_translate($link, $map); + // Skip this item, if the current user does not have access. + if (empty($item)) { + continue; + } + // Build subtree using current replacement arguments. + $new_expand_map = array(); + foreach ($replacements as $placeholder => $value) { + $new_expand_map[$placeholder] = array($value); + } + admin_menu_merge_tree($item, $tree_dynamic, array($new_expand_map)); + $tree[$key]['below'] += $item; + } + } + } + // Sort new subtree items. + ksort($tree[$key]['below']); + } +} + +/** + * Translate an expanded router item into a menu link suitable for rendering. + * + * @param $router_item + * A menu router item. + * @param $map + * A path map with placeholders replaced. + */ +function admin_menu_translate($router_item, $map) { + _menu_translate($router_item, $map, TRUE); + + // Run through hook_translated_menu_link_alter() to add devel information, + // if configured. + $router_item['menu_name'] = 'management'; + // @todo Invoke as usual like _menu_link_translate(). + admin_menu_translated_menu_link_alter($router_item, NULL); + + if ($router_item['access']) { + // Override mlid to make this item unique; since these items are expanded + // from dynamic items, the mlid is always the same, so each item would + // replace any other. + // @todo Doing this instead leads to plenty of duplicate links below + // admin/structure/menu; likely a hidden recursion problem. + // $router_item['mlid'] = $router_item['href'] . $router_item['mlid']; + $router_item['mlid'] = $router_item['href']; + // Turn menu callbacks into regular menu items to make them visible. + if ($router_item['type'] == MENU_CALLBACK) { + $router_item['type'] = MENU_NORMAL_ITEM; + } + + // @see _menu_tree_check_access() + $key = (50000 + $router_item['weight']) . ' ' . $router_item['title'] . ' ' . $router_item['mlid']; + return array($key => array( + 'link' => $router_item, + 'below' => array(), + )); + } + + return array(); +} + +/** + * Create the cartesian product of multiple varying sized argument arrays. + * + * @param $arguments + * A two dimensional array of arguments. + * + * @see hook_admin_menu_map() + */ +function admin_menu_expand_args($arguments) { + $replacements = array(); + + // Initialize line cursors, move out array keys (placeholders) and assign + // numeric keys instead. + $i = 0; + $placeholders = array(); + $new_arguments = array(); + foreach ($arguments as $placeholder => $values) { + // Skip empty arguments. + if (empty($values)) { + continue; + } + $cursor[$i] = 0; + $placeholders[$i] = $placeholder; + $new_arguments[$i] = $values; + $i++; + } + $arguments = $new_arguments; + unset($new_arguments); + + if ($rows = count($arguments)) { + do { + // Collect current argument from each row. + $row = array(); + for ($i = 0; $i < $rows; ++$i) { + $row[$placeholders[$i]] = $arguments[$i][$cursor[$i]]; + } + $replacements[] = $row; + + // Increment cursor position. + $j = $rows - 1; + $cursor[$j]++; + while (!array_key_exists($cursor[$j], $arguments[$j])) { + // No more arguments left: reset cursor, go to next line and increment + // that cursor instead. Repeat until argument found or out of rows. + $cursor[$j] = 0; + if (--$j < 0) { + // We're done. + break 2; + } + $cursor[$j]++; + } + } while (1); + } + + return $replacements; +} + +/** + * Build the administration menu as renderable menu links. + * + * @param $tree + * A data structure representing the administration menu tree as returned from + * menu_tree_all_data(). + * + * @return + * The complete administration menu, suitable for theme_admin_menu_links(). + * + * @see theme_admin_menu_links() + * @see admin_menu_menu_alter() + */ +function admin_menu_links_menu($tree) { + $links = array(); + foreach ($tree as $data) { + // Skip items that are inaccessible, invisible, or link to their parent. + // (MENU_DEFAULT_LOCAL_TASK), and MENU_CALLBACK-alike items that should only + // appear in the breadcrumb. + if (!$data['link']['access'] || $data['link']['type'] & MENU_LINKS_TO_PARENT || $data['link']['type'] == MENU_VISIBLE_IN_BREADCRUMB || $data['link']['hidden'] == 1) { + continue; + } + // Hide 'Administer' and make child links appear on this level. + // @todo Make this configurable. + if ($data['link']['router_path'] == 'admin') { + if ($data['below']) { + $links = array_merge($links, admin_menu_links_menu($data['below'])); + } + continue; + } + // Omit alias lookups. + $data['link']['localized_options']['alias'] = TRUE; + // Remove description to prevent mouseover tooltip clashes. + unset($data['link']['localized_options']['attributes']['title']); + + // Make action links (typically "Add ...") appear first in dropdowns. + // They might appear first already, but only as long as there is no link + // that comes alphabetically first (e.g., a node type with label "Ad"). + if ($data['link']['type'] & MENU_IS_LOCAL_ACTION) { + $data['link']['weight'] -= 1000; + } + + $links[$data['link']['href']] = array( + '#title' => $data['link']['title'], + '#href' => $data['link']['href'], + '#options' => $data['link']['localized_options'], + '#weight' => $data['link']['weight'], + ); + + // Recurse to add any child links. + $children = array(); + if ($data['below']) { + $children = admin_menu_links_menu($data['below']); + $links[$data['link']['href']] += $children; + } + + // Handle links pointing to category/overview pages. + if ($data['link']['page_callback'] == 'system_admin_menu_block_page' || $data['link']['page_callback'] == 'system_admin_config_page') { + // Apply a marker for others to consume. + $links[$data['link']['href']]['#is_category'] = TRUE; + // Automatically hide empty categories. + // Check for empty children first for performance. Only when non-empty + // (typically 'admin/config'), check whether children are accessible. + if (empty($children) || !element_get_visible_children($children)) { + $links[$data['link']['href']]['#access'] = FALSE; + } + } + } + return $links; +} + +/** + * Build icon menu links; mostly containing maintenance helpers. + * + * @see theme_admin_menu_links() + */ +function admin_menu_links_icon() { + $destination = drupal_get_destination(); + + $links = array( + '#theme' => 'admin_menu_links', + '#wrapper_attributes' => array('id' => 'admin-menu-icon'), + '#weight' => -100, + ); + $links['icon'] = array( + '#title' => theme('admin_menu_icon'), + '#attributes' => array('class' => array('admin-menu-icon')), + '#href' => '', + '#options' => array( + 'html' => TRUE, + ), + ); + // Add link to manually run cron. + $links['icon']['cron'] = array( + '#title' => t('Run cron'), + '#weight' => 50, + '#access' => user_access('administer site configuration'), + '#href' => 'admin/reports/status/run-cron', + ); + // Add link to run update.php. + $links['icon']['update'] = array( + '#title' => t('Run updates'), + '#weight' => 50, + // @see update_access_allowed() + '#access' => $GLOBALS['user']->uid == 1 || !empty($GLOBALS['update_free_access']) || user_access('administer software updates'), + '#href' => base_path() . 'update.php', + '#options' => array( + 'external' => TRUE, + ), + ); + // Add link to drupal.org. + $links['icon']['drupal.org'] = array( + '#title' => 'Drupal.org', + '#weight' => 100, + '#access' => user_access('display drupal links'), + '#href' => 'http://drupal.org', + ); + // Add links to project issue queues. + foreach (module_list(FALSE, TRUE) as $module) { + $info = drupal_parse_info_file(drupal_get_path('module', $module) . '/' . $module . '.info'); + if (!isset($info['project']) || isset($links['icon']['drupal.org'][$info['project']])) { + continue; + } + $links['icon']['drupal.org'][$info['project']] = array( + '#title' => t('@project issue queue', array('@project' => $info['name'])), + '#weight' => ($info['project'] == 'drupal' ? -10 : 0), + '#href' => 'http://drupal.org/project/issues/' . $info['project'], + '#options' => array( + 'query' => array('version' => (isset($info['core']) ? $info['core'] : 'All')), + ), + ); + } + // Add items to flush caches. + $links['icon']['flush-cache'] = array( + '#title' => t('Flush all caches'), + '#weight' => 20, + '#access' => user_access('flush caches'), + '#href' => 'admin_menu/flush-cache', + '#options' => array( + 'query' => $destination + array('token' => drupal_get_token('admin_menu/flush-cache')), + ), + ); + $caches = module_invoke_all('admin_menu_cache_info'); + foreach ($caches as $name => $cache) { + $links['icon']['flush-cache'][$name] = array( + '#title' => $cache['title'], + '#href' => 'admin_menu/flush-cache/' . $name, + '#options' => array( + 'query' => $destination + array('token' => drupal_get_token('admin_menu/flush-cache/' . $name)), + ), + ); + } + + // Add Devel module menu links. + if (module_exists('devel')) { + $devel_tree = menu_build_tree('devel'); + $devel_links = admin_menu_links_menu($devel_tree); + if (element_get_visible_children($devel_links)) { + $links['icon']['devel'] = array( + '#title' => t('Development'), + '#weight' => 30, + ) + $devel_links; + } + } + + return $links; +} + +/** + * Builds the account links. + * + * @see theme_admin_menu_links() + */ +function admin_menu_links_account() { + $links = array( + '#theme' => 'admin_menu_links', + '#wrapper_attributes' => array('id' => 'admin-menu-account'), + '#weight' => 100, + ); + $links['account'] = array( + '#title' => format_username($GLOBALS['user']), + '#weight' => -99, + '#attributes' => array('class' => array('admin-menu-action', 'admin-menu-account')), + '#href' => 'user/' . $GLOBALS['user']->uid, + ); + $links['logout'] = array( + '#title' => t('Log out'), + '#weight' => -100, + '#attributes' => array('class' => array('admin-menu-action')), + '#href' => 'user/logout', + ); + // Add Devel module switch user links. + $switch_links = module_invoke('devel', 'switch_user_list'); + if (!empty($switch_links) && count($switch_links) > 1) { + foreach ($switch_links as $uid => $link) { + $links['account'][$link['title']] = array( + '#title' => $link['title'], + '#description' => $link['attributes']['title'], + '#href' => $link['href'], + '#options' => array( + 'query' => $link['query'], + 'html' => !empty($link['html']), + ), + ); + } + } + return $links; +} + +/** + * Builds user counter. + * + * @see theme_admin_menu_links() + */ +function admin_menu_links_users() { + $links = array( + '#theme' => 'admin_menu_links', + '#wrapper_attributes' => array('id' => 'admin-menu-users'), + '#weight' => 150, + ); + // Add link to show current authenticated/anonymous users. + $links['user-counter'] = array( + '#title' => admin_menu_get_user_count(), + '#description' => t('Current anonymous / authenticated users'), + '#weight' => -90, + '#attributes' => array('class' => array('admin-menu-action', 'admin-menu-users')), + '#href' => (user_access('administer users') ? 'admin/people/people' : 'user'), + ); + return $links; +} + +/** + * Build search widget. + * + * @see theme_admin_menu_links() + */ +function admin_menu_links_search() { + $links = array( + '#theme' => 'admin_menu_links', + '#wrapper_attributes' => array('id' => 'admin-menu-search'), + '#weight' => 180, + ); + $links['search'] = array( + '#type' => 'textfield', + '#title' => t('Search'), + '#title_display' => 'attribute', + '#attributes' => array( + 'placeholder' => t('Search'), + 'class' => array('admin-menu-search'), + ), + ); + return $links; +} + +/** + * Form builder function for module settings. + */ +function admin_menu_theme_settings() { + $form['admin_menu_margin_top'] = array( + '#type' => 'checkbox', + '#title' => t('Adjust top margin'), + '#default_value' => variable_get('admin_menu_margin_top', 1), + '#description' => t('Shifts the site output down by approximately 20 pixels from the top of the viewport. If disabled, absolute- or fixed-positioned page elements may be covered by the administration menu.'), + ); + $form['admin_menu_position_fixed'] = array( + '#type' => 'checkbox', + '#title' => t('Keep menu at top of page'), + '#default_value' => variable_get('admin_menu_position_fixed', 1), + '#description' => t('Displays the administration menu always at the top of the browser viewport (even when scrolling the page).'), + ); + // @todo Re-confirm this with latest browser versions. + $form['admin_menu_position_fixed']['#description'] .= '
' . t('In some browsers, this setting may result in a malformed page, an invisible cursor, non-selectable elements in forms, or other issues.') . ''; + + $form['advanced'] = array( + '#type' => 'vertical_tabs', + '#title' => t('Advanced settings'), + ); + + $form['plugins'] = array( + '#type' => 'fieldset', + '#title' => t('Plugins'), + '#group' => 'advanced', + ); + $form['plugins']['admin_menu_components'] = array( + '#type' => 'checkboxes', + '#title' => t('Enabled components'), + '#options' => array( + 'admin_menu.icon' => t('Icon menu'), + 'admin_menu.menu' => t('Administration menu'), + 'admin_menu.search' => t('Search bar'), + 'admin_menu.users' => t('User counts'), + 'admin_menu.account' => t('Account links'), + ), + ); + $form['plugins']['admin_menu_components']['#default_value'] = array_keys(array_filter(variable_get('admin_menu_components', $form['plugins']['admin_menu_components']['#options']))); + + $process = element_info_property('checkboxes', '#process', array()); + $form['plugins']['admin_menu_components']['#process'] = array_merge(array('admin_menu_settings_process_components'), $process); + $form['#attached']['js'][] = drupal_get_path('module', 'admin_menu') . '/admin_menu.admin.js'; + + $form['tweaks'] = array( + '#type' => 'fieldset', + '#title' => t('System tweaks'), + '#group' => 'advanced', + ); + $form['tweaks']['admin_menu_tweak_modules'] = array( + '#type' => 'checkbox', + '#title' => t('Collapse module groups on the %modules page', array( + '%modules' => t('Modules'), + '!modules-url' => url('admin/modules'), + )), + '#default_value' => variable_get('admin_menu_tweak_modules', 0), + ); + if (module_exists('util')) { + $form['tweaks']['admin_menu_tweak_modules']['#description'] .= '
' . t('If the Utility module was installed for this purpose, it can be safely disabled and uninstalled.') . ''; + } + $form['tweaks']['admin_menu_tweak_permissions'] = array( + '#type' => 'checkbox', + '#title' => t('Collapse module groups on the %permissions page', array( + '%permissions' => t('Permissions'), + '@permissions-url' => url('admin/people/permissions'), + )), + '#default_value' => variable_get('admin_menu_tweak_permissions', 0), + ); + $form['tweaks']['admin_menu_tweak_tabs'] = array( + '#type' => 'checkbox', + '#title' => t('Move local tasks into menu'), + '#default_value' => variable_get('admin_menu_tweak_tabs', 0), + '#description' => t('Moves the tabs on all pages into the administration menu. Only possible for themes using the CSS classes tabs primary and tabs secondary.'), + ); + + $form['performance'] = array( + '#type' => 'fieldset', + '#title' => t('Performance'), + '#group' => 'advanced', + ); + $form['performance']['admin_menu_cache_client'] = array( + '#type' => 'checkbox', + '#title' => t('Cache menu in client-side browser'), + '#default_value' => variable_get('admin_menu_cache_client', 1), + ); + + return system_settings_form($form); +} + +/** + * #process callback for component plugin form element in admin_menu_theme_settings(). + */ +function admin_menu_settings_process_components($element) { + // Assign 'rel' attributes to all options to achieve a live preview. + // Unfortunately, #states relies on wrapping .form-wrapper classes, so it + // cannot be used here. + foreach ($element['#options'] as $key => $label) { + if (!isset($element[$key]['#attributes']['rel'])) { + $id = preg_replace('/[^a-z]/', '-', $key); + $element[$key]['#attributes']['rel'] = '#' . $id; + } + } + return $element; +} + +/** + * Form validation handler for admin_menu_theme_settings(). + */ +function admin_menu_theme_settings_validate(&$form, &$form_state) { + // Change the configured components to Boolean values. + foreach ($form_state['values']['admin_menu_components'] as $component => &$enabled) { + $enabled = (bool) $enabled; + } +} + +/** + * Implementation of hook_form_FORM_ID_alter(). + * + * Extends Devel module with Administration menu developer settings. + */ +function _admin_menu_form_devel_admin_settings_alter(&$form, $form_state) { + // Shift system_settings_form buttons. + $weight = isset($form['buttons']['#weight']) ? $form['buttons']['#weight'] : 0; + $form['buttons']['#weight'] = $weight + 1; + + $form['admin_menu'] = array( + '#type' => 'fieldset', + '#title' => t('Administration menu settings'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + $display_options = array('mid', 'weight', 'pid'); + $display_options = array(0 => t('None'), 'mlid' => t('Menu link ID'), 'weight' => t('Weight'), 'plid' => t('Parent link ID')); + $form['admin_menu']['admin_menu_display'] = array( + '#type' => 'radios', + '#title' => t('Display additional data for each menu item'), + '#default_value' => variable_get('admin_menu_display', 0), + '#options' => $display_options, + '#description' => t('Display the selected items next to each menu item link.'), + ); + $form['admin_menu']['admin_menu_show_all'] = array( + '#type' => 'checkbox', + '#title' => t('Display all menu items'), + '#default_value' => variable_get('admin_menu_show_all', 0), + '#description' => t('If enabled, all menu items are displayed regardless of your site permissions. Note: Do not enable on a production site.'), + ); +} + +/** + * Flush all caches or a specific one. + * + * @param $name + * (optional) Name of cache to flush. + */ +function admin_menu_flush_cache($name = NULL) { + if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], current_path())) { + return MENU_ACCESS_DENIED; + } + if (isset($name)) { + $caches = module_invoke_all('admin_menu_cache_info'); + if (!isset($caches[$name])) { + return MENU_NOT_FOUND; + } + } + else { + $caches[$name] = array( + 'title' => t('Every'), + 'callback' => 'drupal_flush_all_caches', + ); + } + // Pass the cache to flush forward to the callback. + $function = $caches[$name]['callback']; + $function($name); + + drupal_set_message(t('!title cache cleared.', array('!title' => $caches[$name]['title']))); + + // The JavaScript injects a destination request parameter pointing to the + // originating page, so the user is redirected back to that page. Without + // destination parameter, the redirect ends on the front page. + drupal_goto(); +} + +/** + * Implements hook_admin_menu_cache_info(). + */ +function admin_menu_admin_menu_cache_info() { + $caches['admin_menu'] = array( + 'title' => t('Administration menu'), + 'callback' => '_admin_menu_flush_cache', + ); + return $caches; +} + +/** + * Implements hook_admin_menu_cache_info() on behalf of System module. + */ +function system_admin_menu_cache_info() { + $caches = array( + 'assets' => t('CSS and JavaScript'), + 'cache' => t('Page and else'), + 'menu' => t('Menu'), + 'registry' => t('Class registry'), + 'theme' => t('Theme registry'), + ); + foreach ($caches as $name => $cache) { + $caches[$name] = array( + 'title' => $cache, + 'callback' => '_admin_menu_flush_cache', + ); + } + return $caches; +} + +/** + * Implements hook_admin_menu_cache_info() on behalf of Update module. + */ +function update_admin_menu_cache_info() { + $caches['update'] = array( + 'title' => t('Update data'), + 'callback' => '_update_cache_clear', + ); + return $caches; +} + +/** + * Flush all caches or a specific one. + * + * @param $name + * (optional) Name of cache to flush. + * + * @see system_admin_menu_cache_info() + */ +function _admin_menu_flush_cache($name = NULL) { + switch ($name) { + case 'admin_menu': + admin_menu_flush_caches(); + break; + + case 'menu': + menu_rebuild(); + break; + + case 'registry': + registry_rebuild(); + // Fall-through to clear cache tables, since registry information is + // usually the base for other data that is cached (e.g. SimpleTests). + case 'cache': + // Don't clear cache_form - in-progress form submissions may break. + // Ordered so clearing the page cache will always be the last action. + // @see drupal_flush_all_caches() + $core = array('cache', 'cache_bootstrap', 'cache_filter', 'cache_page'); + $cache_tables = array_merge(module_invoke_all('flush_caches'), $core); + foreach ($cache_tables as $table) { + cache_clear_all('*', $table, TRUE); + } + break; + + case 'assets': + // Change query-strings on css/js files to enforce reload for all users. + _drupal_flush_css_js(); + + drupal_clear_css_cache(); + drupal_clear_js_cache(); + + // Clear the page cache, since cached HTML pages might link to old CSS and + // JS aggregates. + cache_clear_all('*', 'cache_page', TRUE); + break; + + case 'theme': + system_rebuild_theme_data(); + drupal_theme_rebuild(); + break; + } +} + +/** + * Preprocesses variables for theme_admin_menu_icon(). + */ +function template_preprocess_admin_menu_icon(&$variables) { + // Image source might have been passed in as theme variable. + if (!isset($variables['src'])) { + if (theme_get_setting('toggle_favicon')) { + $variables['src'] = theme_get_setting('favicon'); + } + else { + $variables['src'] = base_path() . 'misc/favicon.ico'; + } + } + // Strip the protocol without delimiters for transient HTTP/HTTPS support. + // Since the menu is cached on the server-side and client-side, the cached + // version might contain a HTTP link, whereas the actual page is on HTTPS. + // Relative paths will work fine, but theme_get_setting() returns an + // absolute URI. + $variables['src'] = preg_replace('@^https?:@', '', $variables['src']); + $variables['src'] = check_plain($variables['src']); + $variables['alt'] = t('Home'); +} + +/** + * Renders an icon to display in the administration menu. + * + * @ingroup themeable + */ +function theme_admin_menu_icon($variables) { + return '' . $variables['alt'] . ''; +} + diff --git a/www/sites/all/modules/contrib/admin_menu/admin_menu.info b/www/sites/all/modules/contrib/admin_menu/admin_menu.info new file mode 100644 index 0000000..c6dbd89 --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/admin_menu.info @@ -0,0 +1,16 @@ +name = Administration menu +description = "Provides a dropdown menu to most administrative tasks and other common destinations (to users with the proper permissions)." +package = Administration +core = 7.x +configure = admin/config/administration/admin_menu +; Requires menu_build_tree() conditions; available after 7.10. +; @see http://drupal.org/node/1025582 +dependencies[] = system (>7.10) +files[] = tests/admin_menu.test + +; Information added by Drupal.org packaging script on 2014-12-19 +version = "7.x-3.0-rc5" +core = "7.x" +project = "admin_menu" +datestamp = "1419029284" + diff --git a/www/sites/all/modules/contrib/admin_menu/admin_menu.install b/www/sites/all/modules/contrib/admin_menu/admin_menu.install new file mode 100644 index 0000000..4e5443d --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/admin_menu.install @@ -0,0 +1,123 @@ +fields(array('weight' => 100)) + ->condition('type', 'module') + ->condition('name', 'admin_menu') + ->execute(); +} + +/** + * Implements hook_uninstall(). + */ +function admin_menu_uninstall() { + // Delete variables. + variable_del('admin_menu_components'); + variable_del('admin_menu_margin_top'); + variable_del('admin_menu_position_fixed'); + variable_del('admin_menu_tweak_modules'); + variable_del('admin_menu_tweak_tabs'); + variable_del('admin_menu_show_all'); + variable_del('admin_menu_display'); + variable_del('admin_menu_cache_server'); + variable_del('admin_menu_cache_client'); + // Unused variables still should be deleted. + variable_del('admin_menu_devel_modules'); + variable_del('admin_menu_devel_modules_enabled'); + variable_del('admin_menu_devel_modules_skip'); +} + +/** + * Ensure that admin_menu is rebuilt after upgrading to D6. + */ +function admin_menu_update_6000() { + // Drop the {admin_menu} table in admin_menu_update_6000() on sites that used + // one of the later patches in #132524. + if (db_table_exists('admin_menu')) { + db_drop_table('admin_menu'); + } +} + +/** + * Wipe and rebuild so we can switch the icon path to . + */ +function admin_menu_update_6001() { + db_delete('menu_links')->condition('module', 'admin_menu')->execute(); + menu_cache_clear('admin_menu'); +} + +/** + * Add {cache_admin_menu} table. + */ +function admin_menu_update_7300() { + if (!db_table_exists('cache_admin_menu')) { + $schema = drupal_get_schema_unprocessed('system', 'cache'); + db_create_table('cache_admin_menu', $schema); + } +} + +/** + * Increase the module weight. + * + * @see admin_menu_install() + */ +function admin_menu_update_7302() { + db_update('system') + ->fields(array('weight' => 100)) + ->condition('type', 'module') + ->condition('name', 'admin_menu') + ->execute(); +} + +/** + * Remove local tasks from {menu_links} table. + */ +function admin_menu_update_7303() { + db_delete('menu_router') + ->condition('path', 'admin/%', 'LIKE') + ->condition('type', MENU_IS_LOCAL_TASK, '&') + ->execute(); +} + +/** + * Remove obsolete 'admin_menu' menu and all orphan links in it. + */ +function admin_menu_update_7304() { + // Remove the custom menu used by 6.x-1.x. + if (db_table_exists('menu_custom')) { + db_delete('menu_custom')->condition('menu_name', 'admin_menu')->execute(); + } + + // 6.x-1.x cloned the entire link structure below the path 'admin' into a + // separate 'menu_name' "admin_menu" with 'module' "admin_menu". 6.x-3.x and + // early alpha versions of 7.x-3.x still did something similar. All of these + // records are obsolete. Removal of the 'module' records (without different + // menu_name) is particularly important, since they would otherwise appear + // as duplicate links. + db_delete('menu_links') + ->condition(db_or() + ->condition('module', 'admin_menu') + ->condition('menu_name', 'admin_menu') + ) + ->execute(); +} diff --git a/www/sites/all/modules/contrib/admin_menu/admin_menu.js b/www/sites/all/modules/contrib/admin_menu/admin_menu.js new file mode 100644 index 0000000..2e28b55 --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/admin_menu.js @@ -0,0 +1,385 @@ +(function($) { + +Drupal.admin = Drupal.admin || {}; +Drupal.admin.behaviors = Drupal.admin.behaviors || {}; +Drupal.admin.hashes = Drupal.admin.hashes || {}; + +/** + * Core behavior for Administration menu. + * + * Test whether there is an administration menu is in the output and execute all + * registered behaviors. + */ +Drupal.behaviors.adminMenu = { + attach: function (context, settings) { + // Initialize settings. + settings.admin_menu = $.extend({ + suppress: false, + margin_top: false, + position_fixed: false, + tweak_modules: false, + tweak_permissions: false, + tweak_tabs: false, + destination: '', + basePath: settings.basePath, + hash: 0, + replacements: {} + }, settings.admin_menu || {}); + // Check whether administration menu should be suppressed. + if (settings.admin_menu.suppress) { + return; + } + var $adminMenu = $('#admin-menu:not(.admin-menu-processed)', context); + // Client-side caching; if administration menu is not in the output, it is + // fetched from the server and cached in the browser. + if (!$adminMenu.length && settings.admin_menu.hash) { + Drupal.admin.getCache(settings.admin_menu.hash, function (response) { + if (typeof response == 'string' && response.length > 0) { + $('body', context).append(response); + } + var $adminMenu = $('#admin-menu:not(.admin-menu-processed)', context); + // Apply our behaviors. + Drupal.admin.attachBehaviors(context, settings, $adminMenu); + // Allow resize event handlers to recalculate sizes/positions. + $(window).triggerHandler('resize'); + }); + } + // If the menu is in the output already, this means there is a new version. + else { + // Apply our behaviors. + Drupal.admin.attachBehaviors(context, settings, $adminMenu); + } + } +}; + +/** + * Collapse fieldsets on Modules page. + */ +Drupal.behaviors.adminMenuCollapseModules = { + attach: function (context, settings) { + if (settings.admin_menu.tweak_modules) { + $('#system-modules fieldset:not(.collapsed)', context).addClass('collapsed'); + } + } +}; + +/** + * Collapse modules on Permissions page. + */ +Drupal.behaviors.adminMenuCollapsePermissions = { + attach: function (context, settings) { + if (settings.admin_menu.tweak_permissions) { + // Freeze width of first column to prevent jumping. + $('#permissions th:first', context).css({ width: $('#permissions th:first', context).width() }); + // Attach click handler. + $modules = $('#permissions tr:has(td.module)', context).once('admin-menu-tweak-permissions', function () { + var $module = $(this); + $module.bind('click.admin-menu', function () { + // @todo Replace with .nextUntil() in jQuery 1.4. + $module.nextAll().each(function () { + var $row = $(this); + if ($row.is(':has(td.module)')) { + return false; + } + $row.toggleClass('element-hidden'); + }); + }); + }); + // Collapse all but the targeted permission rows set. + if (window.location.hash.length) { + $modules = $modules.not(':has(' + window.location.hash + ')'); + } + $modules.trigger('click.admin-menu'); + } + } +}; + +/** + * Apply margin to page. + * + * Note that directly applying marginTop does not work in IE. To prevent + * flickering/jumping page content with client-side caching, this is a regular + * Drupal behavior. + */ +Drupal.behaviors.adminMenuMarginTop = { + attach: function (context, settings) { + if (!settings.admin_menu.suppress && settings.admin_menu.margin_top) { + $('body:not(.admin-menu)', context).addClass('admin-menu'); + } + } +}; + +/** + * Retrieve content from client-side cache. + * + * @param hash + * The md5 hash of the content to retrieve. + * @param onSuccess + * A callback function invoked when the cache request was successful. + */ +Drupal.admin.getCache = function (hash, onSuccess) { + if (Drupal.admin.hashes.hash !== undefined) { + return Drupal.admin.hashes.hash; + } + $.ajax({ + cache: true, + type: 'GET', + dataType: 'text', // Prevent auto-evaluation of response. + global: false, // Do not trigger global AJAX events. + url: Drupal.settings.admin_menu.basePath.replace(/admin_menu/, 'js/admin_menu/cache/' + hash), + success: onSuccess, + complete: function (XMLHttpRequest, status) { + Drupal.admin.hashes.hash = status; + } + }); +}; + +/** + * TableHeader callback to determine top viewport offset. + * + * @see toolbar.js + */ +Drupal.admin.height = function() { + var $adminMenu = $('#admin-menu'); + var height = $adminMenu.outerHeight(); + // In IE, Shadow filter adds some extra height, so we need to remove it from + // the returned height. + if ($adminMenu.css('filter') && $adminMenu.css('filter').match(/DXImageTransform\.Microsoft\.Shadow/)) { + height -= $adminMenu.get(0).filters.item("DXImageTransform.Microsoft.Shadow").strength; + } + return height; +}; + +/** + * @defgroup admin_behaviors Administration behaviors. + * @{ + */ + +/** + * Attach administrative behaviors. + */ +Drupal.admin.attachBehaviors = function (context, settings, $adminMenu) { + if ($adminMenu.length) { + $adminMenu.addClass('admin-menu-processed'); + $.each(Drupal.admin.behaviors, function() { + this(context, settings, $adminMenu); + }); + } +}; + +/** + * Apply 'position: fixed'. + */ +Drupal.admin.behaviors.positionFixed = function (context, settings, $adminMenu) { + if (settings.admin_menu.position_fixed) { + $adminMenu.addClass('admin-menu-position-fixed'); + $adminMenu.css('position', 'fixed'); + } +}; + +/** + * Move page tabs into administration menu. + */ +Drupal.admin.behaviors.pageTabs = function (context, settings, $adminMenu) { + if (settings.admin_menu.tweak_tabs) { + var $tabs = $(context).find('ul.tabs.primary'); + $adminMenu.find('#admin-menu-wrapper > ul').eq(1) + .append($tabs.find('li').addClass('admin-menu-tab')); + $(context).find('ul.tabs.secondary') + .appendTo('#admin-menu-wrapper > ul > li.admin-menu-tab.active') + .removeClass('secondary'); + $tabs.remove(); + } +}; + +/** + * Perform dynamic replacements in cached menu. + */ +Drupal.admin.behaviors.replacements = function (context, settings, $adminMenu) { + for (var item in settings.admin_menu.replacements) { + $(item, $adminMenu).html(settings.admin_menu.replacements[item]); + } +}; + +/** + * Inject destination query strings for current page. + */ +Drupal.admin.behaviors.destination = function (context, settings, $adminMenu) { + if (settings.admin_menu.destination) { + $('a.admin-menu-destination', $adminMenu).each(function() { + this.search += (!this.search.length ? '?' : '&') + Drupal.settings.admin_menu.destination; + }); + } +}; + +/** + * Apply JavaScript-based hovering behaviors. + * + * @todo This has to run last. If another script registers additional behaviors + * it will not run last. + */ +Drupal.admin.behaviors.hover = function (context, settings, $adminMenu) { + // Delayed mouseout. + $('li.expandable', $adminMenu).hover( + function () { + // Stop the timer. + clearTimeout(this.sfTimer); + // Display child lists. + $('> ul', this) + .css({left: 'auto', display: 'block'}) + // Immediately hide nephew lists. + .parent().siblings('li').children('ul').css({left: '-999em', display: 'none'}); + }, + function () { + // Start the timer. + var uls = $('> ul', this); + this.sfTimer = setTimeout(function () { + uls.css({left: '-999em', display: 'none'}); + }, 400); + } + ); +}; + +/** + * Apply the search bar functionality. + */ +Drupal.admin.behaviors.search = function (context, settings, $adminMenu) { + // @todo Add a HTML ID. + var $input = $('input.admin-menu-search', $adminMenu); + // Initialize the current search needle. + var needle = $input.val(); + // Cache of all links that can be matched in the menu. + var links; + // Minimum search needle length. + var needleMinLength = 2; + // Append the results container. + var $results = $('
').insertAfter($input); + + /** + * Executes the search upon user input. + */ + function keyupHandler() { + var matches, $html, value = $(this).val(); + // Only proceed if the search needle has changed. + if (value !== needle) { + needle = value; + // Initialize the cache of menu links upon first search. + if (!links && needle.length >= needleMinLength) { + // @todo Limit to links in dropdown menus; i.e., skip menu additions. + links = buildSearchIndex($adminMenu.find('li:not(.admin-menu-action, .admin-menu-action li) > a')); + } + // Empty results container when deleting search text. + if (needle.length < needleMinLength) { + $results.empty(); + } + // Only search if the needle is long enough. + if (needle.length >= needleMinLength && links) { + matches = findMatches(needle, links); + // Build the list in a detached DOM node. + $html = buildResultsList(matches); + // Display results. + $results.empty().append($html); + } + } + } + + /** + * Builds the search index. + */ + function buildSearchIndex($links) { + return $links + .map(function () { + var text = (this.textContent || this.innerText); + // Skip menu entries that do not contain any text (e.g., the icon). + if (typeof text === 'undefined') { + return; + } + return { + text: text, + textMatch: text.toLowerCase(), + element: this + }; + }); + } + + /** + * Searches the index for a given needle and returns matching entries. + */ + function findMatches(needle, links) { + var needleMatch = needle.toLowerCase(); + // Select matching links from the cache. + return $.grep(links, function (link) { + return link.textMatch.indexOf(needleMatch) !== -1; + }); + } + + /** + * Builds the search result list in a detached DOM node. + */ + function buildResultsList(matches) { + var $html = $(''; + } + return $output; +} + +/** + * Function used by uasort to sort structured arrays by #weight AND #title. + */ +function admin_menu_element_sort($a, $b) { + // @see element_sort() + $a_weight = isset($a['#weight']) ? $a['#weight'] : 0; + $b_weight = isset($b['#weight']) ? $b['#weight'] : 0; + if ($a_weight == $b_weight) { + // @see element_sort_by_title() + $a_title = isset($a['#title']) ? $a['#title'] : ''; + $b_title = isset($b['#title']) ? $b['#title'] : ''; + return strnatcasecmp($a_title, $b_title); + } + return ($a_weight < $b_weight) ? -1 : 1; +} + +/** + * Implements hook_translated_menu_link_alter(). + * + * Here is where we make changes to links that need dynamic information such + * as the current page path or the number of users. + */ +function admin_menu_translated_menu_link_alter(&$item, $map) { + global $user, $base_url; + static $access_all; + + if ($item['menu_name'] != 'admin_menu') { + return; + } + + // Check whether additional development output is enabled. + if (!isset($access_all)) { + $access_all = variable_get('admin_menu_show_all', 0) && module_exists('devel'); + } + // Prepare links that would not be displayed normally. + if ($access_all && !$item['access']) { + $item['access'] = TRUE; + // Prepare for http://drupal.org/node/266596 + if (!isset($item['localized_options'])) { + _menu_item_localize($item, $map, TRUE); + } + } + + // Don't waste cycles altering items that are not visible + if (!$item['access']) { + return; + } + + // Add developer information to all links, if enabled. + if ($extra = variable_get('admin_menu_display', 0)) { + $item['title'] .= ' ' . $extra[0] . ': ' . $item[$extra]; + } +} + +/** + * Implements hook_flush_caches(). + * + * Flushes client-side caches. + * + * @param int $uid + * (optional) A user ID to limit the cache flush to. + */ +function admin_menu_flush_caches($uid = NULL) { + // A call to menu_rebuild() will trigger potentially thousands of calls into + // menu_link_save(), for which admin_menu has to implement the corresponding + // CRUD hooks, in order to take up any menu link changes, since any menu link + // change could affect the admin menu (which essentially is an aggregate) and + // since there is no other way to get notified about stale caches. The cache + // only needs to be flushed once though, so we prevent a ton of needless + // subsequent calls with this static. + // @see http://drupal.org/node/918538 + $was_flushed = &drupal_static(__FUNCTION__, array()); + // $uid can be NULL. PHP automatically converts that into '' (empty string), + // which is different to uid 0 (zero). + if (isset($was_flushed[$uid])) { + return; + } + $was_flushed[$uid] = TRUE; + + $cid = 'admin_menu:'; + if (isset($uid)) { + $cid .= $uid . ':'; + } + // Flush cached output of admin_menu. + cache_clear_all($cid, 'cache_menu', TRUE); + // Flush client-side cache hashes. + drupal_static_reset('admin_menu_cache_get'); + // db_table_exists() required for SimpleTest. + if (db_table_exists('cache_admin_menu')) { + cache_clear_all(isset($uid) ? $cid : '*', 'cache_admin_menu', TRUE); + } +} + +/** + * Implements hook_form_alter(). + */ +function admin_menu_form_alter(&$form, &$form_state, $form_id) { + $global_flush_ids = array( + 'admin_menu_theme_settings' => 1, + // Update links for clean/non-clean URLs. + 'system_clean_url_settings' => 1, + // Incorporate changed user permissions. + 'user_admin_permissions' => 1, + // Removing a role potentially means less permissions. + 'user_admin_role_delete_confirm' => 1, + // User name and roles may be changed on the user account form. + 'user_profile_form' => 1, + ); + if (isset($global_flush_ids[$form_id])) { + $form['#submit'][] = 'admin_menu_form_alter_flush_cache_submit'; + + // Optionally limit the cache flush to a certain user ID. + $form_state['admin_menu_uid'] = NULL; + if ($form_id == 'user_profile_form') { + $form_state['admin_menu_uid'] = $form_state['user']->uid; + } + } + + // UX: Add a confirmation to the permissions form to ask the user whether to + // auto-enable the 'access administration menu' permission along with + // 'access administration pages'. + if ($form_id == 'user_admin_permissions') { + $form['#attached']['js'][] = drupal_get_path('module', 'admin_menu') . '/admin_menu.admin.js'; + } +} + +/** + * Form submission handler to flush Administration menu caches. + */ +function admin_menu_form_alter_flush_cache_submit($form, &$form_state) { + admin_menu_flush_caches($form_state['admin_menu_uid']); +} + +/** + * Implements hook_form_FORM_ID_alter(). + * + * Extends Devel module with Administration menu developer settings. + */ +function admin_menu_form_devel_admin_settings_alter(&$form, &$form_state) { + form_load_include($form_state, 'inc', 'admin_menu'); + _admin_menu_form_devel_admin_settings_alter($form, $form_state); +} diff --git a/www/sites/all/modules/contrib/admin_menu/admin_menu.uid1.css b/www/sites/all/modules/contrib/admin_menu/admin_menu.uid1.css new file mode 100644 index 0000000..e375cfe --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/admin_menu.uid1.css @@ -0,0 +1,9 @@ + +/** + * @file + * Administration menu color override for uid1. + */ + +#admin-menu li.admin-menu-account > a { + background: #911 url(images/bkg-red.png) bottom left repeat-x; +} diff --git a/www/sites/all/modules/contrib/admin_menu/admin_menu_toolbar/admin_menu_toolbar.css b/www/sites/all/modules/contrib/admin_menu/admin_menu_toolbar/admin_menu_toolbar.css new file mode 100644 index 0000000..a3e9f3e --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/admin_menu_toolbar/admin_menu_toolbar.css @@ -0,0 +1,145 @@ + +/** + * @file + * Toolbar style for Administration menu. + * + * Important: We cannot re-use toolbar.png from Toolbar module, since we cannot + * reliably determine the path to it. + * + * @todo Separate shortcut functionality into own module/widget. + */ + +/* Adjust margin/height */ +html body.admin-menu { + margin-top: 29px !important; +} +html body.admin-menu-with-shortcuts { + margin-top: 65px !important; +} +/* Displace the core Toolbar, if concurrently output. */ +body div#toolbar.toolbar { + top: 30px; +} + +/** + * Base styles. + * + * We use a keyword for the toolbar font size to make it display consistently + * across different themes, while still allowing browsers to resize the text. + */ +#admin-menu { + font: normal small "Lucida Grande", Verdana, sans-serif; + -moz-box-shadow: 0 -10px 20px 13px #000; + -webkit-box-shadow: 0 -10px 20px 13px #000; + box-shadow: 0 -10px 20px 13px #000; + right: 0; + width: auto; +} +#admin-menu-wrapper { + font-size: .846em; + padding: 5px 10px 0; +} + +#admin-menu .dropdown a { + color: #fafafa; +} + +/* Remove border from all lists and actions */ +#admin-menu .dropdown .admin-menu-action a { + border-left: 0; +} +#admin-menu .dropdown .admin-menu-icon > a { + padding: 2px 10px 3px; +} + +/** + * Administration menu. + */ +#admin-menu .dropdown .admin-menu-icon > a span { + vertical-align: text-bottom; + width: 11px; + height: 14px; + display: block; + background: url(toolbar.png) no-repeat 0 -45px; + text-indent: -9999px; +} +#admin-menu > div > .dropdown > li > a { + border-right: 0; + margin-bottom: 4px; + padding: 2px 10px 3px; +} +#admin-menu .dropdown .admin-menu-toolbar-category > a, +#admin-menu .dropdown .admin-menu-action > a { + border-radius: 10px; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; +} +#admin-menu .dropdown .admin-menu-toolbar-category > a.active-trail { + text-shadow: #333 0 1px 0; + background: url(toolbar.png) 0 0 repeat-x; +} +#admin-menu .dropdown .admin-menu-toolbar-category > a:hover { + background-color: #444; +} +#admin-menu .dropdown .admin-menu-tab a { + border-right: 0; +} +#admin-menu .dropdown li li.expandable ul { + margin: -22px 0 0 160px; +} + +/** + * Shortcuts toggle. + */ +#admin-menu .shortcut-toggle { + cursor: pointer; + background: url(toolbar.png) 0 -20px no-repeat; + display: block; + float: right; + margin: 0 0 0 1.3em; + text-indent: -9999px; + overflow: hidden; + width: 25px; + height: 25px; +} +#admin-menu .shortcut-toggle:focus, +#admin-menu .shortcut-toggle:hover { + background-position: -50px -20px; +} +#admin-menu .shortcut-toggle.active { + background-position: -25px -20px; +} +#admin-menu .shortcut-toggle.active:focus, +#admin-menu .shortcut-toggle.active:hover { + background-position: -75px -20px; +} + +/** + * Shortcuts widget. + */ +#admin-menu .shortcut-toolbar { + background-color: #666; + clear: both; + display: none; + margin: 0 -10px; + overflow: hidden; + /* Align with icon; @see shortcut.css */ + padding-left: 5px; +} +#admin-menu .shortcut-toolbar.active { + display: block; +} +/* Override theme list style; @see shortcut.css */ +#admin-menu .shortcut-toolbar ul { + margin: 0; +} +/* @see toolbar.css */ +#admin-menu .shortcut-toolbar li { + float: left; + list-style-image: none; + list-style-type: none; +} +#admin-menu .shortcut-toolbar a { + display: block; +} + diff --git a/www/sites/all/modules/contrib/admin_menu/admin_menu_toolbar/admin_menu_toolbar.info b/www/sites/all/modules/contrib/admin_menu/admin_menu_toolbar/admin_menu_toolbar.info new file mode 100644 index 0000000..fa4ca09 --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/admin_menu_toolbar/admin_menu_toolbar.info @@ -0,0 +1,12 @@ +name = Administration menu Toolbar style +description = A better Toolbar. +package = Administration +core = 7.x +dependencies[] = admin_menu + +; Information added by Drupal.org packaging script on 2014-12-19 +version = "7.x-3.0-rc5" +core = "7.x" +project = "admin_menu" +datestamp = "1419029284" + diff --git a/www/sites/all/modules/contrib/admin_menu/admin_menu_toolbar/admin_menu_toolbar.install b/www/sites/all/modules/contrib/admin_menu/admin_menu_toolbar/admin_menu_toolbar.install new file mode 100644 index 0000000..bf067d7 --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/admin_menu_toolbar/admin_menu_toolbar.install @@ -0,0 +1,37 @@ +fields(array('weight' => 101)) + ->condition('type', 'module') + ->condition('name', 'admin_menu_toolbar') + ->execute(); +} + +/** + * Set module weight to a value higher than admin_menu. + * + * At this point, admin_menu should have a weight of 100. To account for + * customized weights, we increase the weight relatively. + * + * @see admin_menu_toolbar_install() + */ +function admin_menu_toolbar_update_6300() { + $weight = db_query("SELECT weight FROM {system} WHERE type = 'module' AND name = 'admin_menu'")->fetchField(); + $weight++; + db_update('system') + ->fields(array('weight' => $weight)) + ->condition('type', 'module') + ->condition('name', 'admin_menu_toolbar') + ->execute(); +} + diff --git a/www/sites/all/modules/contrib/admin_menu/admin_menu_toolbar/admin_menu_toolbar.js b/www/sites/all/modules/contrib/admin_menu/admin_menu_toolbar/admin_menu_toolbar.js new file mode 100644 index 0000000..809d9ea --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/admin_menu_toolbar/admin_menu_toolbar.js @@ -0,0 +1,56 @@ +(function($) { + +Drupal.admin = Drupal.admin || {}; +Drupal.admin.behaviors = Drupal.admin.behaviors || {}; + +/** + * @ingroup admin_behaviors + * @{ + */ + +/** + * Apply active trail highlighting based on current path. + * + * @todo Not limited to toolbar; move into core? + */ +Drupal.admin.behaviors.toolbarActiveTrail = function (context, settings, $adminMenu) { + if (settings.admin_menu.toolbar && settings.admin_menu.toolbar.activeTrail) { + $adminMenu.find('> div > ul > li > a[href="' + settings.admin_menu.toolbar.activeTrail + '"]').addClass('active-trail'); + } +}; + +/** + * Toggles the shortcuts bar. + */ +Drupal.admin.behaviors.shortcutToggle = function (context, settings, $adminMenu) { + var $shortcuts = $adminMenu.find('.shortcut-toolbar'); + if (!$shortcuts.length) { + return; + } + var storage = window.localStorage || false; + var storageKey = 'Drupal.admin_menu.shortcut'; + var $body = $(context).find('body'); + var $toggle = $adminMenu.find('.shortcut-toggle'); + $toggle.click(function () { + var enable = !$shortcuts.hasClass('active'); + $shortcuts.toggleClass('active', enable); + $toggle.toggleClass('active', enable); + if (settings.admin_menu.margin_top) { + $body.toggleClass('admin-menu-with-shortcuts', enable); + } + // Persist toggle state across requests. + storage && enable ? storage.setItem(storageKey, 1) : storage.removeItem(storageKey); + this.blur(); + return false; + }); + + if (!storage || storage.getItem(storageKey)) { + $toggle.trigger('click'); + } +}; + +/** + * @} End of "ingroup admin_behaviors". + */ + +})(jQuery); diff --git a/www/sites/all/modules/contrib/admin_menu/admin_menu_toolbar/admin_menu_toolbar.module b/www/sites/all/modules/contrib/admin_menu/admin_menu_toolbar/admin_menu_toolbar.module new file mode 100644 index 0000000..c6111bd --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/admin_menu_toolbar/admin_menu_toolbar.module @@ -0,0 +1,118 @@ + TRUE); + + $attached['css'][$path . '/admin_menu_toolbar.css'] = $options; + $attached['js'][$path . '/admin_menu_toolbar.js'] = $options; + + // @todo Stop-gap fix until cached rendering is resolved. + // @see http://drupal.org/node/1567622 + if (module_exists('shortcut')) { + $attached['css'][drupal_get_path('module', 'shortcut') . '/shortcut.css'] = $options; + } + + $settings = array(); + // Add current path to support menu item highlighting. + // @todo Compile real active trail here? + $args = explode('/', $_GET['q']); + if ($args[0] == 'admin' && !empty($args[1])) { + $settings['activeTrail'] = url($args[0] . '/' . $args[1]); + } + elseif (drupal_is_front_page()) { + $settings['activeTrail'] = url(''); + } + + $attached['js'][] = array( + 'data' => array('admin_menu' => array('toolbar' => $settings)), + 'type' => 'setting', + ); +} + +/** + * Implements hook_admin_menu_output_build(). + */ +function admin_menu_toolbar_admin_menu_output_build(&$content) { + if (empty($content['#components']['shortcut.links']) && !$content['#complete']) { + return; + } + // Add shortcuts toggle. + $content['shortcut-toggle'] = array( + '#access' => module_exists('shortcut'), + '#weight' => -200, + '#type' => 'link', + '#title' => t('Show shortcuts'), + '#href' => '', + '#options' => array( + 'attributes' => array('class' => array('shortcut-toggle')), + ), + ); + + // Add shortcuts bar. + $content['shortcut'] = array( + '#access' => module_exists('shortcut'), + '#weight' => 200, + '#prefix' => '
', + '#suffix' => '
', + ); + $content['shortcut']['shortcuts'] = array( + // Shortcut module's CSS relies on Toolbar module's markup. + // @see http://drupal.org/node/1217038 + '#prefix' => '
', + '#suffix' => '
', + // @todo Links may contain .active-trail classes. + '#pre_render' => array('shortcut_toolbar_pre_render'), + ); +} + +/** + * Implements hook_admin_menu_output_alter(). + */ +function admin_menu_toolbar_admin_menu_output_alter(&$content) { + // Add a class to top-level items for styling. + if (isset($content['menu'])) { + foreach (element_children($content['menu']) as $link) { + $content['menu'][$link]['#attributes']['class'][] = 'admin-menu-toolbar-category'; + } + } + + // Alter icon. + if (isset($content['icon'])) { + unset($content['icon']['icon']['#theme']); + $content['icon']['icon']['#title'] = '' . t('Home') . ''; + $content['icon']['icon']['#attributes']['class'][] = 'admin-menu-toolbar-category'; + } + + // Alter user account link. + if (isset($content['account'])) { + $content['account']['account']['#title'] = t('Hello @username', array('@username' => $content['account']['account']['#title'])); + $content['account']['account']['#options']['html'] = TRUE; + } +} + diff --git a/www/sites/all/modules/contrib/admin_menu/admin_menu_toolbar/toolbar.png b/www/sites/all/modules/contrib/admin_menu/admin_menu_toolbar/toolbar.png new file mode 100644 index 0000000..f2c7f35 Binary files /dev/null and b/www/sites/all/modules/contrib/admin_menu/admin_menu_toolbar/toolbar.png differ diff --git a/www/sites/all/modules/contrib/admin_menu/images/arrow-rtl.png b/www/sites/all/modules/contrib/admin_menu/images/arrow-rtl.png new file mode 100644 index 0000000..dccaad7 Binary files /dev/null and b/www/sites/all/modules/contrib/admin_menu/images/arrow-rtl.png differ diff --git a/www/sites/all/modules/contrib/admin_menu/images/arrow.png b/www/sites/all/modules/contrib/admin_menu/images/arrow.png new file mode 100644 index 0000000..3c3166f Binary files /dev/null and b/www/sites/all/modules/contrib/admin_menu/images/arrow.png differ diff --git a/www/sites/all/modules/contrib/admin_menu/images/bkg-red.png b/www/sites/all/modules/contrib/admin_menu/images/bkg-red.png new file mode 100644 index 0000000..80647b0 Binary files /dev/null and b/www/sites/all/modules/contrib/admin_menu/images/bkg-red.png differ diff --git a/www/sites/all/modules/contrib/admin_menu/images/bkg.png b/www/sites/all/modules/contrib/admin_menu/images/bkg.png new file mode 100644 index 0000000..9de137b Binary files /dev/null and b/www/sites/all/modules/contrib/admin_menu/images/bkg.png differ diff --git a/www/sites/all/modules/contrib/admin_menu/images/bkg_tab.png b/www/sites/all/modules/contrib/admin_menu/images/bkg_tab.png new file mode 100644 index 0000000..6ee3de0 Binary files /dev/null and b/www/sites/all/modules/contrib/admin_menu/images/bkg_tab.png differ diff --git a/www/sites/all/modules/contrib/admin_menu/images/icon_users.png b/www/sites/all/modules/contrib/admin_menu/images/icon_users.png new file mode 100644 index 0000000..0923fda Binary files /dev/null and b/www/sites/all/modules/contrib/admin_menu/images/icon_users.png differ diff --git a/www/sites/all/modules/contrib/admin_menu/tests/admin_menu.test b/www/sites/all/modules/contrib/admin_menu/tests/admin_menu.test new file mode 100644 index 0000000..4b48c9a --- /dev/null +++ b/www/sites/all/modules/contrib/admin_menu/tests/admin_menu.test @@ -0,0 +1,520 @@ + 'access administration pages', + 'admin_menu' => 'access administration menu', + ); + + function setUp() { + // Enable admin menu module and any other modules. + $modules = func_get_args(); + $modules = isset($modules[0]) ? $modules[0] : $modules; + $modules[] = 'admin_menu'; + parent::setUp($modules); + + // Disable client-side caching. + variable_set('admin_menu_cache_client', FALSE); + // Disable Clean URLs to ensure drupal.org testbot compatibility. + variable_set('clean_url', 0); + } + + /** + * Check that an element exists in HTML markup. + * + * @param $xpath + * An XPath expression. + * @param array $arguments + * (optional) An associative array of XPath replacement tokens to pass to + * DrupalWebTestCase::buildXPathQuery(). + * @param $message + * The message to display along with the assertion. + * @param $group + * The type of assertion - examples are "Browser", "PHP". + * + * @return + * TRUE if the assertion succeeded, FALSE otherwise. + */ + protected function assertElementByXPath($xpath, array $arguments = array(), $message, $group = 'Other') { + $elements = $this->xpath($xpath, $arguments); + return $this->assertTrue(!empty($elements[0]), $message, $group); + } + + /** + * Check that an element does not exist in HTML markup. + * + * @param $xpath + * An XPath expression. + * @param array $arguments + * (optional) An associative array of XPath replacement tokens to pass to + * DrupalWebTestCase::buildXPathQuery(). + * @param $message + * The message to display along with the assertion. + * @param $group + * The type of assertion - examples are "Browser", "PHP". + * + * @return + * TRUE if the assertion succeeded, FALSE otherwise. + */ + protected function assertNoElementByXPath($xpath, array $arguments = array(), $message, $group = 'Other') { + $elements = $this->xpath($xpath, $arguments); + return $this->assertTrue(empty($elements), $message, $group); + } + + /** + * Asserts that links appear in the menu in a specified trail. + * + * @param array $trail + * A list of menu link titles to assert in the menu. + */ + protected function assertLinkTrailByTitle(array $trail) { + $xpath = array(); + $args = array(); + $message = ''; + foreach ($trail as $i => $title) { + $xpath[] = '/li/a[text()=:title' . $i . ']'; + $args[':title' . $i] = $title; + $message .= ($i ? ' » ' : '') . check_plain($title); + } + $xpath = '//div[@id="admin-menu"]/div/ul' . implode('/parent::li/ul', $xpath); + $this->assertElementByXPath($xpath, $args, $message . ' link found.'); + } + + /** + * Asserts that no link appears in the menu for a specified trail. + * + * @param array $trail + * A list of menu link titles to assert in the menu. + */ + protected function assertNoLinkTrailByTitle(array $trail) { + $xpath = array(); + $args = array(); + $message = ''; + foreach ($trail as $i => $title) { + $xpath[] = '/li/a[text()=:title' . $i . ']'; + $args[':title' . $i] = $title; + $message .= ($i ? ' » ' : '') . check_plain($title); + } + $xpath = '//div[@id="admin-menu"]/div/ul' . implode('/parent::li/ul', $xpath); + $this->assertNoElementByXPath($xpath, $args, $message . ' link not found.'); + } +} + +/** + * Tests menu links depending on user permissions. + */ +class AdminMenuPermissionsTestCase extends AdminMenuWebTestCase { + public static function getInfo() { + return array( + 'name' => 'Menu link access permissions', + 'description' => 'Tests appearance of menu links depending on user permissions.', + 'group' => 'Administration menu', + ); + } + + function setUp() { + parent::setUp(array('node')); + } + + /** + * Test that the links are added to the page (no JS testing). + */ + function testPermissions() { + module_enable(array('contact')); + $this->resetAll(); + + // Anonymous users should not see the menu. + $this->drupalGet(''); + $this->assertNoElementByXPath('//div[@id="admin-menu"]', array(), t('Administration menu not found.')); + + // Create a user who + // - can access content overview + // - cannot access drupal.org links + // - cannot administer Contact module + $permissions = $this->basePermissions + array( + 'access content overview', + ); + $admin_user = $this->drupalCreateUser($permissions); + $this->drupalLogin($admin_user); + + // Check that the user can see the admin links, but not the drupal links. + $this->assertElementByXPath('//div[@id="admin-menu"]', array(), 'Administration menu found.'); + $this->assertElementByXPath('//div[@id="admin-menu"]//a[contains(@href, :path)]', array(':path' => 'admin/content'), 'Content link found.'); + $this->assertNoElementByXPath('//div[@id="admin-menu"]//a[@href=:path]', array(':path' => 'http://drupal.org'), 'Icon » Drupal.org link not found.'); + $this->assertNoElementByXPath('//div[@id="admin-menu"]//a[contains(@href, :path)]', array(':path' => 'admin/structure/contact'), 'Structure » Contact link not found.'); + + // Create a user "reversed" to the above; i.e., who + // - cannot access content overview + // - can access drupal.org links + // - can administer Contact module + $permissions = $this->basePermissions + array( + 'display drupal links', + 'administer contact forms', + ); + $admin_user2 = $this->drupalCreateUser($permissions); + $this->drupalLogin($admin_user2); + $this->assertElementByXPath('//div[@id="admin-menu"]', array(), 'Administration menu found.'); + $this->assertNoElementByXPath('//div[@id="admin-menu"]//a[contains(@href, :path)]', array(':path' => 'admin/content'), 'Content link not found.'); + $this->assertElementByXPath('//div[@id="admin-menu"]//a[@href=:path]', array(':path' => 'http://drupal.org'), 'Icon » Drupal.org link found.'); + $this->assertElementByXPath('//div[@id="admin-menu"]//a[contains(@href, :path)]', array(':path' => 'admin/structure/contact'), 'Structure » Contact link found.'); + } + + /** + * Tests handling of links pointing to category/overview pages. + */ + function testCategories() { + // Create a user with minimum permissions. + $admin_user = $this->drupalCreateUser($this->basePermissions); + $this->drupalLogin($admin_user); + + // Verify that no category links appear. + $this->assertNoLinkTrailByTitle(array(t('Structure'))); + $this->assertNoLinkTrailByTitle(array(t('Configuration'))); + + // Create a user with access to one configuration category. + $permissions = $this->basePermissions + array( + 'administer users', + ); + $admin_user = $this->drupalCreateUser($permissions); + $this->drupalLogin($admin_user); + + // Verify that only expected category links appear. + $this->assertNoLinkTrailByTitle(array(t('Structure'))); + $this->assertLinkTrailByTitle(array(t('People'))); + $this->assertLinkTrailByTitle(array(t('Configuration'))); + $this->assertLinkTrailByTitle(array(t('Configuration'), t('People'))); + // Random picks are sufficient. + $this->assertNoLinkTrailByTitle(array(t('Configuration'), t('Media'))); + $this->assertNoLinkTrailByTitle(array(t('Configuration'), t('System'))); + } + + /** + * Tests that user role and permission changes are properly taken up. + */ + function testPermissionChanges() { + // Create a user who is able to change permissions. + $permissions = $this->basePermissions + array( + 'administer permissions', + ); + $admin_user = $this->drupalCreateUser($permissions); + $this->drupalLogin($admin_user); + + // Extract the user role ID that was created for above permissions. + $rid = key(array_diff_key($admin_user->roles, array(DRUPAL_AUTHENTICATED_RID => 0))); + + // Verify that Configuration does not appear. + $this->assertNoLinkTrailByTitle(array(t('Configuration'))); + // Grant the 'administer site configuration' permission to ourselves. + $edit = array( + $rid . '[administer site configuration]' => TRUE, + ); + $this->drupalPost('admin/people/permissions', $edit, t('Save permissions')); + // Verify that Configuration appears. + $this->assertLinkTrailByTitle(array(t('Configuration'))); + + // Verify that Structure » Content types does not appear. + $this->assertNoLinkTrailByTitle(array(t('Structure'), t('Content types'))); + // Create a new role. + $edit = array( + 'name' => 'test', + ); + $this->drupalPost('admin/people/permissions/roles', $edit, t('Add role')); + // It should be safe to assume that the new role gets the next ID. + $test_rid = $rid + 1; + // Grant the 'administer content types' permission for the role. + $edit = array( + $test_rid . '[administer content types]' => TRUE, + ); + $this->drupalPost('admin/people/permissions/' . $test_rid, $edit, t('Save permissions')); + // Verify that Structure » Content types does not appear. + $this->assertNoLinkTrailByTitle(array(t('Structure'), t('Content types'))); + + // Assign the role to ourselves. + $edit = array( + 'roles[' . $test_rid . ']' => TRUE, + ); + $this->drupalPost('user/' . $admin_user->uid . '/edit', $edit, t('Save')); + // Verify that Structure » Content types appears. + $this->assertLinkTrailByTitle(array(t('Structure'), t('Content types'))); + + // Delete the role. + $this->drupalPost('admin/people/permissions/roles/edit/' . $test_rid, array(), t('Delete role')); + $this->drupalPost(NULL, array(), t('Delete')); + // Verify that Structure » Content types does not appear. + $this->assertNoLinkTrailByTitle(array(t('Structure'), t('Content types'))); + } +} + +/** + * Tests appearance, localization, and escaping of dynamic links. + */ +class AdminMenuDynamicLinksTestCase extends AdminMenuWebTestCase { + public static function getInfo() { + return array( + 'name' => 'Dynamic links', + 'description' => 'Tests appearance, localization, and escaping of dynamic links.', + 'group' => 'Administration menu', + ); + } + + function setUp() { + parent::setUp(array('node')); + } + + /** + * Tests node type links. + */ + function testNode() { + $type = $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article')); + // Create a content-type with special characters. + $type = $this->drupalCreateContentType(array('type' => 'special', 'name' => 'Cool & Special')); + + $permissions = $this->basePermissions + array( + 'administer content types', + 'create article content', + 'create special content', + ); + $this->admin_user = $this->drupalCreateUser($permissions); + $this->drupalLogin($this->admin_user); + + // Verify that dynamic links are displayed. + $this->drupalGet(''); + $this->assertElementByXPath('//div[@id="admin-menu"]', array(), t('Administration menu found.')); + $this->assertElementByXPath('//div[@id="admin-menu"]//a[contains(@href, :path)]', array(':path' => 'admin/structure/types'), "Structure » Content types link found."); + + // Verify link title output escaping. + $this->assertNoRaw('Cool & Special'); + $this->assertRaw(check_plain('Cool & Special')); + + // Verify Manage content type links. + $links = array( + 'admin/structure/types/manage/article' => 'Article', + 'admin/structure/types/manage/special' => 'Cool & Special', + ); + foreach ($links as $path => $title) { + $this->assertElementByXPath('//div[@id="admin-menu"]//a[contains(@href, :path) and text()=:title]', array( + ':path' => $path, + ':title' => $title, + ), "Structure » Content types » $title link found."); + } + + // Verify Add content links. + $links = array( + 'node/add/article' => 'Article', + 'node/add/special' => 'Cool & Special', + ); + foreach ($links as $path => $title) { + $this->assertElementByXPath('//div[@id="admin-menu"]//a[contains(@href, :path) and text()=:title]', array( + ':path' => $path, + ':title' => $title, + ), "Add content » $title link found."); + } + } + + /** + * Tests Add content links. + */ + function testNodeAdd() { + $type = $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article')); + + // Verify that "Add content" does not appear for unprivileged users. + $permissions = $this->basePermissions + array( + 'access content', + ); + $this->web_user = $this->drupalCreateUser($permissions); + $this->drupalLogin($this->web_user); + $this->assertNoText(t('Add content')); + + // Verify "Add content" appears below "Content" for administrative users. + $permissions = $this->basePermissions + array( + 'access content overview', + 'access content', + 'create article content', + ); + $this->admin_user = $this->drupalCreateUser($permissions); + $this->drupalLogin($this->admin_user); + $this->assertLinkTrailByTitle(array( + t('Content'), + t('Add content'), + )); + + // Verify "Add content" appears on the top-level for regular users. + $permissions = $this->basePermissions + array( + 'access content', + 'create article content', + ); + $this->web_user = $this->drupalCreateUser($permissions); + $this->drupalLogin($this->web_user); + $this->assertLinkTrailByTitle(array( + t('Add content'), + )); + } +} + +/** + * Tests appearance of different types of links. + */ +class AdminMenuLinkTypesTestCase extends AdminMenuWebTestCase { + public static function getInfo() { + return array( + 'name' => 'Link types', + 'description' => 'Tests appearance of different types of links.', + 'group' => 'Administration menu', + ); + } + + function setUp() { + parent::setUp(array('help')); + + $permissions = module_invoke_all('permission'); + $permissions = array_keys($permissions); + $this->admin_user = $this->drupalCreateUser($permissions); + $this->drupalLogin($this->admin_user); + } + + /** + * Tests appearance of different router item link types. + */ + function testLinkTypes() { + // Verify that MENU_NORMAL_ITEMs appear. + $this->assertLinkTrailByTitle(array( + t('Configuration'), + t('System'), + t('Site information'), + )); + + // Verify that MENU_LOCAL_TASKs appear. + $this->assertLinkTrailByTitle(array(t('People'), t('Permissions'))); + $this->assertLinkTrailByTitle(array(t('Appearance'), t('Settings'))); + $this->assertLinkTrailByTitle(array(t('Modules'), t('Uninstall'))); + + // Verify that MENU_LOCAL_ACTIONs appear. + $this->assertLinkTrailByTitle(array( + t('People'), + t('Add user'), + )); + + // Verify that MENU_DEFAULT_LOCAL_TASKs do NOT appear. + $this->assertNoLinkTrailByTitle(array(t('Modules'), t('List'))); + $this->assertNoLinkTrailByTitle(array(t('People'), t('List'))); + $this->assertNoLinkTrailByTitle(array(t('People'), t('Permissions'), t('Permissions'))); + $this->assertNoLinkTrailByTitle(array(t('Appearance'), t('List'))); + + // Verify that MENU_VISIBLE_IN_BREADCRUMB items (exact type) do NOT appear. + $this->assertNoLinkTrailByTitle(array(t('Modules'), t('Uninstall'), t('Uninstall'))); + $this->assertNoLinkTrailByTitle(array(t('Help'), 'admin_menu')); + + // Verify that special "Index" link appears below icon. + $this->assertElementByXPath('//div[@id="admin-menu"]//a[contains(@href, :path) and text()=:title]', array( + ':path' => 'admin/index', + ':title' => t('Index'), + ), "Icon » Index link found."); + } +} + +/** + * Tests customized menu links. + */ +class AdminMenuCustomizedTestCase extends AdminMenuWebTestCase { + public static function getInfo() { + return array( + 'name' => 'Customized links', + 'description' => 'Tests customized menu links.', + 'group' => 'Administration menu', + ); + } + + function setUp() { + parent::setUp(array('menu')); + + $this->admin_user = $this->drupalCreateUser($this->basePermissions + array( + 'administer menu', + )); + $this->drupalLogin($this->admin_user); + } + + /** + * Test disabled custom links. + */ + function testCustomDisabled() { + $type = $this->drupalCreateContentType(); + $node = $this->drupalCreateNode(array('type' => $type->type)); + $text = $this->randomName(); + $xpath = $this->buildXPathQuery('//div[@id=:id]//a[contains(text(), :text)]', array( + ':id' => 'admin-menu', + ':text' => $text, + )); + + // Verify that the link does not appear in the menu. + $this->drupalGet('node'); + $elements = $this->xpath($xpath); + $this->assertFalse($elements, 'Custom link not found.'); + + // Add a custom link to the node to the menu. + $edit = array( + 'link_path' => 'node/' . $node->nid, + 'link_title' => $text, + 'parent' => 'management:' . $this->queryMlidByPath('admin'), + ); + $this->drupalPost('admin/structure/menu/manage/management/add', $edit, t('Save')); + + // Verify that the link appears in the menu. + $this->drupalGet('node'); + $elements = $this->xpath($xpath); + $this->assertTrue($elements, 'Custom link found.'); + + // Disable the link. + $edit = array( + 'enabled' => FALSE, + ); + $this->drupalPost('admin/structure/menu/item/' . $this->queryMlidByPath('node/' . $node->nid) . '/edit', $edit, t('Save')); + + // Verify that the disabled link does not appear in the menu. + $this->drupalGet('node'); + $elements = $this->xpath($xpath); + $this->assertFalse($elements, 'Disabled custom link not found.'); + } + + /** + * Tests external links. + */ + function testCustomExternal() { + // Add a custom link to the node to the menu. + $edit = array( + 'link_path' => 'http://example.com', + 'link_title' => 'Example', + 'parent' => 'management:' . $this->queryMlidByPath('admin'), + ); + $this->drupalPost('admin/structure/menu/manage/management/add', $edit, t('Save')); + + // Verify that the link appears in the menu. + $this->drupalGet(''); + $elements = $this->xpath('//div[@id=:id]//a[@href=:href and contains(text(), :text)]', array( + ':id' => 'admin-menu', + ':href' => $edit['link_path'], + ':text' => $edit['link_title'], + )); + $this->assertTrue($elements, 'External link found.'); + } + + /** + * Returns the menu link ID for a given link path in the management menu. + */ + protected function queryMlidByPath($path) { + return db_query('SELECT mlid FROM {menu_links} WHERE menu_name = :menu AND link_path = :path', array( + ':menu' => 'management', + ':path' => $path, + ))->fetchField(); + } +} +