# HG changeset patch
# User danieleb
# Date 1379672676 -3600
# Node ID 49b8ebaaad78d669fbd099199337fa2357b2c665
# Parent ce11bbd8f642386847a51b3ca86e37b9987250c8# Parent e063188e9b6ba91c8602791a65755d0ccd2f8228
Added all the needed modules
diff -r ce11bbd8f642 -r 49b8ebaaad78 .DS_Store
Binary file .DS_Store has changed
diff -r ce11bbd8f642 -r 49b8ebaaad78 .gitignore
--- a/.gitignore Thu Sep 19 10:38:44 2013 +0100
+++ b/.gitignore Fri Sep 20 11:24:36 2013 +0100
@@ -4,3 +4,7 @@
# Ignore paths that contain user-generated content.
sites/*/files
sites/*/private
+
+# Ignore system files
+.DS_Store
+.*~
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/CHANGELOG.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/admin_menu/CHANGELOG.txt Fri Sep 20 11:24:36 2013 +0100
@@ -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 -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/LICENSE.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/admin_menu/LICENSE.txt Fri Sep 20 11:24:36 2013 +0100
@@ -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 -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/README.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/admin_menu/README.txt Fri Sep 20 11:24:36 2013 +0100
@@ -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/70151 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 -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/admin_devel/admin_devel.info
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/admin_menu/admin_devel/admin_devel.info Fri Sep 20 11:24:36 2013 +0100
@@ -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 2013-01-31
+version = "7.x-3.0-rc4"
+core = "7.x"
+project = "admin_menu"
+datestamp = "1359651687"
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/admin_devel/admin_devel.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/admin_menu/admin_devel/admin_devel.js Fri Sep 20 11:24:36 2013 +0100
@@ -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 -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/admin_devel/admin_devel.module
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/admin_menu/admin_devel/admin_devel.module Fri Sep 20 11:24:36 2013 +0100
@@ -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 -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/admin_menu-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/admin_menu/admin_menu-rtl.css Fri Sep 20 11:24:36 2013 +0100
@@ -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 -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/admin_menu.admin.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/admin_menu/admin_menu.admin.js Fri Sep 20 11:24:36 2013 +0100
@@ -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 -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/admin_menu.api.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/admin_menu/admin_menu.api.php Fri Sep 20 11:24:36 2013 +0100
@@ -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 -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/admin_menu.color.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/admin_menu/admin_menu.color.css Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,46 @@
+
+/**
+ * @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,
+#admin-menu li li.iehover {
+ 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 -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/admin_menu.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/admin_menu/admin_menu.css Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,250 @@
+
+/**
+ * @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);
+ 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,
+#admin-menu .dropdown li.iehover ul ul,
+#admin-menu .dropdown li.iehover ul ul ul,
+#admin-menu .dropdown li.iehover ul ul ul ul,
+#admin-menu .dropdown li.iehover 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,
+#admin-menu .dropdown li.iehover ul,
+#admin-menu .dropdown li li.iehover ul,
+#admin-menu .dropdown li li li.iehover ul,
+#admin-menu .dropdown li li li li.iehover ul,
+#admin-menu .dropdown li li li li li.iehover 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,
+#admin-menu .dropdown li li.iehover {
+ 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,
+#admin-menu .dropdown li li.iehover li a,
+#admin-menu .dropdown li li.iehover li.iehover li a {
+ color: #EEE;
+}
+#admin-menu .dropdown li li.iehover a,
+#admin-menu .dropdown li li.iehover li.iehover a,
+#admin-menu .dropdown li li.iehover li.iehover li.iehover a {
+ color: #FFF;
+ width: 90%; /* IE */
+}
+
+/* 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 -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/admin_menu.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/admin_menu/admin_menu.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,1033 @@
+ $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 link to toggle developer modules (performance).
+ $saved_state = variable_get('admin_menu_devel_modules_enabled', NULL);
+ $links['icon']['toggle-modules'] = array(
+ '#title' => isset($saved_state) ? t('Enable developer modules') : t('Disable developer modules'),
+ '#weight' => 88,
+ '#access' => user_access('administer modules'),
+ '#href' => 'admin_menu/toggle-modules',
+ '#options' => array(
+ 'query' => $destination + array('token' => drupal_get_token('admin_menu/toggle-modules')),
+ ),
+ );
+
+ // 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),
+ );
+ // Fetch all available modules manually, since module_list() only returns
+ // currently enabled modules, which makes this setting pointless if developer
+ // modules are currently disabled.
+ $all_modules = array();
+ $result = db_query("SELECT name, filename, info FROM {system} WHERE type = 'module' ORDER BY name ASC");
+ foreach ($result as $module) {
+ if (file_exists($module->filename)) {
+ $info = unserialize($module->info);
+ $all_modules[$module->name] = $info['name'];
+ }
+ }
+ $devel_modules = variable_get('admin_menu_devel_modules', _admin_menu_developer_modules());
+ $devel_modules = array_intersect_key($all_modules, array_flip($devel_modules));
+ $form['performance']['admin_menu_devel_modules_skip'] = array(
+ '#type' => 'checkboxes',
+ '#title' => t('Developer modules to keep enabled'),
+ '#default_value' => variable_get('admin_menu_devel_modules_skip', array()),
+ '#options' => $devel_modules,
+ '#access' => !empty($devel_modules),
+ '#description' => t('The selected modules will not be disabled when the link %disable-developer-modules below the icon in the menu is invoked.', array(
+ '%disable-developer-modules' => t('Disable developer modules'),
+ )),
+ );
+
+ 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.'),
+ );
+}
+
+/**
+ * Menu callback; Enable/disable developer modules.
+ *
+ * This can save up to 150ms on each uncached page request.
+ */
+function admin_menu_toggle_modules() {
+ if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], current_path())) {
+ return MENU_ACCESS_DENIED;
+ }
+
+ $rebuild = FALSE;
+ $saved_state = variable_get('admin_menu_devel_modules_enabled', NULL);
+ if (isset($saved_state)) {
+ // Re-enable modules that were enabled before.
+ module_enable($saved_state);
+ variable_del('admin_menu_devel_modules_enabled');
+ drupal_set_message(t('Enabled these modules: !module-list.', array('!module-list' => implode(', ', $saved_state))));
+ $rebuild = TRUE;
+ }
+ else {
+ // Allow site admins to override this variable via settings.php.
+ $devel_modules = variable_get('admin_menu_devel_modules', _admin_menu_developer_modules());
+ // Store currently enabled modules in a variable.
+ $devel_modules = array_intersect(module_list(FALSE, FALSE), $devel_modules);
+ $devel_modules = array_diff($devel_modules, variable_get('admin_menu_devel_modules_skip', array()));
+ if (!empty($devel_modules)) {
+ variable_set('admin_menu_devel_modules_enabled', $devel_modules);
+ // Disable developer modules.
+ module_disable($devel_modules);
+ drupal_set_message(t('Disabled these modules: !module-list.', array('!module-list' => implode(', ', $devel_modules))));
+ $rebuild = TRUE;
+ }
+ else {
+ drupal_set_message(t('No developer modules are enabled.'));
+ }
+ }
+ if ($rebuild) {
+ // Make sure everything is rebuilt, basically a combination of the calls
+ // from system_modules() and system_modules_submit().
+ drupal_theme_rebuild();
+ menu_rebuild();
+ cache_clear_all('schema', 'cache');
+ cache_clear_all();
+ drupal_clear_css_cache();
+ drupal_clear_js_cache();
+ // Synchronize to catch any actions that were added or removed.
+ actions_synchronize();
+ // Finally, flush admin_menu's cache.
+ admin_menu_flush_caches();
+ }
+ drupal_goto();
+}
+
+/**
+ * Helper function to return a default list of developer modules.
+ */
+function _admin_menu_developer_modules() {
+ return array(
+ 'admin_devel',
+ 'cache_disable',
+ 'coder',
+ 'content_copy',
+ 'context_ui',
+ 'debug',
+ 'delete_all',
+ 'demo',
+ 'devel',
+ 'devel_node_access',
+ 'devel_themer',
+ 'field_ui',
+ 'fontyourface_ui',
+ 'form_controller',
+ 'imagecache_ui',
+ 'journal',
+ 'l10n_client',
+ 'l10n_update',
+ 'macro',
+ 'rules_admin',
+ 'stringoverrides',
+ 'trace',
+ 'upgrade_status',
+ 'user_display_ui',
+ 'util',
+ 'views_ui',
+ 'views_theme_wizard',
+ );
+}
+
+/**
+ * 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 '';
+}
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/admin_menu.info
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/admin_menu/admin_menu.info Fri Sep 20 11:24:36 2013 +0100
@@ -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 2013-01-31
+version = "7.x-3.0-rc4"
+core = "7.x"
+project = "admin_menu"
+datestamp = "1359651687"
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/admin_menu.install
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/admin_menu/admin_menu.install Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,122 @@
+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_devel_modules');
+ variable_del('admin_menu_devel_modules_enabled');
+ variable_del('admin_menu_devel_modules_skip');
+ 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');
+}
+
+/**
+ * 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 -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/admin_menu.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/admin_menu/admin_menu.js Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,397 @@
+(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) {
+ // Hover emulation for IE 6.
+ if ($.browser.msie && parseInt(jQuery.browser.version) == 6) {
+ $('li', $adminMenu).hover(
+ function () {
+ $(this).addClass('iehover');
+ },
+ function () {
+ $(this).removeClass('iehover');
+ }
+ );
+ }
+
+ // 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 = $('
');
+ $.each(matches, function () {
+ var result = this.text;
+ var $element = $(this.element);
+
+ // Check whether there is a top-level category that can be prepended.
+ var $category = $element.closest('#admin-menu-wrapper > ul > li');
+ var categoryText = $category.find('> a').text()
+ if ($category.length && categoryText) {
+ result = categoryText + ': ' + result;
+ }
+
+ var $result = $('
' . t('The administration menu module provides a dropdown menu arranged for one- or two-click access to most administrative tasks and other common destinations (to users with the proper permissions). Administration menu also displays the number of anonymous and authenticated users, and allows modules to add their own custom menu items. Integration with the menu varies from module to module; the contributed module Devel, for instance, makes strong use of the administration menu module to provide quick access to development tools.', array('@drupal' => 'http://drupal.org/project/devel')) . '
';
+ $output .= '
' . t('The administration menu settings page allows you to modify some elements of the menu\'s behavior and appearance. Since the appearance of the menu is dependent on your site theme, substantial customizations require modifications to your site\'s theme and CSS files. See the advanced module README.txt file for more information on theme and CSS customizations.', array('@settings' => url('admin/config/administration/admin_menu'))) . '
';
+ $output .= '
' . t('The menu items displayed in the administration menu depend upon the actual permissions of the viewer. First, the administration menu is only displayed to users in roles with the Access administration menu (admin_menu module) permission. Second, a user must be a member of a role with the Access administration pages (system module) permission to view administrative links. And, third, only currently permitted links are displayed; for example, if a user is not a member of a role with the permissions Administer permissions (user module) and Administer users (user module), the User management menu item is not displayed.') . '
';
+ return $output;
+ }
+}
+
+/**
+ * Implements hook_permission().
+ */
+function admin_menu_permission() {
+ return array(
+ 'access administration menu' => array(
+ 'title' => t('Access administration menu'),
+ 'description' => t('Display the administration menu at the top of each page.'),
+ ),
+ 'flush caches' => array(
+ 'title' => t('Flush caches'),
+ 'description' => t('Access links to flush caches in the administration menu.'),
+ ),
+ 'display drupal links' => array(
+ 'title' => t('Display Drupal links'),
+ 'description' => t('Provide Drupal.org links in the administration menu.'),
+ ),
+ );
+}
+
+/**
+ * Implements hook_theme().
+ */
+function admin_menu_theme() {
+ return array(
+ 'admin_menu_links' => array(
+ 'render element' => 'elements',
+ ),
+ 'admin_menu_icon' => array(
+ 'variables' => array('src' => NULL, 'alt' => NULL),
+ 'file' => 'admin_menu.inc',
+ ),
+ );
+}
+
+/**
+ * Implements hook_menu().
+ */
+function admin_menu_menu() {
+ // AJAX callback.
+ // @see http://drupal.org/project/js
+ $items['js/admin_menu/cache'] = array(
+ 'page callback' => 'admin_menu_js_cache',
+ 'delivery callback' => 'admin_menu_deliver',
+ 'access arguments' => array('access administration menu'),
+ 'type' => MENU_CALLBACK,
+ );
+ // Module settings.
+ $items['admin/config/administration'] = array(
+ 'title' => 'Administration',
+ 'description' => 'Administration tools.',
+ 'page callback' => 'system_admin_menu_block_page',
+ 'access arguments' => array('access administration pages'),
+ 'file' => 'system.admin.inc',
+ 'file path' => drupal_get_path('module', 'system'),
+ );
+ $items['admin/config/administration/admin_menu'] = array(
+ 'title' => 'Administration menu',
+ 'description' => 'Adjust administration menu settings.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('admin_menu_theme_settings'),
+ 'access arguments' => array('administer site configuration'),
+ 'file' => 'admin_menu.inc',
+ );
+ // Menu link callbacks.
+ $items['admin_menu/toggle-modules'] = array(
+ 'page callback' => 'admin_menu_toggle_modules',
+ 'access arguments' => array('administer modules'),
+ 'type' => MENU_CALLBACK,
+ 'file' => 'admin_menu.inc',
+ );
+ $items['admin_menu/flush-cache'] = array(
+ 'page callback' => 'admin_menu_flush_cache',
+ 'access arguments' => array('flush caches'),
+ 'type' => MENU_CALLBACK,
+ 'file' => 'admin_menu.inc',
+ );
+ return $items;
+}
+
+/**
+ * Implements hook_menu_alter().
+ */
+function admin_menu_menu_alter(&$items) {
+ // Flush client-side caches whenever the menu is rebuilt.
+ admin_menu_flush_caches();
+}
+
+/**
+ * Implements hook_menu_link_insert().
+ */
+function admin_menu_menu_link_insert($link) {
+ // Flush all of our caches to pick up the link.
+ admin_menu_flush_caches();
+}
+
+/**
+ * Implements hook_menu_link_update().
+ */
+function admin_menu_menu_link_update($link) {
+ // Flush all of our caches to pick up the link.
+ admin_menu_flush_caches();
+}
+
+/**
+ * Implements hook_menu_link_delete().
+ */
+function admin_menu_menu_link_delete($link) {
+ // Flush all of our caches to pick up the link.
+ admin_menu_flush_caches();
+}
+
+/**
+ * Implements hook_system_info_alter().
+ *
+ * Indicate that the 'page_bottom' region (in which the administration menu
+ * is displayed) is an overlay supplemental region that should be refreshed
+ * whenever its content is updated.
+ *
+ * @see toolbar_system_info_alter()
+ */
+function admin_menu_system_info_alter(&$info, $file, $type) {
+ if ($type == 'theme') {
+ $info['overlay_supplemental_regions'][] = 'page_bottom';
+ }
+}
+
+/**
+ * Implements hook_page_build().
+ */
+function admin_menu_page_build(&$page) {
+ if (!user_access('access administration menu') || admin_menu_suppress(FALSE)) {
+ return;
+ }
+ // Performance: Skip this entirely for AJAX requests.
+ if (strpos($_GET['q'], 'js/') === 0) {
+ return;
+ }
+ global $user, $language;
+ $path = drupal_get_path('module', 'admin_menu');
+
+ $page['page_bottom']['admin_menu'] = array(
+ '#attached' => array(),
+ );
+ $attached = &$page['page_bottom']['admin_menu']['#attached'];
+ $options = array('every_page' => TRUE);
+
+ $attached['css'][$path . '/admin_menu.css'] = $options;
+ if ($user->uid == 1) {
+ $attached['css'][$path . '/admin_menu.uid1.css'] = $options;
+ }
+ // Previous versions used the 'defer' attribute to increase browser rendering
+ // performance. At least starting with Firefox 3.6, deferred .js files are
+ // loaded, but Drupal.behaviors are not contained in the DOM when drupal.js
+ // executes Drupal.attachBehaviors().
+ $attached['js'][$path . '/admin_menu.js'] = $options;
+
+ // Destination query strings are applied via JS.
+ $settings['destination'] = drupal_http_build_query(drupal_get_destination());
+
+ // Determine whether we need to show all components and disable all caches.
+ $complete = FALSE;
+ if (current_path() == 'admin/config/administration/admin_menu' && $_SERVER['REQUEST_METHOD'] == 'GET') {
+ $complete = TRUE;
+ }
+
+ // If the client supports JavaScript and we have a cached menu for the current
+ // user, only output the hash for the client-side HTTP cache callback URL.
+ $cid = 'admin_menu:' . $user->uid . ':' . session_id() . ':' . $language->language;
+ if (!$complete && !empty($_COOKIE['has_js']) && ($hash = admin_menu_cache_get($cid))) {
+ $settings['hash'] = $hash;
+ // The base path to use for cache requests depends on whether clean URLs
+ // are enabled, whether Drupal runs in a sub-directory, and on the language
+ // system configuration. url() already provides us the proper path and also
+ // invokes potentially existing custom_url_rewrite() functions, which may
+ // add further required components to the URL to provide context. Due to
+ // those components, and since url('') returns only base_path() when clean
+ // URLs are disabled, we need to use a replacement token as path. Yuck.
+ $settings['basePath'] = url('admin_menu');
+ }
+ // Otherwise, add the full menu to the page.
+ else {
+ $page['page_bottom']['admin_menu']['#markup'] = admin_menu_output($complete);
+ }
+
+ $replacements = module_invoke_all('admin_menu_replacements', $complete);
+ if (!empty($replacements)) {
+ $settings['replacements'] = $replacements;
+ }
+
+ if ($setting = variable_get('admin_menu_margin_top', 1)) {
+ $settings['margin_top'] = $setting;
+ // @todo Drupal.behaviors.adminMenuMarginTop is obsolete, but
+ // hook_page_build() does not allow to set a CSS class on the body yet.
+ // @see http://drupal.org/node/1473548, http://drupal.org/node/1194528
+ //$page['#attributes']['class'][] = 'admin-menu';
+ }
+ if ($setting = variable_get('admin_menu_position_fixed', 1)) {
+ $settings['position_fixed'] = $setting;
+
+ // In fixed positioning, supply a callback function for tableheader.js to
+ // allow it to determine the top viewport offset.
+ // @see admin_menu.js, toolbar.js
+ $attached['js'][] = array(
+ 'data' => array('tableHeaderOffset' => 'Drupal.admin.height'),
+ 'type' => 'setting',
+ );
+ }
+ if ($setting = variable_get('admin_menu_tweak_tabs', 0)) {
+ $settings['tweak_tabs'] = $setting;
+ }
+ if ($_GET['q'] == 'admin/modules' || strpos($_GET['q'], 'admin/modules/list') === 0) {
+ $settings['tweak_modules'] = variable_get('admin_menu_tweak_modules', 0);
+ }
+ if ($_GET['q'] == 'admin/people/permissions' || $_GET['q'] == 'admin/people/permissions/list') {
+ $settings['tweak_permissions'] = variable_get('admin_menu_tweak_permissions', 0);
+ }
+
+ $attached['js'][] = array(
+ 'data' => array('admin_menu' => $settings),
+ 'type' => 'setting',
+ );
+}
+
+/**
+ * Suppress display of administration menu.
+ *
+ * This function should be called from within another module's page callback
+ * (preferably using module_invoke()) when the menu should not be displayed.
+ * This is useful for modules that implement popup pages or other special
+ * pages where the menu would be distracting or break the layout.
+ *
+ * @param $set
+ * Defaults to TRUE. If called before hook_footer(), the menu will not be
+ * displayed. If FALSE is passed, the suppression state is returned.
+ */
+function admin_menu_suppress($set = TRUE) {
+ static $suppress = FALSE;
+ // drupal_add_js() must only be invoked once.
+ if (!empty($set) && $suppress === FALSE) {
+ $suppress = TRUE;
+ drupal_add_js(array('admin_menu' => array('suppress' => 1)), 'setting');
+ }
+ return $suppress;
+}
+
+/**
+ * Implements hook_js().
+ */
+function admin_menu_js() {
+ return array(
+ 'cache' => array(
+ 'callback' => 'admin_menu_js_cache',
+ 'includes' => array('common', 'theme', 'unicode'),
+ 'dependencies' => array('devel', 'filter', 'user'),
+ ),
+ );
+}
+
+/**
+ * Retrieve a client-side cache hash from cache.
+ *
+ * The hash cache is consulted more than once per request; we therefore cache
+ * the results statically to avoid multiple database requests.
+ *
+ * This should only be used for client-side cache hashes. Use cache_menu for
+ * administration menu content.
+ *
+ * @param $cid
+ * The cache ID of the data to retrieve.
+ */
+function admin_menu_cache_get($cid) {
+ $cache = &drupal_static(__FUNCTION__, array());
+
+ if (!variable_get('admin_menu_cache_client', TRUE)) {
+ return FALSE;
+ }
+ if (!array_key_exists($cid, $cache)) {
+ $cache[$cid] = cache_get($cid, 'cache_admin_menu');
+ if ($cache[$cid] && isset($cache[$cid]->data)) {
+ $cache[$cid] = $cache[$cid]->data;
+ }
+ }
+
+ return $cache[$cid];
+}
+
+/**
+ * Store a client-side cache hash in persistent cache.
+ *
+ * This should only be used for client-side cache hashes. Use cache_menu for
+ * administration menu content.
+ *
+ * @param $cid
+ * The cache ID of the data to retrieve.
+ */
+function admin_menu_cache_set($cid, $data) {
+ if (variable_get('admin_menu_cache_client', TRUE)) {
+ cache_set($cid, $data, 'cache_admin_menu');
+ }
+}
+
+/**
+ * Menu callback; Output administration menu for HTTP caching via AJAX request.
+ *
+ * @see admin_menu_deliver()
+ */
+function admin_menu_js_cache() {
+ global $conf;
+
+ // Suppress Devel module.
+ $GLOBALS['devel_shutdown'] = FALSE;
+
+ // Enforce page caching.
+ $conf['cache'] = 1;
+ drupal_page_is_cacheable(TRUE);
+
+ // If we have a cache, serve it.
+ // @see _drupal_bootstrap_page_cache()
+ $cache = drupal_page_get_cache();
+ if (is_object($cache)) {
+ header('X-Drupal-Cache: HIT');
+ // Restore the metadata cached with the page.
+ $_GET['q'] = $cache->data['path'];
+ date_default_timezone_set(drupal_get_user_timezone());
+
+ drupal_serve_page_from_cache($cache);
+
+ // We are done.
+ exit;
+ }
+
+ // Otherwise, create a new page response (that will be cached).
+ header('X-Drupal-Cache: MISS');
+
+ // The Expires HTTP header is the heart of the client-side HTTP caching. The
+ // additional server-side page cache only takes effect when the client
+ // accesses the callback URL again (e.g., after clearing the browser cache or
+ // when force-reloading a Drupal page).
+ $max_age = 3600 * 24 * 365;
+ drupal_add_http_header('Expires', gmdate(DATE_RFC1123, REQUEST_TIME + $max_age));
+ drupal_add_http_header('Cache-Control', 'private, max-age=' . $max_age);
+
+ // Retrieve and return the rendered menu.
+ return admin_menu_output();
+}
+
+/**
+ * Delivery callback for client-side HTTP caching.
+ *
+ * @see admin_menu_js_cache()
+ */
+function admin_menu_deliver($page_callback_result) {
+ drupal_add_http_header('Content-Type', 'text/html; charset=utf-8');
+
+ // Send appropriate language header for browsers.
+ global $language;
+ drupal_add_http_header('Content-Language', $language->language);
+
+ // The page callback is always admin_menu_js_cache(), which always returns a
+ // string, and is only accessed when the user actually has access to it.
+ // Therefore, we do not care for the other possible page callback results.
+ print $page_callback_result;
+
+ // Perform end-of-request tasks. The page cache is created here.
+ drupal_page_footer();
+}
+
+/**
+ * Implements hook_admin_menu_replacements().
+ */
+function admin_menu_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;
+}
+
+/**
+ * Return count of online anonymous/authenticated users.
+ *
+ * @see user_block(), user.module
+ */
+function admin_menu_get_user_count() {
+ $interval = REQUEST_TIME - variable_get('user_block_seconds_online', 900);
+ $count_anon = admin_menu_session_count($interval, TRUE);
+ $count_auth = admin_menu_session_count($interval, FALSE);
+
+ return t('@count-anon / @count-auth', array('@count-anon' => $count_anon, '@count-auth' => $count_auth));
+}
+
+/**
+ * Counts how many users are active on the site.
+ *
+ * Counts how many users have sessions which have been active since the
+ * specified time. Can count either anonymous sessions or authenticated
+ * sessions.
+ *
+ * @param $timestamp
+ * A Unix timestamp. Users who have been active since this time will be
+ * counted. The default is 0, which counts all existing sessions.
+ * @param $anonymous
+ * TRUE counts only anonymous users. FALSE counts only authenticated users.
+ *
+ * @return
+ * The number of users with sessions.
+ *
+ * @todo There are mostly no anonymous sessions anymore. Split this into a
+ * separate module providing proper user statistics.
+ */
+function admin_menu_session_count($timestamp = 0, $anonymous = TRUE) {
+ $query = db_select('sessions');
+ $query->addExpression('COUNT(sid)', 'count');
+ $query->condition('timestamp', $timestamp, '>=');
+ $query->condition('uid', 0, $anonymous ? '=' : '>');
+ return $query->execute()->fetchField();
+}
+
+/**
+ * Build the administration menu output.
+ *
+ * @param bool $complete
+ * (optional) Whether to build to the complete menu including all components
+ * and ignore the cache. Defaults to FALSE. Internally used for the settings
+ * page.
+ */
+function admin_menu_output($complete = FALSE) {
+ global $user, $language;
+
+ $cache_server_enabled = !$complete && variable_get('admin_menu_cache_server', TRUE);
+ $cid = 'admin_menu:' . $user->uid . ':' . session_id() . ':' . $language->language;
+
+ // Try to load and output administration menu from server-side cache.
+ // @todo Duplicates the page cache? Page cache ID contains the hash that is
+ // generated at the bottom of this function, which is based on $content,
+ // but logically identical to the $cid. Investigate whether not only the
+ // cache_menu but also the cache_admin_menu could be dropped; the
+ // client-side HTTP cache hash check could be based on a cid lookup in
+ // cache_page instead? (i.e., one cache to rule them all) However,
+ // cache_page is cleared very often.
+ if ($cache_server_enabled) {
+ $cache = cache_get($cid, 'cache_menu');
+ if ($cache && isset($cache->data)) {
+ $content = $cache->data;
+ }
+ }
+
+ // Rebuild the output.
+ if (!isset($content)) {
+ // Retrieve enabled components to display and make them available for others.
+ $components = variable_get('admin_menu_components', array());
+ $components += array(
+ 'admin_menu.menu' => TRUE,
+ 'admin_menu.icon' => TRUE,
+ 'admin_menu.account' => TRUE,
+ );
+ $content['#components'] = $components;
+ $content['#complete'] = $complete;
+
+ // Add site name as CSS class for development/staging theming purposes. We
+ // leverage the cookie domain instead of HTTP_HOST to account for many (but
+ // not all) multi-domain setups (e.g. language-based sub-domains).
+ $classes = 'admin-menu-site' . drupal_strtolower(preg_replace('/[^a-zA-Z0-9-]/', '-', $GLOBALS['cookie_domain']));
+ // Displace overlay.
+ // @see Drupal.overlay.create
+ // @see toolbar_preprocess_toolbar()
+ if (module_exists('overlay')) {
+ $classes .= ' overlay-displace-top';
+ }
+ // @todo Always output container to harden JS-less support.
+ $content['#prefix'] = '
';
+ $content['#suffix'] = '
';
+
+ // Load menu builder functions.
+ module_load_include('inc', 'admin_menu');
+
+ // @todo Move the below callbacks into hook_admin_menu_build()
+ // implementations (and $module.admin_menu.inc).
+
+ // Add administration menu.
+ if (!empty($components['admin_menu.menu']) || $complete) {
+ $content['menu'] = admin_menu_links_menu(admin_menu_tree('management'));
+ $content['menu']['#theme'] = 'admin_menu_links';
+ $content['menu']['#wrapper_attributes']['id'] = 'admin-menu-menu';
+ // Ensure the menu tree is rendered between the icon and user links.
+ $content['menu']['#weight'] = 0;
+ }
+
+ // Add menu additions.
+ if (!empty($components['admin_menu.icon']) || $complete) {
+ $content['icon'] = admin_menu_links_icon();
+ }
+ if (!empty($components['admin_menu.account']) || $complete) {
+ $content['account'] = admin_menu_links_account();
+ }
+ if (!empty($components['admin_menu.users']) || $complete) {
+ $content['users'] = admin_menu_links_users();
+ }
+ if (!empty($components['admin_menu.search']) || $complete) {
+ $content['search'] = admin_menu_links_search();
+ }
+
+ // Allow modules to enhance the menu.
+ // Uses '_output' suffix for consistency with the alter hook (see below).
+ foreach (module_implements('admin_menu_output_build') as $module) {
+ $function = $module . '_admin_menu_output_build';
+ $function($content);
+ }
+
+ // Allow modules to alter the output.
+ // The '_output' suffix is required to prevent hook implementation function
+ // name clashes with the contributed Admin module.
+ drupal_alter('admin_menu_output', $content);
+
+ $content = drupal_render($content);
+
+ // Cache the menu for this user.
+ if ($cache_server_enabled) {
+ cache_set($cid, $content, 'cache_menu');
+ }
+ }
+
+ // Store the new hash for this user.
+ if (!empty($_COOKIE['has_js']) && !$complete) {
+ admin_menu_cache_set($cid, md5($content));
+ }
+
+ return $content;
+}
+
+/**
+ * Implements hook_admin_menu_output_build().
+ */
+function admin_menu_admin_menu_output_build(&$content) {
+ if (!isset($content['menu'])) {
+ return;
+ }
+
+ // Unassign weights for categories below Configuration.
+ // An alphabetical order is more natural for a dropdown menu.
+ if (isset($content['menu']['admin/config'])) {
+ foreach (element_children($content['menu']['admin/config']) as $key) {
+ $content['menu']['admin/config'][$key]['#weight_original'] = $content['menu']['admin/config'][$key]['#weight'];
+ unset($content['menu']['admin/config'][$key]['#weight']);
+ }
+ }
+
+ // Retrieve the "Add content" link tree.
+ $link = db_query("SELECT * FROM {menu_links} WHERE router_path = 'node/add' AND module = 'system'")->fetchAssoc();
+ $conditions = array();
+ for ($i = 1; $i < MENU_MAX_DEPTH; $i++) {
+ if (!empty($link["p$i"])) {
+ $conditions["p$i"] = $link["p$i"];
+ }
+ }
+ $tree = menu_build_tree($link['menu_name'], array(
+ 'conditions' => $conditions,
+ 'min_depth' => $link['depth'],
+ ));
+ $links = admin_menu_links_menu($tree);
+ if (!empty($links)) {
+ // If the user has access to the top-level "Content" category, insert the
+ // "Add content" link tree there.
+ if (isset($content['menu']['admin/content'])) {
+ $content['menu']['admin/content'] += $links;
+ }
+ // Otherwise make insert "Add content" as top-level category.
+ else {
+ $key = key($links);
+ $links[$key]['#weight'] = -100;
+ $content['menu'] += $links;
+ }
+ }
+}
+
+/**
+ * Implements hook_admin_menu_output_alter().
+ */
+function admin_menu_admin_menu_output_alter(&$content) {
+ foreach ($content['menu'] as $key => $link) {
+ // Move local tasks on 'admin' into icon menu.
+ if ($key == 'admin/tasks' || $key == 'admin/index') {
+ $content['icon']['icon'][$key] = $link;
+ unset($content['menu'][$key]);
+ }
+ }
+}
+
+/**
+ * Render a themed list of links.
+ *
+ * @param $variables
+ * - elements: A renderable array of links using the following keys:
+ * - #attributes: Optional array of attributes for the list item, processed
+ * via drupal_attributes().
+ * - #title: Title of the link, passed to l().
+ * - #href: Optional path of the link, passed to l(). When omitted, the
+ * element's '#title' is rendered without link.
+ * - #description: Optional alternative text for the link, passed to l().
+ * - #options: Optional alternative text for the link, passed to l().
+ * The array key of each child element itself is passed as path for l().
+ */
+function theme_admin_menu_links($variables) {
+ $destination = &drupal_static('admin_menu_destination');
+ $elements = $variables['elements'];
+
+ if (!isset($destination)) {
+ $destination = drupal_get_destination();
+ $destination = $destination['destination'];
+ }
+
+ // The majority of items in the menu are sorted already, but since modules
+ // may add or change arbitrary items anywhere, there is no way around sorting
+ // everything again. element_sort() is not sufficient here, as it
+ // intentionally retains the order of elements having the same #weight,
+ // whereas menu links are supposed to be ordered by #weight and #title.
+ uasort($elements, 'admin_menu_element_sort');
+ $elements['#sorted'] = TRUE;
+
+ $output = '';
+ foreach (element_children($elements) as $path) {
+ // Early-return nothing if user does not have access.
+ if (isset($elements[$path]['#access']) && !$elements[$path]['#access']) {
+ continue;
+ }
+ $elements[$path] += array(
+ '#attributes' => array(),
+ '#options' => array(),
+ );
+ // Render children to determine whether this link is expandable.
+ if (isset($elements[$path]['#type']) || isset($elements[$path]['#theme']) || isset($elements[$path]['#pre_render'])) {
+ $elements[$path]['#children'] = drupal_render($elements[$path]);
+ }
+ else {
+ $elements[$path]['#children'] = theme('admin_menu_links', array('elements' => $elements[$path]));
+ if (!empty($elements[$path]['#children'])) {
+ $elements[$path]['#attributes']['class'][] = 'expandable';
+ }
+ if (isset($elements[$path]['#attributes']['class'])) {
+ $elements[$path]['#attributes']['class'] = $elements[$path]['#attributes']['class'];
+ }
+ }
+
+ $link = '';
+ // Handle menu links.
+ if (isset($elements[$path]['#href'])) {
+ // Strip destination query string from href attribute and apply a CSS class
+ // for our JavaScript behavior instead.
+ if (isset($elements[$path]['#options']['query']['destination']) && $elements[$path]['#options']['query']['destination'] == $destination) {
+ unset($elements[$path]['#options']['query']['destination']);
+ $elements[$path]['#options']['attributes']['class'][] = 'admin-menu-destination';
+ }
+
+ $link = l($elements[$path]['#title'], $elements[$path]['#href'], $elements[$path]['#options']);
+ }
+ // Handle plain text items, but do not interfere with menu additions.
+ elseif (!isset($elements[$path]['#type']) && isset($elements[$path]['#title'])) {
+ if (!empty($elements[$path]['#options']['html'])) {
+ $title = $elements[$path]['#title'];
+ }
+ else {
+ $title = check_plain($elements[$path]['#title']);
+ }
+ $attributes = '';
+ if (isset($elements[$path]['#options']['attributes'])) {
+ $attributes = drupal_attributes($elements[$path]['#options']['attributes']);
+ }
+ $link = '' . $title . '';
+ }
+
+ $output .= '
',
+ // @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 -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/admin_menu_toolbar/toolbar.png
Binary file modules/admin_menu/admin_menu_toolbar/toolbar.png has changed
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/images/arrow-rtl.png
Binary file modules/admin_menu/images/arrow-rtl.png has changed
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/images/arrow.png
Binary file modules/admin_menu/images/arrow.png has changed
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/images/bkg-red.png
Binary file modules/admin_menu/images/bkg-red.png has changed
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/images/bkg.png
Binary file modules/admin_menu/images/bkg.png has changed
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/images/bkg_tab.png
Binary file modules/admin_menu/images/bkg_tab.png has changed
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/images/icon_users.png
Binary file modules/admin_menu/images/icon_users.png has changed
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/admin_menu/tests/admin_menu.test
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/admin_menu/tests/admin_menu.test Fri Sep 20 11:24:36 2013 +0100
@@ -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();
+ }
+}
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/LICENSE.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/LICENSE.txt Fri Sep 20 11:24:36 2013 +0100
@@ -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 -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/README.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/README.txt Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,143 @@
+
+ biblio.module
+
+Author: Ron Jerome
+Released under the GPL
+
+
+Description:
+============
+This module extends the node data type with additional fields to manage lists
+of scholarly publications.
+
+It closely follows the EndNote model, thus both importing from and exporting
+to Endote are supported. Other formats such as bibtex and RIS are also supported.
+
+Bibliographic information is displayed in lists with links to detailed
+information on each publication.
+
+The lists can be sorted, filtered and ordered in many different ways.
+
+
+
+
+Requirements:
+=============
+Drupal 7.x, Upgrades supported from any Biblio version after 6.x-1.9
+
+Installation:
+=============
+Create a directory called biblio in the sites/all/modules directory, then place all of the
+files packaged with this module in that directory.
+
+This module will auto-install the required database tables the first time you
+enable it on the admin/modules page. This will also setup a number of pre-defined
+publication types. These types can be changed or deleted on the
+admin/config/content/biblio/types page.
+
+Robots.txt
+==========
+In order to limit recursive searches by web bots, it is recommended that you add the following
+to your robots.txt file. Note: if you change the base url for biblio you will have to make the
+corresponding change here. i.e. if you base url for biblio is "publications" then replace "biblio"
+with "publications" in the directives below.
+
+# Biblio
+Disallow: /biblio/export/
+Disallow: /biblio?*
+Disallow: /biblio?page=*&*
+Allow: /biblio?page=*
+
+
+Settings:
+=========
+A number of settings are available at admin/config/content/biblio. They control how
+the author names are displayed, whether export links are added to pages and the
+number of entries per page to display.
+
+The 'admin/config/content/biblio/fields' page allows the the site administrator to set
+the default field titles and set which fields are common to all publication
+types. When a new publication type is added, it will contain all the common
+fields and any that are specifically activated (custom is checked). This also
+allows the admin to over ride any of the default settings for any given type.
+
+Access Control:
+===============
+Three permissions are controlable on the admin/access page. I think they are fairly
+self evident, they control who can create biblio entries, edit entries and who can
+import from file.
+
+Adding/importing records:
+=========================
+Bibliographic entries can be added to the database in one of two ways, individualy
+from the node/add/biblio link, or by importing records from one of the supported file
+formats. Administrators can go to 'admin/config/content/biblio/import' and fill in
+the form to upload and import publication data from files.
+
+
+Features:
+=========
+By default, the /biblio page will list all of the entries in the database sorted
+by Year in descending order. If you wish to sort by "Title" or "Type", you may
+do so by clicking on the appropriate links at the top of the page. To reverse
+the sort order, simply click the link a second time.
+
+
+Filtering Search Results:
+=========================
+If you wish to filter the results, click on the "Filter" tab at the top of the
+page. To add a filter, click the radio button to the left of the filter type
+you wish to apply, then select the filter criteria from the drop down list
+on the right, then click the filter button.
+
+It is possible to create complex filters by returning to the "Filter" tab and
+adding additional filters. Simply follow the steps outlined above and press
+the "Refine" button.
+
+All filters can be removed by clicking the Clear All Filters link at the top
+of the result page, or on the "Filter" tab they can be removed one at a time
+using the "Undo" button, or you can remove them all using the "Clear All" button
+
+You may also construct URLs which filter. For example, /biblio/year/2005 will
+show all of the entries for 2005. /biblio/year/2005/author/smith will show all
+of entries from 2005 for smith.
+
+
+Exporting Search Results:
+=========================
+Assuming this option has been enabled by the administrator, you can export
+search results directly into EndNote. The link at the top of the result page
+will export all of the search results, and the links on individual entries will
+export the information related to that single entry.
+
+Clicking on one of the export links should cause your browser to ask you
+whether you want to Open, or Save To Disk, the file endnote.enw. If you choose
+to open it, Endnote should start and ask you which library you would like
+store the results in. Alternatively, you can save the file to disk and manually
+import it into EndNote.
+
+
+The information is exported in either EndNote "Tagged" format similar to this...
+
+ %0 Book
+ %A John Smith
+ %D 1959
+ %T The Works of John Smith
+ ...
+
+Or Endnote 7 XML format which is similar to this...
+
+
+
+
+ 10
+ 1959
+ The Works of John Smith
+
+ John Smith
+
+
+
+
+
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/biblio.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/biblio.css Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,338 @@
+#biblio-filter ul {
+ padding: 1px;
+ margin: 1px;
+ width: 100%;
+}
+
+#biblio-buttons {
+ float: left;
+ margin-left: 0.5em;
+ margin-top: 1em;
+ /* clear: right; */
+}
+
+.biblio-alpha-line {
+ text-align: center;
+}
+
+dl.bibliomultiselect dd.b,dl.bibliomultiselect dd.b .form-item,dl.bibliomultiselect dd.b select
+ {
+ font-family: inherit;
+ font-size: inherit;
+ width: 14em;
+}
+
+dl.bibliomultiselect dd.a,dl.bibliomultiselect dd.a .form-item {
+ width: 8em;
+}
+
+dl.bibliomultiselect dt,dl.bibliomultiselect dd {
+ float: left;
+ line-height: 1.75em;
+ padding: 0;
+ margin: 0 1em 0 0;
+}
+
+dl.bibliomultiselect .form-item {
+ height: 1.75em;
+ margin: 0;
+}
+#biblio-authors table, #biblio-tertiary-authors table {
+ width: 100%;
+}
+#biblio-authors .form-text {
+ width: 95%;
+}
+#biblio-authors td.biblio-contributor,
+#biblio-secondary-authors td.biblio-contributor,
+#biblio-tertiary-authors td.biblio-contributor,
+#biblio-subsidiary-authors td.biblio-contributor,
+#biblio-corp-authors td.biblio-contributor{
+ width: 98%;
+}
+#biblio-authors #biblio-tertiary-authors .draggable a.tabledrag-handle {
+ padding: 0;
+}
+
+.biblio-head {
+ width: 97%;
+ color: Black;
+ font-weight: normal;
+ background-color: #EAEAEA;
+ border: medium solid;
+ border-left-color: #F0F8FF;
+ border-right-color: Gray;
+ border-bottom-color: Gray;
+ border-top-color: #F0F8FF;
+ padding: 3px;
+}
+
+.biblio-head a:link,.biblio-head a.active,.biblio-head a:visited,.biblio-head a:focus,.biblio-head a:hover
+ {
+ color: black;
+}
+
+.biblio-current-filters {
+ background-color: #ffe1e1;
+}
+
+.biblio-separator-bar {
+ color: #000000;
+ font-weight: bold;
+ background-color: #e1e1e1;
+ border: 1px solid #ccc;
+ padding: 0.5em;
+ margin: 1em 0 1em 0;
+}
+
+.biblio-toolbar {
+ width: 97%;
+ color: Red;
+ font-weight: bold;
+ background-color: Silver;
+ border: medium solid;
+ border-left-color: #F0F8FF;
+ border-right-color: Gray;
+ border-bottom-color: Gray;
+ border-top-color: #F0F8FF;
+ padding: 3px;
+}
+
+.biblio-entry {
+ margin: 1em 0 1em 0;
+}
+
+.biblio-style-mla {
+ text-indent: -25px;
+ padding-left: 25px;
+}
+
+.biblio-publisher {
+ font-style: oblique;
+ font-weight: bold;
+}
+
+.biblio-title {
+ font-weight: bold;
+ text-decoration: none;
+ font-style: normal;
+ line-height: normal;
+ text-align: left;
+ font-family: "@Arial Unicode MS", Arial, sans-serif;
+ color: #336599;
+}
+
+a:active {
+
+}
+
+.biblio-authors a {
+ font-weight: normal;
+ text-decoration: none;
+ font-style: normal;
+}
+
+.biblio_type-1 {
+ background-color: #F2F2D9;
+}
+
+.biblio_type-2 {
+ background-color: #D9E6F2;
+}
+
+.biblio_type-3 {
+ background-color: #E5F2D9;
+}
+
+.biblio_type-4 {
+ background-color: #D9F2E6;
+}
+
+.biblio_type-5 {
+ background-color: #F2E6D9;
+}
+
+.biblio_type-6 {
+ background-color: #D9E6F2;
+}
+
+.biblio_type-7 {
+ background-color: #D9E6F2;
+}
+
+.biblio_type-8 {
+ background-color: #D9E6F2;
+}
+
+.biblio_type-9 {
+ background-color: #D9E6F2;
+}
+
+.biblio-export {
+ text-align: right;
+ text-decoration: none;
+ float: right;
+}
+
+.biblio-abstract-link {
+ text-align: left;
+ text-decoration: none;
+ font-style: normal;
+ font-weight: normal;
+ font-size: 75%;
+}
+
+.biblio-export-links {
+ float: right;
+ text-align: left;
+ text-decoration: none;
+ font-style: normal;
+ font-weight: normal;
+ font-size: 75%;
+ line-height: 100%;
+}
+
+ul.biblio-export-buttons,ul.biblio-export-buttons li {
+ background: transparent;
+ list-style-image: none;
+ list-style-type: none;
+ display: inline;
+ border-bottom: 0px;
+ border-right: 1px;
+ padding: 0;
+ margin: 0.1em;
+}
+
+.biblio-annotation {
+ text-align: left;
+ text-decoration: none;
+ margin-left: 2.5em;
+ margin-top: 0.5em;
+ margin-right: 2.5em;
+}
+
+.biblio-sort {
+ text-decoration: none;
+ text-align: left;
+}
+
+.biblio-openurl-text {
+ text-align: right;
+ text-decoration: none;
+ float: right;
+}
+
+.biblio-left-td {
+ text-align: right;
+ vertical-align: top;
+ width: 20%;
+}
+
+#biblio-header {
+ display: block;
+}
+/*
+#biblio-header ul.tabs {
+ border-bottom: 1px solid #BBBBBB;
+ padding: 0 0 1.765em 1em;
+}
+
+#biblio-header ul li {
+ padding: 0 0 0 0;
+ float: left;
+ display: block;
+}
+
+#biblio-header ul.tabs li a .a {
+ float: left;
+ height: 20px;
+ padding: 2px 0em 3px 0em;
+ margin: 0px;
+ padding: 0px;
+ background-image: url(main-tab1.png);
+ background-repeat: no-repeat;
+ background-position: 100% 0px;
+}
+
+#biblio-header ul.tabs li a .a .b {
+ display: block;
+ margin: 0px;
+ height: 20px;
+ padding: 0px 1em 3px;
+ background-image: url(main-tab2.png);
+ background-repeat: no-repeat;
+ background-position: 0% 0px;
+}
+
+#biblio-header ul.tabs li.active a {
+ background-color: transparent;
+ border-width: 0px;
+}
+
+#biblio-header ul.tabs li.active a .a {
+ background-position: 100% -60px;
+}
+
+#biblio-header ul.tabs li.active a .a .b {
+ background-position: 0% -60px;
+}
+
+#biblio-header ul.tabs li a:hover {
+ border-width: 0px;
+ text-decoration: none !important;
+}
+
+#biblio-header ul.tabs li a:hover .a {
+ background-position: 100% -30px;
+}
+
+#biblio-header ul.tabs li a:hover .a .b {
+ background-position: 0% -30px;
+}
+
+#biblio-header ul.tabs li.active a:hover {
+ background-color: #fff;
+ border-width: 0px;
+}
+
+#biblio-header ul.tabs li.active a:hover .a {
+ background-position: 100% -60px;
+}
+
+#biblio-header ul.tabs li.active a:hover .a .b {
+ background-position: 0% -60px;
+}
+*/
+.exposed-filters .filters {
+ float: left; /* LTR */
+ margin-right: 1em; /* LTR */
+ width: 25em; /* IE6 */
+}
+.exposed-filters .form-item {
+ margin: 0 0 0.1em 0;
+ padding: 0;
+}
+.exposed-filters .form-item label {
+ float: left; /* LTR */
+ font-weight: normal;
+ width: 10em;
+}
+.exposed-filters .form-select {
+ width: 14em;
+}
+/* Current filters */
+.exposed-filters .current-filters {
+ margin-bottom: 1em;
+}
+.exposed-filters .current-filters .placeholder {
+ font-style: normal;
+ font-weight: bold;
+}
+.exposed-filters .additional-filters {
+ float: left; /* LTR */
+ margin-right: 1em; /* LTR */
+}
+.biblio-highlight {
+ background-color: #FFF4F4;
+ border: 2px solid #494949;
+}
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/biblio.info
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/biblio.info Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,39 @@
+name = Biblio
+description = Maintains bibliographic lists.
+core = 7.x
+dependencies[] = taxonomy
+package = Biblio
+
+configure = admin/config/content/biblio
+files[] = tests/biblio.test
+files[] = tests/keyword.test
+files[] = tests/contributor.test
+files[] = tests/import.export.test
+
+files[] = includes/Name.php
+files[] = includes/Parser.php
+
+files[] = views/biblio_handler_citation.inc
+files[] = views/biblio_handler_field_keyword.inc
+files[] = views/biblio_handler_field_biblio_keyword_data_word.inc
+files[] = views/biblio_handler_field_biblio_keyword_kid.inc
+files[] = views/biblio_handler_field_biblio_type.inc
+files[] = views/biblio_handler_field_contributor.inc
+files[] = views/biblio_handler_field.inc
+files[] = views/biblio_handler_field_markup.inc
+files[] = views/biblio_handler_filter_biblio_contributor_auth_type.inc
+files[] = views/biblio_handler_filter_biblio_keyword_kid.inc
+files[] = views/biblio_handler_filter_biblio_keyword_word.inc
+files[] = views/biblio_handler_filter_biblio_type.inc
+files[] = views/biblio_handler_filter_contributor_lastname.inc
+files[] = views/biblio_handler_filter_contributor_uid.inc
+files[] = views/biblio_handler_filter_contributor.inc
+files[] = views/biblio_handler_sort_contributor_lastname.inc
+files[] = views/biblio_handler_argument_many_to_one.inc
+files[] = views/biblio_handler_field_export_link.inc
+; Information added by drupal.org packaging script on 2013-07-20
+version = "7.x-1.0-rc7"
+core = "7.x"
+project = "biblio"
+datestamp = "1374290470"
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/biblio.install
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/biblio.install Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,2218 @@
+ 'biblio',
+ 'name' => $t('Biblio'),
+ 'base' => 'biblio',
+ 'description' => $t('Use Biblio for scholarly content, such as journal papers and books.'),
+ 'body_label' => $t('Full text')
+ );
+
+ // Complete the node type definition by setting any defaults not explicitly
+ // declared above.
+ // http://api.drupal.org/api/function/node_type_set_defaults/7
+ $content_type = node_type_set_defaults($biblio);
+ node_add_body_field($content_type);
+
+ // Save the content type
+ node_type_save($content_type);
+
+ drupal_set_time_limit(300);
+
+ $result[] = _add_db_field_data();
+
+ $result[] = _add_publication_types();
+
+ $result[] = _add_custom_field_data();
+
+ //_enable_biblio_keyword_vocabulary();
+
+ $result[] = _set_system_weight();
+
+
+
+// if (count($result) == count(array_filter($result))) {
+// drupal_set_message(t('The biblio module has successfully added its tables to the database.'));
+// }
+// else {
+// drupal_set_message(t('Drupal encountered some errors while attempting to install the database tables for the biblio module.'), 'error');
+// }
+}
+
+function biblio_enable() {
+//TODO taxonomy
+ //if (module_exists('taxonomy')) _enable_biblio_vocabularies();
+ _set_system_weight();
+ //_enable_biblio_collection_vocabulary();
+ // _add_biblio_keywords();
+}
+
+function _enable_biblio_vocabularies() {
+ $vids = variable_get('biblio_vocabularies', array());
+ foreach ($vids as $vid ) {
+ if (($voc = taxonomy_vocabulary_load($vid))) {
+ $voc = (array) $voc;
+ $voc['nodes']['biblio'] = 1;
+ taxonomy_save_vocabulary($voc);
+ }
+ }
+}
+
+function biblio_disable() {
+ $vids = array();
+//TODO taxonomy
+/*
+ if (module_exists('taxonomy')) {
+ $voc = taxonomy_get_vocabularies();
+ foreach ($voc as $vid => $vocabulary) {
+ if (isset($vocabulary->nodes['biblio'])) {
+ $vids[] = $vid;
+ }
+ }
+ variable_set('biblio_vocabularies', $vids);
+ }
+*/
+}
+
+function biblio_uninstall() {
+ $batch = array(
+ 'title' => t('Remove all Biblio nodes'),
+ 'operations' => array(
+ array('biblio_batch_uninstall', array()),
+ ),
+ 'progress_message' => t('Deleteing Biblio nodes...'),
+ 'finished' => 'biblio_batch_uninstall_finished',
+ 'file' => drupal_get_path('module', 'biblio') . '/biblio.install'
+ );
+
+ batch_set($batch);
+}
+function biblio_batch_uninstall(&$context) {
+
+ $limit = 5;
+ if (empty($context['sandbox'])) {
+ $context['sandbox']['progress'] = 0;
+ $context['sandbox']['current_node'] = 0;
+ $context['sandbox']['max'] = db_query("SELECT COUNT(DISTINCT nid) FROM {node} WHERE type='biblio'")->fetchField();
+ $context['sandbox']['itters'] = $context['sandbox']['max'] / $limit;
+ $context['sandbox']['eta'] = 0;
+ }
+ // Bail out if the cache is empty.
+ if ($context['sandbox']['max'] == 0) {
+ $context['finished'] = 1;
+ return;
+ }
+
+ timer_start('biblio_delete');
+
+ $result = db_select('node')
+ ->fields('node', array('nid'))
+ ->condition('nid', $context['sandbox']['current_node'], '>')
+ ->condition('type', 'biblio')
+ ->orderBy('nid')
+ ->range(0, $limit)
+ ->execute();
+
+ foreach ($result as $row) {
+ $node = node_delete($row->nid);
+ if (function_exists('search_wipe')) {
+ search_wipe($row->nid, 'node');
+ }
+ $context['sandbox']['progress']++;
+ $context['sandbox']['current_node'] = $row->nid;
+ }
+
+ $looptime = timer_stop('biblio_delete');
+ $context['sandbox']['eta'] += $looptime['time'];
+ $itters = $context['sandbox']['progress'] / $limit;
+ if ($itters) {
+ $average_time = $context['sandbox']['eta'] / $itters;
+ $eta = (($context['sandbox']['itters'] * $average_time) - ($average_time * $itters)) / 1000;
+ if ($eta >= 60) {
+ $min = (int) $eta / 60;
+ }
+ else {
+ $min = 0;
+ }
+ $sec = $eta % 60;
+ $eta = sprintf("%d:%02d", $min, $sec);
+ $progress = sprintf("%d / %d", $context['sandbox']['progress'], $context['sandbox']['max'] );
+ $context['message'] = t(' Biblio nodes deleted: %progress Time remaining: %eta min. ' , array('%progress' => $progress, '%eta' => $eta));
+ }
+ if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
+ $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
+ }
+}
+
+
+function biblio_batch_uninstall_finished($success, $results, $operations) {
+ if ($success) {
+//TODO taxonomy
+/*
+ if (module_exists('taxonomy')) {
+ $voc = taxonomy_get_vocabularies();
+ foreach ($voc as $vid => $vocabulary) {
+ if ($vocabulary->module == 'biblio') taxonomy_del_vocabulary($vid);
+ }
+ }
+*/
+ $vars = db_query("SELECT * FROM {variable} WHERE name LIKE 'biblio_%'");
+ foreach ($vars as $var) {
+ variable_del($var->name);
+ }
+ }
+}
+
+function biblio_requirements($phase) {
+ $requirements = array();
+ $message = '';
+ // Ensure translations don't break at install time
+ $t = get_t();
+
+ // Report Drupal version
+ if ($phase == 'runtime') {
+ $dir = drupal_get_path('module', 'biblio');
+ $files = file_scan_directory($dir, '/..*.inc$/', array('recurse' => FALSE));
+ if (count($files) > 1) {
+ $message = $t('There is a problem with your Biblio installation! There should not be any ".inc" files in the %biblio directory. You probably forgot to delete the old biblio files when you upgraded the module. You should remove the following files from that directory...', array('%biblio' => $dir));
+ $message .= "
";
+ foreach ($files as $file) {
+ $message .= "
" . $file->filename;
+ }
+ $message .= "
";
+ $requirements['biblio'] = array(
+ 'title' => $t('Biblio'),
+ 'value' => BIBLIO_VERSION,
+ 'severity' => empty($message) ? REQUIREMENT_OK : REQUIREMENT_WARNING,
+ 'description' => $message,
+ );
+ }
+
+ }
+ return $requirements;
+}
+
+function _biblio_helper_modules($mode) {
+
+ $modules = _biblio_get_helper_modules();
+ switch ($mode) {
+ case 'install':
+ module_enable($modules);
+ break;
+ case 'uninstall':
+ foreach ($modules as $module) {
+ drupal_uninstall_modules($module);
+ }
+ break;
+ }
+}
+
+function _biblio_get_helper_modules() {
+ return array(
+ 'biblio_bibtex',
+ 'biblio_crossref',
+ 'biblio_marc',
+ 'biblio_pm',
+ 'biblio_ris',
+ 'biblio_tagged',
+ 'biblio_xml',
+ 'biblio_citeproc',
+ 'biblio_rtf',
+ );
+
+}
+
+function _set_system_weight() {
+ db_update('system')
+ ->fields(array(
+ 'weight' => 9,
+ ))
+ ->condition('name', 'biblio')
+ ->execute();
+ return;
+}
+
+function _enable_biblio_keyword_vocabulary() {
+
+//TODO taxonomy
+/*
+ if ($vocabulary = taxonomy_vocabulary_load(variable_get('biblio_keyword_vocabulary', 0))) {
+ // Existing install. Add back forum node type, if the biblio
+ // vocabulary still exists. Keep all other node types intact there.
+ $vocabulary = (array) $vocabulary;
+ $vocabulary['nodes']['biblio'] = 1;
+ taxonomy_save_vocabulary($vocabulary);
+ }
+
+
+
+ return $vocabulary['vid'];
+*/
+}
+
+function _enable_biblio_collection_vocabulary() {
+//TODO taxonomy
+/*
+ if ($vocabulary = taxonomy_vocabulary_load(variable_get('biblio_collection_vocabulary', 0))) {
+ // Existing install. Add back forum node type, if the biblio
+ // vocabulary still exists. Keep all other node types intact there.
+ $vocabulary = (array) $vocabulary;
+ $vocabulary['nodes']['biblio'] = 1;
+ taxonomy_save_vocabulary($vocabulary);
+ }
+ else {
+ // Create the forum vocabulary if it does not exist. Assign the vocabulary
+ // a low weight so it will appear first in forum topic create and edit
+ // forms.
+ $vocabulary = array(
+ 'name' => 'Biblio Collections',
+ 'description' => 'You may organize your publications into collections by adding a collection names to this vocabulary',
+ 'help' => '',
+ 'nodes' => array('biblio' => 1),
+ 'hierarchy' => 0,
+ 'relations' => 1,
+ 'tags' => 0,
+ 'multiple' => 1,
+ 'required' => 0,
+ 'weight' => 0,
+ 'module' => 'biblio',
+ );
+ taxonomy_save_vocabulary($vocabulary);
+ variable_set('biblio_collection_vocabulary', $vocabulary['vid']);
+ $default_collection = array(
+ 'name' => t('Default'),
+ 'description' => t("This is the collection that all biblio entries will be a part of if no other collection is selected. Deleting this term will render all your biblio entries inaccessable. (You've been warned!)" ),
+ 'parent' => array(),
+ 'relations' => array(),
+ 'synonyms' => '',
+ 'weight' => 0,
+ 'vid' => variable_get('biblio_collection_vocabulary', 0),
+ );
+ taxonomy_save_term($default_collection);
+ }
+ return $vocabulary['vid'];
+*/
+}
+
+/**
+ * Copies keywords from the biblio_keyword column of the biblio table
+ * to a taxonomy vocabulary
+ *
+ * @return none
+ */
+function _add_biblio_keywords() {
+//TODO taxonomy
+/*
+ set_time_limit(300);
+ $kw_sep = variable_get('biblio_keyword_sep', ',');
+ $vid = ($vid = variable_get('biblio_keyword_vocabulary', 0))? $vid:_enable_biblio_keyword_vocabulary();
+ if ($vid ) {
+ $db_result = db_query("SELECT b.biblio_keywords, b.nid, b.vid FROM {biblio} b");
+ $result = array();
+ foreach ($db_result as $row) {
+ foreach (explode($kw_sep, $row->biblio_keywords) as $keyword) {
+ $result[] = array('value' => trim($keyword), 'nid' => $row->nid, 'vid' => $row->vid);
+ }
+ db_query('DELETE tn.* FROM {term_node} tn INNER JOIN {term_data} td ON tn.tid = td.tid WHERE nid = %d AND td.vid = %d', $row->nid, $vid);
+ }
+ $inserted = array();
+ $count = 0;
+ foreach ($result as $keywords) {
+ // See if the term exists in the chosen vocabulary
+ // and return the tid; otherwise, add a new record.
+ $possibilities = taxonomy_get_term_by_name($keywords['value']);
+ $term_tid = NULL; // tid match, if any.
+ foreach ($possibilities as $possibility) {
+ if ($possibility->vid == $vid) {
+ $term_tid = $possibility->tid;
+ }
+ }
+
+ if (!$term_tid) {
+ $term = array('vid' => $vid, 'name' => $keywords['value']);
+ $status = taxonomy_save_term($term);
+ $term_tid = $term['tid'];
+ }
+
+ // Defend against duplicate, differently cased tags
+ if (!isset($inserted[$keywords['vid']][$term_tid])) {
+ db_query('INSERT INTO {term_node} (nid, vid, tid) VALUES (%d, %d, %d)', $keywords['nid'], $keywords['vid'], $term_tid);
+ $inserted[$keywords['vid']][$term_tid] = TRUE;
+ $count++;
+ }
+ }
+ return array('success' => TRUE, 'query' => 'Added ' . $count . ' keywords to the biblio/taxonomy keyword vocabulary');
+ }
+ return array('success' => FALSE, 'query' => 'Biblio keyword vocabulary not available');
+*/
+}
+
+function biblio_schema() {
+ $schema['biblio'] = array(
+ 'fields' => array(
+ 'nid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'description' => '',
+ ),
+ 'vid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'description' => '',
+ ),
+ 'biblio_type' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'description' => '',
+ ),
+ 'biblio_number' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '128',
+ 'description' => '',
+ ),
+ 'biblio_other_number' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '128',
+ 'description' => '',
+ ),
+ 'biblio_sort_title' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '64',
+ 'description' => 'A normalized version of the title, used for sorting on titles. (only first 64 characters saved)',
+ ),
+ 'biblio_secondary_title' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '255',
+ 'description' => '',
+ ),
+ 'biblio_tertiary_title' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '255',
+ 'description' => '',
+ ),
+ 'biblio_edition' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '255',
+ 'description' => '',
+ ),
+ 'biblio_publisher' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '255',
+ 'description' => '',
+ ),
+ 'biblio_place_published' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '255',
+ 'description' => '',
+ ),
+ 'biblio_year' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 9999,
+ 'description' => '',
+ ),
+ 'biblio_volume' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '128',
+ 'description' => '',
+ ),
+ 'biblio_pages' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '128',
+ 'description' => '',
+ ),
+ 'biblio_date' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '64',
+ 'description' => '',
+ ),
+ 'biblio_isbn' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '128',
+ 'description' => '',
+ ),
+ 'biblio_lang' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '24',
+ 'default' => 'eng',
+ 'description' => '',
+ ),
+ 'biblio_abst_e' => array(
+ 'type' => 'text',
+ 'not null' => FALSE,
+ 'description' => '',
+ ),
+ 'biblio_abst_f' => array(
+ 'not null' => FALSE,
+ 'type' => 'text',
+ 'description' => '',
+ ),
+ 'biblio_full_text' => array(
+ 'type' => 'int',
+ 'not null' => FALSE,
+ 'default' => 0,
+ 'description' => '',
+ ),
+ 'biblio_url' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '255',
+ 'description' => '',
+ ),
+ 'biblio_issue' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '128',
+ 'description' => '',
+ ),
+ 'biblio_type_of_work' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '128',
+ 'description' => '',
+ ),
+ 'biblio_accession_number' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '128',
+ 'description' => '',
+ ),
+ 'biblio_call_number' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '128',
+ 'description' => '',
+ ),
+ 'biblio_notes' => array(
+ 'type' => 'text',
+ 'not null' => FALSE,
+ 'description' => '',
+ ),
+ 'biblio_custom1' => array(
+ 'type' => 'text',
+ 'not null' => FALSE,
+ 'description' => '',
+ ),
+ 'biblio_custom2' => array(
+ 'type' => 'text',
+ 'not null' => FALSE,
+ 'description' => '',
+ ),
+ 'biblio_custom3' => array(
+ 'type' => 'text',
+ 'not null' => FALSE,
+ 'description' => '',
+ ),
+ 'biblio_custom4' => array(
+ 'type' => 'text',
+ 'not null' => FALSE,
+ 'description' => '',
+ ),
+ 'biblio_custom5' => array(
+ 'type' => 'text',
+ 'not null' => FALSE,
+ 'description' => '',
+ ),
+ 'biblio_custom6' => array(
+ 'type' => 'text',
+ 'not null' => FALSE,
+ 'description' => '',
+ ),
+ 'biblio_custom7' => array(
+ 'type' => 'text',
+ 'not null' => FALSE,
+ 'description' => '',
+ ),
+ 'biblio_research_notes' => array(
+ 'type' => 'text',
+ 'not null' => FALSE,
+ 'description' => '',
+ ),
+ 'biblio_number_of_volumes' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '128',
+ 'description' => '',
+ ),
+ 'biblio_short_title' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '255',
+ 'description' => '',
+ ),
+ 'biblio_alternate_title' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '255',
+ 'description' => '',
+ ),
+ 'biblio_original_publication' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '255',
+ 'description' => '',
+ ),
+ 'biblio_reprint_edition' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '255',
+ 'description' => '',
+ ),
+ 'biblio_translated_title' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '255',
+ 'description' => '',
+ ),
+ 'biblio_section' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '128',
+ 'description' => '',
+ ),
+ 'biblio_citekey' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '255',
+ 'description' => '',
+ ),
+ 'biblio_coins' => array(
+ 'type' => 'text',
+ 'not null' => FALSE,
+ 'description' => '',
+ ),
+ 'biblio_doi' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '255',
+ 'description' => '',
+ ),
+ 'biblio_issn' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '128',
+ 'description' => '',
+ ),
+ 'biblio_auth_address' => array(
+ 'type' => 'text',
+ 'not null' => FALSE,
+ 'description' => '',
+ ),
+ 'biblio_remote_db_name' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '255',
+ 'description' => '',
+ ),
+ 'biblio_remote_db_provider' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '255',
+ 'description' => '',
+ ),
+ 'biblio_label' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '255',
+ 'description' => '',
+ ),
+ 'biblio_access_date' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '255',
+ 'description' => '',
+ ),
+ 'biblio_refereed' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '20',
+ 'description' => '',
+ ),
+ 'biblio_md5' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '32',
+ 'description' => '',
+ ),
+ 'biblio_formats' => array(
+ 'type' => 'blob',
+ 'not null' => FALSE,
+ 'description' => '',
+ 'serialize' => TRUE,
+ ),
+ ),
+ 'foreign keys' => array(
+ 'node_revision' => array(
+ 'table' => 'node_revision',
+ 'columns' => array('vid' => 'vid'),
+ ),
+ 'node' => array(
+ 'table' => 'node',
+ 'columns' => array('nid' => 'nid'),
+ ),
+ 'biblio_type' => array(
+ 'table' => 'biblio_types',
+ 'columns' => array('biblio_type' => 'tid'),
+ ),
+ ),
+ 'primary key' => array(
+ 'vid'
+ ),
+ 'indexes' => array(
+ 'nid' => array('nid'),
+ 'md5' => array('biblio_md5'),
+ 'year' => array('biblio_year'),
+ 'title_sort' => array('biblio_sort_title'),
+ 'date' => array('biblio_date')
+ ),
+ );
+
+ $schema['biblio_fields'] = array(
+ 'fields' => array(
+ 'fid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => '{biblio_fields}.fid of the node',
+ ),
+ 'name' => array(
+ 'type' => 'varchar',
+ 'length' => '128',
+ 'not null' => TRUE,
+ 'default' => ''
+ ),
+ 'type' => array(
+ 'type' => 'varchar',
+ 'length' => '128',
+ 'not null' => TRUE,
+ 'default' => 'textfield'
+ ),
+ 'size' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 60,
+ ),
+ 'maxsize' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 255,
+ ),
+ ),
+ 'primary key' => array('fid'),
+ );
+
+ $schema['biblio_field_type'] = array(
+ 'description' => 'Relational table linking {biblio_fields} with {biblio_field_type_data}',
+ 'fields' => array(
+ 'tid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => '{biblio_types}.tid of the node',
+ ),
+ 'fid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => '{biblio_fields}.fid of the node',
+ ),
+ 'ftdid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => '{biblio_field_type_data}.ftdid of the node, points to the current data, default or custom',
+ ),
+ 'cust_tdid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => 'This always points to the custom data for this field. Stored so we can switch back an forth between default and custom',
+ ),
+ 'common' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ ),
+ 'vtab' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ ),
+ 'autocomplete' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ ),
+ 'required' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => 'Is input required for this field'
+ ),
+ 'weight' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'description' => 'The weight (location) of the field on the input form'
+ ),
+ 'visible' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => 'Determines if the field is visible on the input form'
+ ),
+
+ ),
+ 'primary key' => array('tid', 'fid'),
+ 'indexes' => array(
+ 'tid' => array('tid')
+ ),
+ );
+
+ $schema['biblio_field_type_data'] = array(
+ 'description' => 'Data used to build the form elements on the input form',
+ 'fields' => array(
+ 'ftdid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => '{biblio_field_type_data}.ftdid of the node',
+ ),
+ 'title' => array(
+ 'type' => 'varchar',
+ 'length' => '128',
+ 'not null' => TRUE,
+ 'default' => '',
+ 'description' => 'The title, which will be displayed on the form, for a given field'
+ ),
+ 'hint' => array(
+ 'type' => 'varchar',
+ 'length' => '255',
+ 'not null' => FALSE,
+ 'description' => 'The hint text printed below the input widget'
+ ),
+ ),
+ 'primary key' => array('ftdid'),
+ );
+
+ $schema['biblio_types'] = array(
+ 'fields' => array(
+ 'tid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'description' => '{biblio_types}.tid of the publication type',
+ ),
+ 'name' => array(
+ 'type' => 'varchar',
+ 'length' => '64',
+ 'not null' => TRUE,
+ 'default' => '',
+ 'description' => 'The name of the publication type'
+ ),
+ 'description' => array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '255',
+ 'description' => 'Description of the publication type'
+ ),
+ 'weight' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'description' => 'Controls the order the types are listed in'
+ ),
+ 'visible' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 1,
+ 'description' => 'Determines if the publication type is visible in the list'
+ ),
+ ),
+ 'primary key' => array('tid'),
+
+ );
+
+
+
+ $schema['biblio_contributor'] = array(
+ 'description' => 'Relational table linking authors to biblio entries',
+ 'fields' => array(
+ 'nid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => '{node}.nid of the node',
+ ),
+ 'vid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => '{node}.vid of the node',
+ ),
+ 'cid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => '{biblio_contributor_data}.cid of the node',
+ ),
+ 'auth_type' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 1,
+ 'description' => '{biblio_contributor_type}.auth_type of the node',
+ ),
+ 'auth_category' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 1,
+ 'description' => '',
+ ),
+ 'rank' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => 'Position of the author name on the publication (first,second,third...)',
+ ),
+ 'merge_cid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'unsigned' => TRUE,
+ 'description' => '',
+ ),
+ ),
+ 'foreign keys' => array(
+ 'node_revision' => array(
+ 'table' => 'node_revision',
+ 'columns' => array('vid' => 'vid'),
+ ),
+ 'node' => array(
+ 'table' => 'node',
+ 'columns' => array('nid' => 'nid'),
+ ),
+ 'biblio_contributor_data' => array(
+ 'table' => 'biblio_contributor_data',
+ 'columns' => array('cid' => 'cid'),
+ ),
+ 'biblio_contributor_type' => array(
+ 'table' => 'biblio_contributor_type',
+ 'columns' => array('auth_type' => 'auth_type'),
+ ),
+ 'biblio_contributor_category' => array(
+ 'table' => 'biblio_contributor_type',
+ 'columns' => array('auth_category' => 'auth_category'),
+ ),
+ ),
+ 'primary key' => array(
+ 'vid',
+ 'cid',
+ 'auth_type',
+ 'rank'
+ ),
+ );
+
+ $schema['biblio_contributor_data'] = array(
+ 'description' => 'Contains Author information for each publication',
+ 'fields' => array(
+ 'cid' => array(
+ 'type' => 'serial',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'description' => 'Primary Key: Author ID',
+ ),
+ 'aka' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'unsigned' => TRUE,
+ 'description' => 'Also known as, links this author entry with others so you can have variation on the name, but listing by cid will find all other (aka) author entries',
+ ),
+ 'alt_form' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'unsigned' => TRUE,
+ 'description' => 'Alternate form of an author name, this value points to the desired form (cid), this form is kept in the database so that future imports of the same name will not create a new author.',
+ ),
+ 'drupal_uid' => array(
+ 'type' => 'int',
+ 'not null' => FALSE,
+ 'unsigned' => TRUE,
+ 'description' => 'Drupal User ID',
+ ),
+ 'name' => array(
+ 'type' => 'varchar',
+ 'length' => '255',
+ 'not null' => TRUE,
+ 'default' => '',
+ 'description' => 'Full name',
+ ),
+ 'lastname' => array(
+ 'type' => 'varchar',
+ 'length' => '255',
+ 'not null' => TRUE,
+ 'default' => '',
+ 'description' => 'Author last name',
+ ),
+ 'firstname' => array(
+ 'type' => 'varchar',
+ 'length' => '128',
+ 'not null' => FALSE,
+ 'default' => '',
+ 'description' => 'Author first name',
+ ),
+ 'prefix' => array(
+ 'type' => 'varchar',
+ 'length' => '128',
+ 'not null' => FALSE,
+ 'default' => '',
+ 'description' => 'Author name prefix',
+ ),
+ 'suffix' => array(
+ 'type' => 'varchar',
+ 'length' => '128',
+ 'not null' => FALSE,
+ 'default' => '',
+ 'description' => 'Author name suffix',
+ ),
+ 'initials' => array(
+ 'type' => 'varchar',
+ 'length' => '10',
+ 'not null' => FALSE,
+ 'default' => '',
+ 'description' => 'Author initials (including first name initial)',
+ ),
+ 'affiliation' => array(
+ 'type' => 'varchar',
+ 'length' => '255',
+ 'not null' => FALSE,
+ 'default' => '',
+ 'description' => 'Author affiliation or address',
+ ),
+ 'literal' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'unsigned' => TRUE,
+ 'description' => 'Determines if the author name is allowed to be reformated by the variaous styles or should be used literally.',
+ ),
+ 'md5' => array(
+ 'type' => 'varchar',
+ 'length' => '32',
+ 'not null' => FALSE,
+ 'description' => '',
+ )
+ ),
+ 'foreign keys' => array(
+ 'biblio_contributor' => array(
+ 'table' => 'biblio_contributor',
+ 'columns' => array('cid' => 'cid'),
+ ),
+ 'node_author' => array(
+ 'table' => 'users',
+ 'columns' => array('drupal_uid' => 'uid'),
+ ),
+ ),
+ 'primary key' => array('cid'),
+ 'indexes' => array(
+ 'lastname' => array('lastname'),
+ 'firstname' => array('firstname'),
+ 'initials' => array('initials')
+ )
+ );
+ $schema['biblio_contributor_type'] = array(
+ 'description' => 'Contains definitions of the contributor types',
+ 'fields' => array(
+ 'auth_category' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => 'There are 5 catagoies of author: Primary, Secondary, Tertiery, Subsidary and Corporate ',
+ ),
+ 'biblio_type' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => '',
+ ),
+ 'auth_type' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => 'This is the pulication type specific verion of a particular catagory',
+ ),
+ ),
+ 'foreign keys' => array(
+ 'biblio' => array(
+ 'table' => 'biblio',
+ 'columns' => array('biblio_type' => 'biblio_type'),
+ ),
+ 'biblio_contributor_type' => array(
+ 'table' => 'biblio_contributor',
+ 'columns' => array('auth_type' => 'auth_type'),
+ ),
+ 'biblio_contributor_category' => array(
+ 'table' => 'biblio_contributor',
+ 'columns' => array('auth_category' => 'auth_category'),
+ ),
+ ),
+ 'primary key' => array('auth_category', 'biblio_type', 'auth_type'),
+ );
+
+ $schema['biblio_contributor_type_data'] = array(
+ 'description' => 'Data used to build the form elements on the input form',
+ 'fields' => array(
+ 'auth_type' => array(
+ 'type' => 'serial',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'description' => '{biblio_contributor_type_data} ctdid of the node',
+ ),
+ 'title' => array(
+ 'type' => 'varchar',
+ 'length' => '128',
+ 'not null' => TRUE,
+ 'default' => '',
+ 'description' => 'The title, which will be displayed on the form, for a given field'
+ ),
+ 'hint' => array(
+ 'type' => 'varchar',
+ 'length' => '255',
+ 'not null' => FALSE,
+ 'description' => 'The hint text printed below the input widget'
+ ),
+ ),
+ 'primary key' => array('auth_type'),
+ );
+
+ $schema['biblio_keyword'] = array(
+ 'description' => 'Relational table linking keywords to biblio nodes',
+ 'fields' => array(
+ 'kid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => 'Primary Key: The {biblio_keyword_data}.kid of the keyword of the node.',
+ ),
+ 'nid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => 'The {node}.nid of the node.',
+ ),
+ 'vid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => 'Primary Key: The {node}.vid of the node.',
+ ),
+ ),
+ 'foreign keys' => array(
+ 'node_revision' => array(
+ 'table' => 'node_revision',
+ 'columns' => array('vid' => 'vid'),
+ ),
+ 'node' => array(
+ 'table' => 'node',
+ 'columns' => array('nid' => 'nid'),
+ ),
+ 'keyword' => array(
+ 'table' => 'biblio_keyword_data',
+ 'columns' => array('kid' => 'kid'),
+ ),
+ ),
+ 'primary key' => array('kid', 'vid'),
+ 'indexes' => array(
+ 'vid' => array('vid'),
+ 'nid' => array('nid'),
+ ),
+ );
+
+ $schema['biblio_keyword_data'] = array(
+ 'description' => 'Stores the keywords related to nodes.',
+ 'fields' => array(
+ 'kid' => array(
+ 'type' => 'serial',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'description' => 'Primary Key: The id of the keyword assigned to the node',
+ ),
+ 'word' => array(
+ 'type' => 'varchar',
+ 'length' => 255,
+ 'not null' => TRUE,
+ 'default' => '',
+ 'description' => 'The keyword',
+ ),
+ ),
+ 'primary key' => array('kid'),
+ 'indexes' => array(
+ 'kword' => array('word'),
+ ),
+ );
+ $schema['biblio_collection'] = array(
+ 'description' => 'Relational table grouping biblio nodes into collections',
+ 'fields' => array(
+ 'cid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => 'Primary Key: The {biblio_collection_data}.cid of the collection',
+ ),
+ 'vid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => 'Primary Key: The {node}.vid of the node.',
+ ),
+ 'pid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => 'The parent id of the collection',
+ ),
+ 'nid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => 'The {node}.nid of the node.',
+ ),
+ ),
+ 'primary key' => array('cid', 'vid'),
+ 'indexes' => array(
+ 'pid' => array('pid'),
+ 'nid' => array('nid'),
+ ),
+ );
+ $schema['biblio_collection_type'] = array(
+ 'description' => 'Descriptions of the collections.',
+ 'fields' => array(
+ 'cid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => 'Primary Key: The id of the collection',
+ ),
+ 'name' => array(
+ 'type' => 'varchar',
+ 'length' => 255,
+ 'not null' => TRUE,
+ 'default' => '',
+ 'description' => 'The name of the collection',
+ ),
+ 'description' => array(
+ 'type' => 'varchar',
+ 'length' => 255,
+ 'not null' => TRUE,
+ 'default' => '',
+ 'description' => 'The description of the collection',
+ ),
+ ),
+ 'primary key' => array('cid'),
+ 'indexes' => array(
+ 'name' => array('name'),
+ ),
+ );
+ $schema['biblio_duplicates'] = array(
+ 'description' => 'Relational table linking possible duplicate biblio nodes',
+ 'fields' => array(
+ 'vid' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => 'Primary Key: The {biblio}.nid of the original node',
+ ),
+ 'did' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => 'The {biblio}.nid of the newly imported node which may be a duplicate.',
+ ),
+ 'type' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => 'The type of duplicate 0=biblio, 1=author.',
+ ),
+ ),
+ 'primary key' => array('vid', 'did'),
+ 'indexes' => array(
+ 'did' => array('vid'),
+ ),
+ );
+
+ $schema['biblio_import_cache'] = array(
+ 'description' => 'tables used for caching data imported from file and then batch processed',
+ 'fields' => array(
+ 'id' => array(
+ 'type' => 'serial',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE),
+ 'session_id' => array(
+ 'type' => 'varchar',
+ 'length' => 45,
+ 'not null' => TRUE),
+ 'data' => array(
+ 'description' => 'A collection of data to cache.',
+ 'type' => 'blob',
+ 'not null' => FALSE,
+ 'size' => 'big'),
+ ),
+ 'primary key' => array('id'));
+
+ $schema['biblio_type_maps'] = array(
+ 'description' => 'Table used to store the mapping information between various file formats and the biblio schema',
+ 'fields' => array(
+ 'format' => array(
+ 'description' => 'The import/export file format',
+ 'type' => 'varchar',
+ 'length' => 128,
+ 'not null' => TRUE),
+ 'type_map' => array(
+ 'description' => 'The mapping between the publication types in the file format and biblio',
+ 'type' => 'blob',
+ 'not null' => FALSE,
+ 'size' => 'big'),
+ 'type_names' => array(
+ 'description' => 'The human readable names of the publication types',
+ 'type' => 'blob',
+ 'not null' => FALSE,
+ 'size' => 'big'),
+ 'field_map' => array(
+ 'description' => 'The mapping between the fields in the file format and biblio',
+ 'type' => 'blob',
+ 'not null' => FALSE,
+ 'size' => 'big'),
+ 'export_map' => array(
+ 'description' => 'which fields are exported',
+ 'type' => 'blob',
+ 'not null' => FALSE,
+ 'size' => 'big'),
+ ),
+ 'primary key' => array('format'));
+
+ $schema['biblio_vtabs'] = array(
+ 'description' => 'Table used to store the information to create the vertical tabs on the input form',
+ 'fields' => array(
+ 'tab_id' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => ''
+ ),
+ 'weight' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ 'description' => ''
+ ),
+ 'title' => array(
+ 'type' => 'varchar',
+ 'length' => 128,
+ 'not null' => TRUE,
+ 'default' => '',
+ 'description' => 'The title of the tab',
+ ),
+ 'description' => array(
+ 'type' => 'varchar',
+ 'length' => 255,
+ 'not null' => TRUE,
+ 'default' => '',
+ 'description' => 'The description of the tab',
+ ),
+ ),
+ 'primary key' => array('tab_id'));
+
+ return ($schema);
+
+}
+
+function biblio_reset_types() {
+ $result = array();
+
+ db_drop_table('biblio_field_type_data');
+ db_drop_table('biblio_field_type');
+ db_drop_table('biblio_fields');
+ db_drop_table('biblio_contributor_type');
+ db_drop_table('biblio_contributor_type_data');
+
+ db_query('DELETE FROM {biblio_types} WHERE tid>999');
+ db_query('UPDATE {biblio_types} SET visible=1 WHERE visible=0');
+
+ $schema = biblio_schema();
+ db_create_table('biblio_field_type_data', $schema['biblio_field_type_data']);
+ db_create_table('biblio_field_type', $schema['biblio_field_type']);
+ db_create_table('biblio_fields', $schema['biblio_fields']);
+ db_create_table('biblio_contributor_type', $schema['biblio_contributor_type']);
+ db_create_table('biblio_contributor_type_data', $schema['biblio_contributor_type_data']);
+
+ variable_set('biblio_last_ftdid', 100); // reset custom field type id too
+ //_add_db_field_data_XML();
+ _add_db_field_data();
+ _add_custom_field_data();
+}
+
+function _biblio_add_vtabs() {
+ $vtabs = array(
+ array('tab_id' => 1, 'weight' => 1, 'title' => 'Authors', 'description' => ''),
+ array('tab_id' => 2, 'weight' => 2, 'title' => 'Publication', 'description' => ''),
+ array('tab_id' => 3, 'weight' => 3, 'title' => 'Publisher', 'description' => ''),
+ array('tab_id' => 4, 'weight' => 4, 'title' => 'Identifiers', 'description' => ''),
+ array('tab_id' => 5, 'weight' => 5, 'title' => 'Locators', 'description' => 'URL\'s etc'),
+ array('tab_id' => 6, 'weight' => 6, 'title' => 'Keywords', 'description' => ''),
+ array('tab_id' => 7, 'weight' => 7, 'title' => 'Notes', 'description' => ''),
+ array('tab_id' => 8, 'weight' => 8, 'title' => 'Alternate Titles', 'description' => ''),
+ array('tab_id' => 9, 'weight' => 9, 'title' => 'Other', 'description' => ''),
+ );
+
+ foreach ($vtabs as $record) {
+ db_insert('biblio_vtabs')->fields($record)->execute();
+ }
+
+
+}
+
+function _add_publication_types() {
+ $types[] = array(100, 'Book', NULL, 1);
+ $types[] = array(101, 'Book Chapter', NULL, 2);
+ $types[] = array(102, 'Journal Article', NULL, 3);
+ $types[] = array(131, 'Journal', NULL, 3);
+ $types[] = array(103, 'Conference Paper', NULL, 4);
+ $types[] = array(104, 'Conference Proceedings', NULL, 5);
+ $types[] = array(105, 'Newspaper Article', NULL, 6);
+ $types[] = array(106, 'Magazine Article', NULL, 7);
+ $types[] = array(107, 'Web Article', NULL, 8);
+ $types[] = array(132, 'Website', NULL, 8);
+ $types[] = array(133, 'Web service', NULL, 8);
+ $types[] = array(134, 'Web project page', NULL, 8);
+ $types[] = array(108, 'Thesis', NULL, 9);
+ $types[] = array(109, 'Report', NULL, 10);
+ $types[] = array(110, 'Film', NULL, 11);
+ $types[] = array(111, 'Broadcast', NULL, 12);
+ $types[] = array(112, 'Artwork', NULL, 13);
+ $types[] = array(113, 'Software', NULL, 14);
+ $types[] = array(114, 'Audiovisual', NULL, 15);
+ $types[] = array(115, 'Hearing', NULL, 16);
+ $types[] = array(116, 'Case', NULL, 17);
+ $types[] = array(117, 'Bill', NULL, 18);
+ $types[] = array(118, 'Statute', NULL, 19);
+ $types[] = array(119, 'Patent', NULL, 20);
+ $types[] = array(120, 'Personal', NULL, 21);
+ $types[] = array(121, 'Manuscript', NULL, 22);
+ $types[] = array(122, 'Map', NULL, 23);
+ $types[] = array(123, 'Chart', NULL, 24);
+ $types[] = array(124, 'Unpublished', NULL, 25);
+ $types[] = array(125, 'Database', NULL, 26);
+ $types[] = array(126, 'Government Report', NULL, 27);
+ $types[] = array(127, 'Classical' , NULL, 28);
+ $types[] = array(128, 'Legal Ruling', NULL, 29);
+ $types[] = array(129, 'Miscellaneous', NULL, 30);
+ $types[] = array(130, 'Miscellaneous Section', NULL, 31);
+ $types[] = array(135,'Presentation', NULL, 8);
+
+ foreach ($types as $record) {
+ db_insert('biblio_types')->fields(array(
+ 'tid' => $record[0],
+ 'name' => $record[1],
+ 'description' => $record[2],
+ 'weight' => $record[3],
+ ))->execute();
+
+ }
+ return;
+}
+
+function _add_db_field_data_XML() {
+ $next_ctdid=10; //first contributor_type_data id
+ $schema = biblio_schema();
+ $fieldnames = array_keys($schema['biblio_fields']['fields']);
+ $field_type_fieldnames = array_keys($schema['biblio_field_type']['fields']);
+ $field_type_data_fieldnames = array_keys($schema['biblio_field_type_data']['fields']);
+ db_query("/*!40000 ALTER TABLE {biblio_field_type_data} DISABLE KEYS */;");
+ db_query("/*!40000 ALTER TABLE {biblio_fields} DISABLE KEYS */;");
+ for ($type = 1; $type <= 5; $type++) {
+ for ($biblio_type = 100; $biblio_type <= 130; $biblio_type++) {
+ db_query("INSERT INTO {biblio_contributor_type} (auth_category, biblio_type, auth_type) VALUES (%d, %d, %d)", $type, $biblio_type, $type);
+ }
+ }
+ _id_by_name(NULL, NULL, NULL, array('tablename' => 'biblio_field_type_data', 'name_column' => 'title', 'id_column' => 'ftdid'));
+
+ $xml_file = drupal_get_path('module', 'biblio') . '/field_data.xml';
+ $xml = simplexml_load_file($xml_file);
+ foreach ($xml->field as $field) {
+ $link_data = array(0, $field['fid'], $field['fid'], $field['fid'], $field->common, $field->autocomplete, $field->required, $field->weight, $field->visible);
+ db_query("INSERT INTO {biblio_field_type} (" . implode(", ", $field_type_fieldnames) . ")
+ VALUES (%d, %d, %d, %d, %d, %d, %d, %d, %d)", $link_data);
+ for ($t = 100; $t <= 130; $t++) {
+ $values = array($t, $field['fid'], $field['fid'], $field['fid'], $field->common, $field->autocomplete, $field->required, $field->weight, $field->visible);
+ db_query("INSERT INTO {biblio_field_type} (" . implode(", ", $field_type_fieldnames) . ")
+ VALUES('" . implode("', '", $values) . "')");
+ }
+ $ftd = array($field['fid'], $field->default_name, $field->hint);
+ db_query("INSERT INTO {biblio_field_type_data} (" . implode(", ", $field_type_data_fieldnames) . ")
+ VALUES('" . implode("', '", $ftd) . "')");
+ $field_data = array($field['fid'], $field->field_name, $field->type, $field->width, $field->maxlength);
+ db_query("INSERT INTO {biblio_fields} (" . implode(", ", $fieldnames) . ")
+ VALUES('" . implode("', '", $field_data) . "')");
+ foreach ($field->name as $name) {
+ if ($name != "~" ) { //&& $field->type != 'contrib_widget') {
+ $ftd[0] = ($existing_id = _id_by_name('biblio_field_type_data', $name)) ? $existing_id : variable_get('biblio_last_ftdid', 100); // ftdid
+ $ftd[1] = trim($name); // title
+ $ftd[2] = ""; // hint
+ db_query("UPDATE {biblio_field_type}
+ SET ftdid = %d, cust_tdid = %d, visible = %d
+ WHERE tid = %d AND fid = %d ", $ftd[0], $ftd[0], 1, $name['tid'], $field['fid'] );
+ if (!$existing_id) {
+ // if this title doesn't alreay exist, then insert it into the table
+ db_query("INSERT INTO {biblio_field_type_data} (" . implode(", ", $field_type_data_fieldnames) . ")
+ VALUES (%d, '%s', '%s')", $ftd);
+ _id_by_name('biblio_field_type_data', $name, $ftd[0]); // cache the new id value for future use
+ variable_set('biblio_last_ftdid', $ftd[0] +1); //increment the field type data id by one.
+ }
+
+ }
+ elseif ($name == "~" ) {
+ // turn the visibility off for this (~) type
+ db_query("UPDATE {biblio_field_type}
+ SET visible = 0
+ WHERE tid = %d AND fid = %d ", $name['tid'], $field['fid'] );
+ }
+ if ($field->type == 'contrib_widget' && $name != "~" ) {
+ db_query("UPDATE {biblio_contributor_type} SET auth_type=%d where auth_category=%d and biblio_type=%d", $ftd[0], $field->contrib_type, $name['tid']);
+ }
+ }
+ }
+
+
+
+ db_query("/*!40000 ALTER TABLE {biblio_field_type_data} ENABLE KEYS */;");
+ db_query("/*!40000 ALTER TABLE {biblio_fields} ENABLE KEYS */;");
+
+ return $result;
+}
+
+function _add_db_field_data() {
+ if (db_driver() == 'mysql' or db_driver() == 'mysqli') {
+ db_query("/*!40000 ALTER TABLE {biblio_field_type_data} DISABLE KEYS */;");
+ db_query("/*!40000 ALTER TABLE {biblio_fields} DISABLE KEYS */;");
+ }
+ $csv_file = drupal_get_path('module', 'biblio') . '/misc/biblio.field.link.data.csv';
+
+ if ($handle = fopen($csv_file, "r")) {
+ $header = fgetcsv($handle, 10000, ","); // the first line has the field names
+ while (($row = fgetcsv($handle, 10000, ",")) !== FALSE) {
+ $column = 0;
+ // add link data for default biblio type (0) and all other defined types (100-130)
+ foreach (array_merge(array(0), range(100, 136)) as $t) {
+ db_insert('biblio_field_type')->fields(array(
+ 'tid' => $t,
+ 'fid' => $row[0],
+ 'ftdid' => $row[0],
+ 'cust_tdid' => $row[0],
+ 'common' => $row[3],
+ 'autocomplete' => $row[4],
+ 'required' => $row[5],
+ 'weight' => $row[6],
+ 'visible' => $row[7],
+ 'vtab' => $row[12]
+ ))->execute();
+ }
+
+ db_insert('biblio_field_type_data')->fields(array(
+ 'ftdid' => $row[0],
+ 'title' => $row[1],
+ 'hint' => $row[2]
+ ))->execute();
+
+ db_insert('biblio_fields')->fields(array(
+ 'fid' => $row[0],
+ 'name' => $row[8],
+ 'type' => $row[9],
+ 'size' => $row[10],
+ 'maxsize' => $row[11]
+ ))->execute();
+
+ // add contributor type data
+ if ($row[9] == 'contrib_widget') {
+ // use field name without trailing 's' as initial guess for author type
+ $auth_type = (substr($row[1], -1, 1) == 's') ? substr($row[1], 0, -1) : $row[1];
+
+ db_insert('biblio_contributor_type_data')->fields(array(
+ 'auth_type' => $row[0],
+ 'title' => $auth_type
+ ))->execute();
+
+ db_insert('biblio_contributor_type')->fields(array(
+ 'auth_category' => $row[0],
+ 'biblio_type' => 0,
+ 'auth_type' => $row[0]
+ ))->execute();
+ }
+ }
+ fclose($handle);
+ $result = array('success' => TRUE, 'query' => 'Added field titles and default values');
+
+ }
+ else {
+ $result = array('success' => FALSE, 'query' => 'Could not open ' . $csv_file);
+ }
+
+ if (db_driver() == 'mysql' or db_driver() == 'mysqli') {
+ db_query("/*!40000 ALTER TABLE {biblio_field_type_data} ENABLE KEYS */;");
+ db_query("/*!40000 ALTER TABLE {biblio_fields} ENABLE KEYS */;");
+ }
+ return $result;
+}
+
+function _add_custom_field_data() {
+
+ $next_ctdid=10; //first contributor_type_data id
+ $schema = biblio_schema();
+ $fieldnames = array_keys($schema['biblio_field_type_data']['fields']);
+
+ $query = "SELECT fid, name FROM {biblio_fields} ";
+ $res = db_query($query);
+ foreach ($res as $row) {
+ $fieldmap[$row->name] = $row->fid;
+ }
+
+ $csv_file = drupal_get_path('module', 'biblio') . '/misc/biblio.field.type.data.csv';
+
+ if ($handle = fopen($csv_file, "r")) {
+ $header = fgetcsv($handle, 10000, ","); // the first line has the field names
+ $generic = fgetcsv($handle, 10000, ","); // the second line has the default titles if none given
+ // build cache lookups
+ _id_by_name(NULL, NULL, NULL, array('tablename' => 'biblio_field_type_data', 'name_column' => 'title', 'id_column' => 'ftdid'));
+ _id_by_name(NULL, NULL, NULL, array('tablename' => 'biblio_contributor_type_data', 'name_column' => 'title', 'id_column' => 'auth_type'));
+ // map contributor field titles to field ids
+ $res = db_query("SELECT fid,name FROM {biblio_fields} WHERE type='contrib_widget'");
+ $contributor_categories = array();
+ foreach ($res as $row ) {
+ $contributor_categories[$row->name] = $row->fid;
+ }
+ // process all rows of the file
+ while (($row = fgetcsv($handle, 10000, ",")) !== FALSE) {
+ $column = 0;
+ if (empty($row[1])) continue;
+
+ foreach ($header as $key => $field_name) {
+ if (!empty($field_name) && $field_name != 'tid') {
+ if (!empty($row[$column]) && $row[$column] != "~" && isset($fieldmap[$field_name])) {
+ $ftd[0] = ($existing_id = _id_by_name('biblio_field_type_data', $row[$column])) ? $existing_id : variable_get('biblio_last_ftdid', 100); // ftdid
+ $ftd[1] = trim($row[$column]); // title
+ $ftd[2] = ""; // hint
+
+ db_update('biblio_field_type')
+ ->fields(array( 'ftdid' => $ftd[0], 'cust_tdid' => $ftd[0], 'visible' => 1))
+ ->condition(db_and()->condition('tid', $row[1])->condition('fid', $fieldmap[$field_name]))
+ ->execute();
+
+ if (!$existing_id) {
+ // if this title doesn't alreay exist, then insert it into the table
+ db_insert('biblio_field_type_data')
+ ->fields(array('ftdid' => $ftd[0], 'title' => $ftd[1], 'hint' => $ftd[2]))
+ ->execute();
+
+ _id_by_name('biblio_field_type_data', $row[$column], $ftd[0]); // cache the new id value for future use
+ variable_set('biblio_last_ftdid', $ftd[0] +1); //increment the field type data id by one.
+ }
+
+ // also populate biblio_contributor_type tables
+ if ((substr($field_name, -7, 7) == 'authors') && $row[$column] != '~' ) {
+ $type = $contributor_categories[$field_name];
+ $title = trim($row[$column]);
+ $biblio_type = $row[1];
+ $ctdid = ($eid = _id_by_name('biblio_contributor_type_data', $title)) ? $eid : $next_ctdid;
+ db_update('biblio_contributor_type')
+ ->fields(array(
+ 'auth_type' => $ctdid))
+ ->condition(db_and()->condition('auth_category', $type)->condition('biblio_type', $biblio_type))
+ ->execute();
+
+ if (!$eid) {
+ db_insert('biblio_contributor_type_data')
+ ->fields(array('auth_type' => $ctdid, 'title' => $title))
+ ->execute();
+
+ _id_by_name('biblio_contributor_type_data', $title, $ctdid); // cache the new id value for future use
+ $next_ctdid++;
+ }
+ }
+ }
+ elseif ($row[$column] == "~" && isset($fieldmap[$field_name])) {
+ // turn the visibility off for this (~) type
+
+ db_update('biblio_field_type')
+ ->fields(array('visible' => 0))
+ ->condition(db_and()->condition('tid', $row[1])->condition('fid', $fieldmap[$field_name]))
+ ->execute();
+
+ }
+ elseif (empty($row[$column]) && isset($fieldmap[$field_name])) {
+ // use the default field title when the title is blank
+ db_update('biblio_field_type')
+ ->fields(array('visible' => 1))
+ ->condition(db_and()->condition('tid', $row[1])->condition('fid', $fieldmap[$field_name]))
+ ->execute();
+ }
+ }
+ $column++;
+ }
+ }
+ fclose($handle);
+ $result = array('success' => TRUE, 'query' => 'Added type specific field titles');
+ }
+ else {
+ $result = array('success' => FALSE, 'query' => 'Could not open ' . $csv_file);
+ }
+
+ return $result;
+}
+function _id_by_name($table, $name, $id = NULL, $build = NULL) {
+ static $result = NULL;
+ if (!empty($build)) { //refresh cache from table
+ unset($result[$build['tablename']]);
+ $res = db_query("SELECT " . $build['name_column'] . ", " . $build['id_column'] . " FROM {" . $build['tablename'] . "}", array(), array('fetch' => PDO::FETCH_ASSOC));
+ foreach ($res as $row ) {
+ $result[$build['tablename']][$row[$build['name_column']]] = $row[$build['id_column']];
+ }
+ return;
+ }
+ $name = trim($name);
+ if (isset($result[$table][$name])) return $result[$table][$name];
+ if ($id) $result[$table][$name] = $id;
+ return FALSE;
+}
+/*
+ * Removed updates 1 - 27 since they were from 5.x biblio
+ */
+
+/*
+ * Removed updates 6000 - 6023 only upgrades from biblio 6.x-1.9 are supported
+ */
+/* add the new field -refereed- on the biblio table
+*/
+function biblio_update_6024() {
+
+ db_add_field('biblio', 'biblio_refereed', array('type' => 'varchar', 'length' => '20'));
+
+ /* add the field data for -refereed- on the biblo_fields table
+ you need to get the last inserted record from biblio_fields and increment it by one
+ so you don't step on customized fields added via the user online interface */
+
+ $sql = 'SELECT fid FROM {biblio_fields} ORDER BY fid DESC';
+ $lastfid = db_query_range($sql, 0, 1)->fetchField();
+ $newfid = $lastfid + 1;
+
+ db_query("INSERT INTO {biblio_fields} (fid, name, type, size, maxsize) VALUES
+ ($newfid, 'biblio_refereed', 'select', 0, 125)");
+
+ /*use the same fid and insert an entry in the biblio_field_type_data */
+ db_query("INSERT INTO {biblio_field_type_data}
+ (ftdid, title, hint) VALUES ($newfid, 'Refereed Designation', NULL)");
+
+ /* get a list of unique tids from the biblio_field_type table. You want to
+ insert a tid,fid using the new fid for every available tid */
+
+ $newsql = "SELECT DISTINCT tid FROM {biblio_field_type} ORDER BY tid DESC";
+
+ $tidlist = db_query($newsql);
+ foreach ($tidlist as $tid) {
+ $newtid = $tid->tid ;
+ db_query('INSERT INTO {biblio_field_type}
+ (tid, fid, ftdid, cust_tdid, common, autocomplete, required, weight, visible)
+ VALUES (%d, %d, %d, %d, %d, %d, %d, %d, %d)',
+ $newtid, $newfid, $newfid, $newfid, 1, 1, 0, 1, 1);
+ }
+}
+
+function biblio_update_6025() {
+ $schema = biblio_schema();
+ db_create_table('biblio_type_maps', $schema['biblio_type_maps']);
+}
+
+function biblio_update_6026() {
+ // move custom block titles stored in variable "biblio_block_title" to the block table if the title has not already been overriden
+ $custom_title = variable_get('biblio_block_title', '');
+ if (!empty($custom_title)) {
+ $db_result = db_query("SELECT bid,title FROM {blocks} b where module='biblio' ");
+ foreach ($db_result as $block) {
+ if (empty ($block->title)) {
+ $block->title = $custom_title;
+ db_query("UPDATE {blocks} SET title='" . $block->title . "' WHERE bid=" . $block->bid);
+ }
+ }
+ variable_del('biblio_block_title');
+ }
+}
+
+function biblio_update_6027() {
+ // renunmber the author rank such that it is zero based accross all categories
+ // this only needs to be done for entries that actually have auth_categories other than 1
+ require_once(drupal_get_path('module', 'biblio') . '/includes/biblio.contributors.inc');
+ $result = array();
+ $count = 0;
+ $db_result = db_query("SELECT DISTINCT(vid),nid FROM {biblio_contributor} WHERE auth_category IN (2,3,4,5) ");
+ $count_success = db_query("SELECT COUNT(DISTINCT(vid)) FROM {biblio_contributor} WHERE auth_category IN (2,3,4,5) ")->fetchField();
+ foreach ($db_result as $node) {
+ $contributors = biblio_load_contributors($node->vid);
+ _save_contributors($contributors, $node->nid, $node->vid, $update = FALSE) ;
+ $count++;
+ }
+}
+
+function biblio_update_6028() {
+/*
+ * Caching is not used in 7.x CiteProc
+ *
+ $table = drupal_get_schema_unprocessed('system', 'cache');
+ $table['description'] = 'Cache table for biblio to store pre-built csl objects';
+ $table['fields']['serialized']['default'] = 1;
+*/
+}
+
+function biblio_update_6029() {
+ $spec = array(
+ 'type' => 'blob',
+ 'not null' => FALSE,
+ 'default' => NULL,
+ 'size' => 'big',
+ 'description' => 'Stores the mapping between biblio fields and external file formats',
+ );
+ db_add_field('biblio_type_maps', 'export_map', $spec);
+}
+
+function biblio_update_6030() {
+
+ $spec = array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'unsigned' => TRUE,
+ 'description' => 'Determines if the author name is allowed to be reformated by the variaous styles or should be used literally.',
+ );
+ db_add_field('biblio_contributor_data', 'literal', $spec);
+
+}
+
+function biblio_update_6031() {
+ $result = array();
+ $types[] = array(131, 'Journal', NULL, 3);
+ $types[] = array(132, 'Web site', NULL, 8);
+ $types[] = array(133, 'Web service','e.g. Google, Yahoo', 8);
+ $types[] = array(134, 'Web project page', NULL, 8);
+ $types[] = array(135, 'Presentation', NULL, 8);
+ $types[] = array(136, 'Newspaper', NULL, 8);
+
+ foreach ($types as $record) {
+ db_query("INSERT INTO {biblio_types} (tid, name, description, weight) VALUES ('" . implode("', '", $record) . "')");
+ }
+
+ db_query("DELETE FROM {biblio_types} WHERE tid=-1");
+
+ return $result;
+}
+
+function biblio_update_6032() {
+ $spec = array(
+ 'type' => 'varchar',
+ 'length' => '255',
+ 'not null' => TRUE,
+ 'default' => '',
+ 'description' => 'Full name',
+ );
+ db_change_field('biblio_contributor_data', 'name', 'name', $spec);
+}
+function biblio_update_6033() {
+ $spec = array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '64',
+ 'description' => 'A normalized version of the title, used for sorting on titles. (only first 64 characters saved)',
+ );
+ db_add_field('biblio', 'biblio_sort_title', $spec);
+}
+
+function biblio_update_7000() {
+
+ _biblio_helper_modules('install');
+
+}
+/**
+ * Add new column to biblio_contributor_data table
+ */
+function biblio_update_7001() {
+ if (!db_field_exists('biblio_contributor_data', 'literal')) {
+ $spec = array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'unsigned' => TRUE,
+ 'description' => 'Determines if the author name is allowed to be reformated by the variaous styles or should be used literally.',
+ );
+ db_add_field('biblio_contributor_data', 'literal', $spec);
+ }
+}
+/**
+ *
+ * Adds export_map column to biblio_type_maps table
+ */
+function biblio_update_7002() {
+ if (!db_field_exists('biblio_type_maps', 'export_map')) {
+ biblio_update_6029();
+ }
+}
+/**
+ *
+ * Adds some new publication types
+ */
+function biblio_update_7003() {
+ $result = db_query('SELECT tid FROM {biblio_types} WHERE tid = :tid', array(':tid' => 136))->fetchField();
+ if (!$result) {
+ biblio_update_6031();
+ }
+}
+
+function _biblio_update_field_link_data($range, $vtabs = FALSE) {
+ $csv_file = drupal_get_path('module', 'biblio') . '/misc/biblio.field.link.data.csv';
+
+ if ($handle = fopen($csv_file, "r")) {
+ $header = fgetcsv($handle, 10000, ","); // the first line has the field names
+ while (($row = fgetcsv($handle, 10000, ",")) !== FALSE) {
+ if ($vtabs) {
+ // add link data for default biblio type (0) and all other defined types (100-130)
+ foreach (array_merge(array(0), range($range[0], $range[1])) as $t) {
+ db_update('biblio_field_type')
+ ->fields(array(
+ 'vtab' => $row[12]
+ ))
+ ->condition(db_and()->condition('tid', $t)->condition('fid', $row[0]))
+ ->execute();
+ }
+ }
+ else {
+ foreach (range($range[0], $range[1]) as $t) {
+ db_insert('biblio_field_type')->fields(array(
+ 'tid' => $t,
+ 'fid' => $row[0],
+ 'ftdid' => $row[0],
+ 'cust_tdid' => $row[0],
+ 'common' => $row[3],
+ 'autocomplete' => $row[4],
+ 'required' => $row[5],
+ 'weight' => $row[6],
+ 'visible' => $row[7],
+ 'vtab' => $row[12]
+ ))->execute();
+ }
+ }
+ }
+ }
+
+}
+
+/**
+ * Add information to manage vtabs on input form.
+*/
+function biblio_update_7005() {
+ $spec = array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ 'default' => 0,
+ );
+ db_add_field('biblio_field_type', 'vtab', $spec);
+ _biblio_update_field_link_data(array(100, 130), TRUE);
+ cache_clear_all();
+}
+
+function biblio_update_7006() {
+ $result = db_query('SELECT fid FROM {biblio_field_type} WHERE tid = :tid', array(':tid' => 136))->fetchField();
+ if (!$result) {
+ _biblio_update_field_link_data(array(131, 136));
+ cache_clear_all();
+ }
+}
+/**
+ * Increases the size of the {biblio_contributor_data}.name column to 255 characters
+*/
+function biblio_update_7007() {
+ $spec = array(
+ 'type' => 'varchar',
+ 'length' => '255',
+ 'not null' => TRUE,
+ 'default' => '',
+ 'description' => 'Full name',
+ );
+ db_change_field('biblio_contributor_data', 'name', 'name', $spec);
+}
+/**
+ * Adds new "biblio_sort_title" column to the biblio table, which is used for title sorting.
+*/
+function biblio_update_7008() {
+ if (!db_field_exists('biblio', 'biblio_sort_title')) {
+ biblio_update_6033();
+ }
+}
+
+/**
+ * Populates the new "biblio_sort_title" column, which is used for title sorting.
+*/
+function biblio_update_7009(&$sandbox) {
+ $sandbox['#finished'] = 0;
+ module_load_include('inc', 'biblio', '/includes/biblio.util');
+
+ if (!isset($sandbox['max'])) {
+ $sandbox['max'] = db_query('SELECT COUNT(DISTINCT vid) FROM {node} n WHERE n.type = :type', array(':type' => 'biblio'))->fetchField();
+ $sandbox['current_vid'] = 0;
+ }
+
+ $nodes = db_select('node', 'n')
+ ->fields('n', array('vid', 'title'))
+ ->condition('vid', $sandbox['current_vid'], '>')
+ ->condition('type', 'biblio')
+ ->range(0, 20)
+ ->orderBy('vid', 'ASC')
+ ->execute();
+
+ foreach ($nodes as $node) {
+ $node->biblio_sort_title = biblio_normalize_title($node->title);
+ db_update('biblio')
+ ->fields(array('biblio_sort_title' => $node->biblio_sort_title))
+ ->condition('vid', $node->vid)
+ ->execute();
+
+ $sandbox['progress']++;
+ $sandbox['current_vid'] = $node->vid;
+ }
+
+ $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']);
+}
+/**
+ * Removes "biblio_inlinemode_in_links" variable
+ */
+function biblio_update_7010() {
+ variable_del('biblio_inlinemode_in_links');
+}
+/**
+ * Add a body field instance
+ */
+function biblio_update_7011() {
+ $content_type = node_type_load('biblio');
+ node_add_body_field($content_type, 'Full text');
+}
+/**
+ * Update biblio_field_type table
+ */
+function biblio_update_7012() {
+
+ // there was a problem with update 7006 and it might no have done anything so lets try again.
+ biblio_update_7006();
+}
+
+function biblio_update_7013() {
+ db_add_index('biblio', 'title_sort', array('biblio_sort_title'));
+ db_add_index('biblio', 'date', array('biblio_date'));
+
+}
+
+/**
+ *
+ * Widen the biblio_date column to 64 characters
+ */
+function biblio_update_7014() {
+ $spec = array(
+ 'type' => 'varchar',
+ 'not null' => FALSE,
+ 'length' => '64',
+ 'description' => '',
+ );
+ db_change_field('biblio', 'biblio_date', 'biblio_date', $spec);
+
+}
+/**
+ *
+ * Add biblio_formats column to biblio table to hold the format information for each text area
+ */
+function biblio_update_7015() {
+ if (!db_field_exists('biblio', 'biblio_formats')) {
+ $spec = array(
+ 'type' => 'blob',
+ 'not null' => FALSE,
+ 'description' => '',
+ 'serialize' => TRUE,
+ );
+ db_add_field('biblio', 'biblio_formats', $spec);
+ }
+}
+/**
+ * Convert textarea fields to text_format
+ */
+function biblio_update_7016() {
+ db_update('biblio_fields')
+ ->fields(array('type' => 'text_format'))
+ ->condition('type', 'textarea')
+ ->execute();
+}
+
+/**
+ * Remove views export handlers in sub-modules (if they still exist)
+ */
+function biblio_update_7017() {
+ $dirs = array('bibtexParse', 'endnote', 'RIS', 'rtf');
+ foreach ($dirs as $dir) {
+ $path = drupal_get_path('module', 'biblio') . '/modules/' . $dir . '/views';
+ if (is_dir($path)) {
+ $message = t('You have an inconsistancy in your installation, the directory: @path, should not exist!', array('@path' => $path));
+ drupal_set_message($message, 'error');
+ }
+ }
+ if (module_exists('views')) { // rebuild the data tables
+ views_invalidate_cache();
+ }
+}
+/**
+ *
+ * Widen the biblio_contributor_data.lastname column to 255 characters
+ */
+function biblio_update_7018() {
+ $spec = array(
+ 'type' => 'varchar',
+ 'length' => '255',
+ 'not null' => TRUE,
+ 'default' => '',
+ 'description' => 'Author last name',
+ );
+ db_change_field('biblio_contributor_data', 'lastname', 'lastname', $spec);
+
+}
+/**
+ *
+ * Change biblio_contributor_data.cid to a signed int
+ */
+
+function biblio_update_7019() {
+
+}
+
+/**
+ *
+ * Change the primary key of the biblio_contributor_data table
+ */
+function biblio_update_7020() {
+ $driver = db_driver();
+ if ($driver == 'mysql') {
+ db_query('ALTER TABLE `biblio_contributor_data` DROP PRIMARY KEY , ADD PRIMARY KEY ( `cid` )');
+ }
+ if ($driver == 'pgsql') {
+ db_drop_primary_key('biblio_contributor_data');
+ db_add_primary_key('biblio_contributor_data', array('cid'));
+ }
+}
+/**
+ *
+ * Add alt_form column to the biblio_contributor_data table
+ */
+function biblio_update_7021() {
+ if (!db_field_exists('biblio_contributor_data', 'alt_form')) {
+ $spec = array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'unsigned' => TRUE,
+ 'description' => 'Alternate form of an author name, this value points to the desired form (cid), this form is kept in the database so that future imports of the same name will not create a new author.',
+ );
+ db_add_field('biblio_contributor_data', 'alt_form', $spec);
+ }
+}
+/**
+ *
+ * Add merge_cid column to the biblio_contributor_data table
+ */
+function biblio_update_7022() {
+ if (!db_field_exists('biblio_contributor', 'merge_cid')) {
+ $spec = array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'unsigned' => TRUE,
+ 'description' => '',
+ );
+ db_add_field('biblio_contributor', 'merge_cid', $spec);
+ }
+}
+
+/**
+ *
+ * Re-apply update 7014 in case the install happened after 7014 was implemented. The main scheme definition was not changed at that time to match the update resulting a schema mismatch.
+ *
+ */
+function biblio_update_7023() {
+ biblio_update_7014();
+}
+/**
+ *
+ * Re-apply update 7022 in case the install happened after 7022 was implemented. The main scheme definition was not changed at that time to match the update resulting a schema mismatch.
+ *
+ */
+
+function biblio_update_7024() {
+ biblio_update_7022();
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/biblio.module
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/biblio.module Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,2259 @@
+auth_category][$row->biblio_type][] = $row->auth_type;
+ }
+ }
+ // fall back to defaults, if no author types are defined for this biblio_type
+ $result = isset($auth_types[$auth_category][$biblio_type])?$auth_types[$auth_category][$biblio_type]:$auth_types[$auth_category][0];
+ return $result;
+}
+function _biblio_get_auth_type($auth_category, $biblio_type) {
+ $result = (array)_biblio_get_auth_types($auth_category, $biblio_type);
+ // return first element of the array
+ return empty($result) ? NULL : current($result);
+}
+
+/**
+ * Translate field titles and hints through the interface translation system, if
+ * the i18nstrings module is enabled.
+ */
+function _biblio_localize_fields(&$fields) {
+ if (function_exists('i18n_string')) {
+ foreach ($fields as $key => $row) {
+ $fields[$key]['title'] = i18n_string("biblio:field:{$row['ftdid']}:title", $fields[$key]['title']);
+ $fields[$key]['hint'] = i18n_string("biblio:field:{$row['ftdid']}:hint", $fields[$key]['hint']);
+ }
+ }
+}
+
+/**
+ * Translate a publication type through the interface translation system, if
+ * the i18nstrings module is enabled.
+ *
+ * @param integer $tid
+ * The biblio publication type identifier.
+ *
+ * @param string $value
+ * The string to translate.
+ *
+ * @param string $field
+ * The publication type field to translate (either 'name' or 'description').
+ *
+ * @return
+ * Translated value.
+ */
+function _biblio_localize_type($tid, $value, $field = 'name') {
+ if (function_exists('i18n_string')) {
+ return i18n_string("biblio:type:$tid:$field", $value);
+ }
+ return $value;
+}
+
+/**
+ * Implementation of hook_locale().
+ */
+function biblio_locale($op = 'groups', $group = NULL) {
+ switch ($op) {
+ case 'groups':
+ return array('biblio' => t('Biblio'));
+
+ case 'refresh':
+ if ($group == 'biblio') {
+ biblio_locale_refresh_fields();
+ biblio_locale_refresh_types();
+ }
+ break;
+ }
+}
+
+/**
+ * Refresh all translatable field strings.
+ *
+ * @param integer $tid
+ * Biblio publication type id whose field strings are to be refreshed. If not
+ * specified, strings for all fields will be refreshed.
+ */
+function biblio_locale_refresh_fields($tid = NULL) {
+ if (function_exists('i18n_string')) {
+ if (isset($tid)) {
+ $result = db_query('SELECT d.* FROM {biblio_field_type} b INNER JOIN {biblio_field_type_data} d ON b.ftdid = d.ftdid WHERE tid = :tid', array(':tid' => $tid));
+ }
+ else {
+ $result = db_query('SELECT * FROM {biblio_field_type_data}');
+ }
+ $options = array('translate' => FALSE, 'update' => TRUE);
+ foreach ($result as $row) {
+ i18n_string("biblio:field:{$row->ftdid}:title", $row->title, $options);
+ i18n_string("biblio:field:{$row->ftdid}:hint", $row->hint, $options);
+ }
+ }
+}
+
+/**
+ * Refresh all publication type strings.
+ *
+ * @param integer $tid
+ * Biblio publication type id whose field strings are to be refreshed. If not
+ * specified, strings for all fields will be refreshed.
+ */
+function biblio_locale_refresh_types($tid = NULL) {
+ if (function_exists('i18n_string')) {
+ if (isset($tid)) {
+ $result = db_query('SELECT * FROM {biblio_types} WHERE tid = :tid', array(':tid' => $tid));
+ }
+ else {
+ $result = db_query('SELECT * FROM {biblio_types} WHERE tid > 0');
+ }
+ $options = array('translate' => FALSE, 'update' => TRUE);
+ foreach ($result as $row ) {
+ i18n_string("biblio:type:{$row->tid}:name", $row->name, $options);
+ i18n_string("biblio:type:{$row->tid}:description", $row->description, $options);
+ }
+ }
+}
+
+function biblio_init() {
+ global $user, $conf;
+ drupal_add_css(drupal_get_path('module', 'biblio') . '/biblio.css');
+
+ if ($user->uid === 0) { // Prevent caching of biblio pages for anonymous users so session variables work and thus filering works
+ $base = variable_get('biblio_base', 'biblio');
+ if (drupal_match_path($_GET['q'], "$base\n$base/*"))
+ $conf['cache'] = FALSE;
+ }
+}
+
+function biblio_cron() {
+ require_once(drupal_get_path('module', 'biblio') .'/includes/biblio.contributors.inc');
+ require_once(drupal_get_path('module', 'biblio') .'/includes/biblio.keywords.inc');
+
+ $interval = variable_get('biblio_orphan_clean_interval', 24*60*60); //defaults to once per day
+
+ if (time() >= variable_get('biblio_orphan_clean_next_execution', 0)) {
+ biblio_delete_orphan_authors();
+ biblio_delete_orphan_keywords();
+ variable_set('biblio_orphan_clean_next_execution', time() + $interval);
+ }
+}
+
+function biblio_theme($existing, $type, $theme, $path) {
+ $path = drupal_get_path('module', 'biblio');
+ return array(
+ 'biblio_alpha_line' => array(
+ 'file' => '/includes/biblio_theme.inc',
+ 'variables' => array(
+ 'type' => 'author',
+ 'current' => NULL,
+ 'path' => NULL),
+ ),
+ 'biblio_admin_keyword_edit_form' => array(
+ 'file' => '/includes/biblio.admin.inc',
+ 'render element' => 'form',
+ ),
+ 'biblio_admin_author_types_form' => array(
+ 'file' => '/includes/biblio.admin.inc',
+ 'render element' => 'form',
+ ),
+ 'biblio_admin_type_mapper_form' => array(
+ 'file' => '/includes/biblio.admin.inc',
+ 'render element' => 'form',
+ ),
+ 'biblio_admin_io_mapper_form'=> array(
+ 'file' => '/includes/biblio.admin.inc',
+ 'render element' => 'form',
+ ),
+ 'biblio_admin_io_mapper_add_form'=> array(
+ 'file' => '/includes/biblio.admin.inc',
+ 'render element' => 'form',
+ ),
+ 'biblio_admin_field_mapper_form' => array(
+ 'file' => '/includes/biblio.admin.inc',
+ 'render element' => 'form',
+ ),
+ 'biblio_admin_types_edit_form' => array(
+ 'file' => '/includes/biblio_theme.inc',
+ 'render element' => 'form',
+ ),
+ 'biblio_admin_types_form' => array(
+ 'file' => '/includes/biblio_theme.inc',
+ 'render element' => 'form',
+ ),
+ 'biblio_field_tab' => array(
+ 'file' => '/includes/biblio_theme.inc',
+ 'render element' => 'form',
+ ),
+ 'biblio_admin_author_edit_form' => array(
+ 'file' => '/includes/biblio_theme.inc',
+ 'render element' => 'form',
+ ),
+ 'biblio_admin_author_edit_merge_table' => array(
+ 'file' => '/includes/biblio_theme.inc',
+ 'render element' => 'form',
+ ),
+ 'biblio_openurl' => array(
+ 'file' => '/includes/biblio_theme.inc',
+ 'variables' => array('openURL'),
+ ),
+ 'biblio_style' => array(
+ 'file' => '/includes/biblio_theme.inc',
+ 'variables' => array(
+ 'node' => NULL,
+ 'style_name' => 'classic',
+ ),
+ ),
+ 'biblio_long' => array(
+ 'file' => '/includes/biblio_theme.inc',
+ 'variables' => array(
+ 'node' => NULL,
+ 'base' => 'biblio',
+ 'style_name' => 'classic'),
+ ),
+ 'biblio_tabular' => array(
+ 'file' => '/includes/biblio_theme.inc',
+ 'variables' => array(
+ 'node' => NULL,
+ 'base' => 'biblio',
+ 'teaser' => FALSE),
+ ),
+ 'biblio_entry' => array(
+ 'file' => '/includes/biblio_theme.inc',
+ 'variables' => array(
+ 'node',
+ 'style_name' => 'classic',
+ ),
+ ),
+ 'biblio_format_authors' => array(
+ 'file' => '/includes/biblio_theme.inc',
+ 'variables' => array(
+ 'contributors' => NULL,
+ 'options' => array(),
+ ),
+ ),
+ 'biblio_page_number' => array(
+ 'file' => '/includes/biblio_theme.inc',
+ 'variables' => array(
+ 'orig_page_info' => NULL,
+ 'page_range_delim' => "-",
+ 'single_page_prefix' => '',
+ 'page_range_prefix' => '',
+ 'total_pages_prefix' => '',
+ 'single_page_suffix' => '',
+ 'page_range_suffix' => '',
+ 'total_pages_suffix' => '',
+ 'shorten_page_range_end' => FALSE),
+ ),
+ 'biblio_author_link' => array(
+ 'file' => '/includes/biblio_theme.inc',
+ 'variables' => array(
+ 'author'),
+ ),
+ 'biblio_filters' => array(
+ 'file' => '/includes/biblio_theme.inc',
+ 'render element' => 'form',
+ ),
+ 'form_filter' => array(
+ 'file' => '/includes/biblio_theme.inc',
+ 'render element' => 'form',
+ ),
+ 'biblio_export_links' => array(
+ 'file' => '/includes/biblio_theme.inc',
+ 'variables' => array(
+ 'node' => NULL,
+ 'filter' => array()),
+ ),
+ 'biblio_download_links' => array(
+ 'file' => '/includes/biblio_theme.inc',
+ 'variables' => array('node'),
+ ),
+ 'google_scholar_link' => array(
+ 'file' => '/includes/biblio_theme.inc',
+ 'variables' => array('node'),
+ ),
+ 'biblio_contributors' => array(
+ 'file' => '/includes/biblio_theme.inc',
+ 'render element' => 'form',
+ ),
+ 'biblio_sort_tabs' => array(
+ 'file' => 'includes/biblio_theme.inc',
+ 'variables' => array(),
+ )
+ );
+}
+
+function biblio_autocomplete($field, $string = '') {
+ $matches = array();
+ switch ($field) {
+ case 'contributor':
+ case 'a':
+ $result = db_query_range("SELECT name FROM {biblio_contributor_data} WHERE LOWER(lastname) LIKE LOWER(:name) OR LOWER(firstname) LIKE LOWER(:firstname) ORDER BY lastname ASC ", 0, 10, array(':name' => $string . '%', ':firstname' => $string . '%'));
+ foreach ($result as $data ) {
+ $matches[$data->name] = check_plain($data->name);
+ }
+ break;
+ case 'biblio_keywords':
+ case 'k':
+ $sep = check_plain(variable_get('biblio_keyword_sep', ','));
+ $sep_pos = strrpos($string, $sep); //find the last separator
+ $start = trim(drupal_substr($string, 0, $sep_pos)); // first part of the string upto the last separator
+ $end_sep = ($sep_pos) ? $sep_pos + 1 :$sep_pos;
+ $end = trim(drupal_substr($string, $end_sep)) . '%'; // part of the string after the last separator
+ $result = db_query_range("SELECT * FROM {biblio_keyword_data} WHERE LOWER(word) LIKE LOWER(:end) ORDER BY word ASC ", 0, 10, array(':end' => $end));
+ foreach ($result as $data) {
+ // now glue the word found onto the end of the original string...
+ $keywords = ($sep_pos) ? $start . ', ' . check_plain($data->word) : check_plain($data->word);
+ $matches[$keywords] = $keywords;
+ }
+ break;
+
+ default:
+ $field = drupal_strtolower($field);
+ $string = '%' . drupal_strtolower($string) . '%';
+ $query = db_select('biblio', 'b')
+ ->fields('b', array($field))
+ ->condition($field, $string, 'LIKE')
+ ->orderBy($field, 'ASC')
+ ->range(0, 10);
+ $result = $query->execute();
+
+ foreach ($result as $data) {
+ $matches[$data->$field] = check_plain($data->$field);
+ }
+ }
+ print drupal_json_encode($matches);
+ exit();
+}
+
+function biblio_help_page() {
+ $base = variable_get('biblio_base', 'biblio');
+ $text = "
" . t('General:') . "
";
+ $text .= "
" . t('By default, the !url page will list all of the entries in the database sorted by Year in descending order. If you wish to sort by "Title" or "Type", you may do so by clicking on the appropriate links at the top of the page. To reverse the sort order, simply click the link a second time.', array(
+ '!url' => l('',
+ $base
+ ))) . "
";
+ $text .= "
" . t('Filtering Search Results:') . "
";
+ $text .= "
" . t('If you wish to filter the results, click on the "Filter" tab at the top of the page. To add a filter, click the radio button to the left of the filter type you wish to apply, then select the filter criteria from the drop down list on the right, then click the filter button.') . "
";
+ $text .= "
" . t('It is possible to create complex filters by returning to the Filter tab and adding additional filters. Simply follow the steps outlined above and press the "Refine" button.') . "
";
+ $text .= "
" . t('All filters can be removed by clicking the Clear All Filters link at the top of the result page, or on the Filter tab they can be removed one at a time using the Undo button, or you can remove them all using the Clear All button.') . "
";
+ $text .= "
" . t('You may also construct URLs which filter. For example, /biblio/year/2005 will show all of the entries for 2005. /biblio/year/2005/author/smith will show all of entries from 2005 for smith.') . "
";
+ $text .= "
" . t('Exporting Search Results:') . "
";
+ $text .= "
" . t('Assuming this option has been enabled by the administrator, you can export search results directly into EndNote. The link at the top of the result page will export all of the search results, and the links on individual entries will export the information related to that single entry.') . "
";
+ $text .= "
" . t('The information is exported in EndNote "Tagged" format similar to this...') . "
" . t('
+ %0 Book
+ %A John Smith
+ %D 1959
+ %T The Works of John Smith
+ ...') . '
';
+ $text .= "
" . t('Clicking on one of the export links should cause your browser to ask you whether you want to Open, or Save To Disk, the file endnote.enw. If you choose to open it, Endnote should start and ask you which library you would like store the results in. Alternatively, you can save the file to disk and manually import it into EndNote.') . "
#584616Import: Invalid argument supplied for foreach () in biblio.import.export.inc
+
#592750Error when Block Settings is ordered by Year Published following upgrade from 6.x-1.6 to 6.x-1.7
+
+
+
6.x-1.7
+New features...
+
+
New settings available in "Styling" to allow admin to change the text that is displayed when there is no year of publication available (9999) or the "In Press" text (9998)
+
Reworked the SQL query used for the list display to improve speed at which the list display is sorted. This is especially noticable on large datasets.
+
Reworked export functions such that the data is streamed to the client node by node thus reducing the memory footprint required to export large datasets.
+
Thanks to Filipe Rocha for the Portuguese translation file (biblio.pt-pt.po)
+
Added links to file attachments in the Tagged, bibtex and EndNote 8 export file formats
+
Thanks to Turczi Attil for the Hungarian translation file (biblio.hu.po)
+
+Bugs Fixed...
+
+
fixed potential XSS vulnerability
+
#585332 fixed Can't use the print module in the biblio list page
+
disabled default views so they do not over ride some of the built in paths
+
#570640 fixed author ordering problem when "More Authors" are added on the input form
+
#561722 fixed Order Vocabularies by Weight on Import Screen(s)
+
#561800 fixed Incorrectly placed curly bracket } around table name in db_query
+
#551362 fixed problem with author and keyword edit links when base url has more than one level
+
#502140 fixed typo which prevented removal of BibTex braces in the title with Views display
+
#536062 fixed bug which would overwrite page title if the page had a "View" containing a biblio node
+
fixed bug which prevented the "Alpha" line from being displayed on the "Authors" page when there were no authors to display
+
+
+
6.x-1.6
+New features...
+
+
Added configurable "type" mapping #520828. This feature allows mapping between various input file format publication types and Biblio publication types.
+
Added a per-user setting for OpenURL information #528930
+
EndNote XML files are now formated in the latest XML format by default, good for versions 8 and newer of EndNote.
+
Added new setting in the OpenURL section to set the Site ID (sid) of the OpenURL link
+
+Bugs Fixed...
+
+
fixed potential XSS vulnerability
+
#514882 fixed MLA style looks for incorrect year field
+
#------ fixed incorrect link in keyword edit page
+
#513930fixed Missing '</ul>' tag in biblio_theme.inc, and also refactored the entire link building process so that the links on the "node" display are built by the same code as the links on the "bibliographic" display
+
#504702fixed The first [bib] causes a line break with hovertips enabled
+
#501932fixed warning generated when new "type" is created and no fields are set "visible", also change the default for new types so that ALL fields will be visible rather than invisible.
+
#497594removed the manditory requirement for the year of publication to be supplied
+
#502140fixed Views citation handler does not remove BibTeX brackets
#477438fixed issue with CrossRef XML parser where it would truncate data with embedded HTML tags, also added the retention of font style (bold, italic, underline, subscript, superscript) information.
+
#477438fixed issue with EndNote XML parser where it would truncate data with embedded styles, also added the retention of font style information.
+
#------ fixed issue with author formatting which could cause extra periods before and after initials
+
#------ removed some debug code which was left in the Crossref xml parser by mistake
+
#492214by scottrigby: biblio: authors views field sql error
+
#486462 Fixed: Arrow images not showing when Drupal is not installed at DocumentRoot
+
#486790 "Edit" links on admin/settings/biblio/author/list are broken
Added Views handlers for sorting, filtering and arguments on most fields.
+
Added new settings in the ISI Web of Knowledge section on the admin/settings/biblio page. Turning this on automatically converts EndNote "Go to ISI" links to valid ISI search links. (ISI subscription required)
+
Added new settings in the links section on the admin/settings/biblio page. You choose to carry "inline" mode through to all subsequent links. Inline mode is used primarily by people accessing biblio data from custom code, so the average user will not need this.
+
Added new settings in the links section on the admin/settings/biblio page. You can now toggle the export links on/off individually as well as the Google Scholar link
+
Added links from each entry to Google Scholar. Following the link does a Google Scholar search using the title and first authors name.
+
Added a new feature (and setting to turn it on/off) which will allow you to retain BibTex protected capitalization braces in title strings, they will be stripped out on display, but will still be in place when exported in BibTex format.
+
Added a new permission called "access biblio content" which will allow you to restrict access to any of the biblio pages (biblio, biblio/authors, biblio/keywords etc.) A user MUST have this permission to see anything from the biblio module!
+
Added a section to the user profile page to allow entry of CrossRef login information used for DOI lookup
+
Added a new option when selecting taxonomy terms from a vocabulary, you can now choose to copy them to the biblio keyword database or not. There is a check box on the input and import forms and there is also a new check box in the "Keywords" section of the admin/settings page which sets the default for this option.
+
Added a setting in the links section to toggle the hyperlinks on the author names.
Added "DOI Lookup" option on the input form. Entering a valid DOI name (number) here will query crossref.org and poplulate the input form with all the data it gets. You are then presented with the populated form to make further additions/changes prior to saving it to the database.
+
Added "BibTex cut and paste" option to the input form. Pasting a valid bibTex string into the box will populate the input form with the data and similar to the DOI lookup above, allows you to preview and make changes prior to saving it in the database.
+
Added a new user permission called "edit biblio authors" which allows the user to edit biblio author information but not other biblio settings, unlike "administer biblio" which gives them the right to edit all biblio settings.
+
Changed "Views" integration such that Blblio is no longer a "Base" type of view. You should now use the "Node" view type to create a view containing biblio information.
+
Added an option to toggle sort links between text and tab type display.
+
Changed Keyword/Taxonomy freetag handling... The Taxonomy freetag input box is no longer displayed on the input form. All keywords/taxonomy freetags should be entered into the biblio Keywords input box and (if required) the taxonomy freetags will be updated when the keywords are saved. This keeps the keywords and freetags in sync and avoids the confustion of having two input boxes (one for keywords and one for freetags).
Added option to automatically delete authors "orphaned" by the update or deletion of an entry
+
User selectable bibliographic styles, authorized users can choose a style other than the system default on their "edit user" page
+
Author "Link" allows 2 or more authors to be linked together (intended to deal with name changes due to marriage, but could be used for other purposes)
New bibliographic output sytles (AMA, Chicago, MLA, Vancouver)
+
Authors page (biblio/authors) which displays all authors in the database linked to publication lists filtered by that author. ("edit" links are provided for privileged users)
+
Author edit/merge form (merge allows you to merge all instances of the same author which have been entered slightly
+differently. i.e. Smith, J and John Smith are the same person so you merge the two entries into one.)
+
Orphaned author page(admin/settings/biblio/author/orphans), allows you to remove authors who are not associated with any publications from the database
+
Keywords page (biblio/keywords) which displays all keywords in the database linked to publication list filtered by that keyword. ("edit" links are provided for privileged users)
+
Orphaned keyword page (admin/settings/biblio/keyword/orphans) allows you to find and remove orphaned keywords (keywords which are no longer associated with any publications)
+
added 'tabledrag' to admin/settings/biblio/defaults and admin/settings/biblio/types/edit/xxx which allows you to change the order of the fields on the input form by just dragging them to the desired location
';
+ $disabled = FALSE;
+ }
+ $form['footnotes']['biblio_footnotes_integration'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Integration with the footnotes module') . $additional_text,
+ '#disabled' => $disabled,
+ '#return_value' => 1,
+ '#default_value' => variable_get('biblio_footnotes_integration', 0),
+ '#description' => t('This will convert <bib> tags into <fn> tags. This will cause intermingled <bib> and <fn> tags to be sequentially numbered. For this to work, you must put the <bib> filter ahead of the <fn> filter in the filter chain. If this option is not set, <bib> and <fn> tags will be handled separately.')
+ );
+ $form['isi_wok'] = array(
+ '#type' => 'fieldset',
+ '#collapsible' => TRUE,
+ '#collapsed' => TRUE,
+ '#title' => t('ISI Web of Knowledge'),
+ '#description' => '',
+ '#group' => 'biblio_settings',
+ '#weight' => 60,
+ );
+ $form['isi_wok']['biblio_fix_isi_links'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Automatically replace "Go to ISI" links with the URL below'),
+ '#return_value' => 1,
+ '#default_value' => variable_get('biblio_fix_isi_links', 0),
+ '#description' => t('This option automatically replaces any fake "Go to ISI" links with the supplied URL to ISI Web of Knowledge. Note a subscription with ISI is required for these links to function.')
+ );
+ $form['isi_wok']['biblio_isi_url'] = array(
+ '#type' => 'textfield',
+ '#title' => t('ISI Web of Knowledge URL'),
+ '#size' => 128,
+ '#maxlength' => 512,
+ '#default_value' => variable_get('biblio_isi_url', 'http://apps.isiknowledge.com/InboundService.do?Func=Frame&product=WOS&action=retrieve&SrcApp=EndNote&Init=Yes&SrcAuth=ResearchSoft&mode=FullRecord&UT='),
+ '#description' => t('Enter the URL which will replace the "Go to ISI" fake links imported from EndNote')
+ );
+ $form['keywords'] = array(
+ '#type' => 'fieldset',
+ '#collapsible' => TRUE,
+ '#collapsed' => TRUE,
+ '#title' => t('Keywords'),
+ '#description' => '',
+ '#group' => 'biblio_settings',
+ '#weight' => 70,
+ );
+ $form['keywords']['biblio_keyword_sep'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Keyword separator'),
+ '#size' => 2,
+ '#default_value' => variable_get('biblio_keyword_sep', ','),
+ '#description' => t('Enter the character which will be used to separate multiple keywords in the keyword field')
+ );
+ $form['keywords']['biblio_keyword_orphan_autoclean'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Automatically remove orphaned keywords'),
+ '#return_value' => 1,
+ '#default_value' => variable_get('biblio_keyword_orphan_autoclean', 1),
+ '#description' => t('This option automatically deletes keywords which are no longer associated with any publications (primarily due to the due to the removal of a publication or editing a keyword).')
+ );
+ $taxo_mesg = '
';
+ $search_disabled = FALSE;
+ }
+ $form['search'] = array(
+ '#type' => 'fieldset',
+ '#collapsible' => TRUE,
+ '#collapsed' => TRUE,
+ '#description' => $search_text,
+ '#title' => t('Search'),
+ '#group' => 'biblio_settings',
+ '#weight' => 110,
+ );
+ $form['search']['biblio_search'] = array(
+ '#type' => 'checkbox',
+ '#disabled' => $search_disabled,
+ '#title' => t('Enable a search box on the biblio page.'),
+ '#return_value' => 1,
+ '#default_value' => variable_get('biblio_search', 0),
+ '#description' => t('Shows a search box on the biblio page that returns drupal search results in the biblio style.')
+ );
+ $form['search']['biblio_search_button_text'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Search button text'),
+ '#disabled' => $search_disabled,
+ '#size' => 95,
+ '#default_value' => variable_get('biblio_search_button_text', t('Biblio search')),
+ '#description' => t('This allows you to customize the text on the search button, it defaults to "Biblio search".')
+ );
+ $form['search']['biblio_index'] = array(
+ '#type' => 'checkbox',
+ '#disabled' => $search_disabled,
+ '#title' => t('Re-/Index a biblio node when creating or updating.'),
+ '#return_value' => 1,
+ '#default_value' => variable_get('biblio_index', 0),
+ '#description' => t('A biblio node must be indexed for the drupal search to know its content. You need to check this option if you want to search for a biblio node that you just created or updated. Otherwise you must wait for the cron job to reindex nodes.')
+ );
+ $form['sort'] = array(
+ '#type' => 'fieldset',
+ '#collapsible' => TRUE,
+ '#collapsed' => TRUE,
+ '#title' => t('Sorting'),
+ '#description' => t('You can set the default sorting and ordering for the /biblio page here.'),
+ '#group' => 'biblio_settings',
+ '#weight' => 120,
+ );
+ $form['sort']['biblio_sort'] = array(
+ '#type' => 'select',
+ '#title' => t('Sort by'),
+ '#default_value' => variable_get('biblio_sort', 'year'),
+ '#options' => array(
+ 'author' => t('Author'),
+ 'keyword' => t('Keyword'),
+ 'title' => t('Title'),
+ 'type' => t('Type'),
+ 'year' => t('Year')
+ ),
+ '#description' => t('This is the initial default sort.'),
+ );
+ $stop_words = 'a,an,is,on,the';
+ $form['sort']['biblio_stop_words'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Words to remove from the beginning of titles prior to sorting'),
+ '#size' => 60,
+ '#default_value' => variable_get('biblio_stop_words', $stop_words),
+ '#description' => t('A comma separated list of (case insensitive) words to strip from the title for sorting purposes. NOTE: quotation and punctuation are stripped automatically.')
+ );
+
+ $form['sort']['biblio_sort_tabs'] = array(
+ '#type' => 'checkboxes',
+ '#title' => t('Show sort links'),
+ '#default_value' => variable_get('biblio_sort_tabs', array('author', 'title', 'type', 'year')),
+ '#options' => array(
+ 'author' => t('Author'),
+ 'keyword' => t('Keyword (Warning: sorting by keyword may produce many duplicates due to the fact that an entry is listed for each keyword attached to it.)'),
+ 'title' => t('Title'),
+ 'type' => t('Type'),
+ 'year' => t('Year')
+ ),
+ '#description' => t('You turn the sorting links at the top of the /biblio page here.')
+ );
+ $form['sort']['biblio_sort_tabs_style'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Show sort links as "tabs"'),
+ '#default_value' => variable_get('biblio_sort_tabs_style', 0),
+ '#return_value' => 1,
+ '#description' => t('This changes the sort links from text links to tabs')
+ );
+ $form['sort']['biblio_order'] = array(
+ '#type' => 'radios',
+ '#title' => t('Order'),
+ '#default_value' => variable_get('biblio_order', 'DESC'),
+ '#options' => array(
+ 'DESC' => t('Descending'),
+ 'ASC' => t('Ascending')
+ )
+ );
+ $form['style'] = array(
+ '#type' => 'fieldset',
+ '#collapsible' => TRUE,
+ '#collapsed' => TRUE,
+ '#title' => t('Styling'),
+ '#description' => t('You can set the default style for the /biblio page here.'),
+ '#group' => 'biblio_settings',
+ '#weight' => 130,
+ );
+ $form['style']['biblio_no_year_text'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Text to display if no year of publication is available'),
+ '#size' => 95,
+ '#default_value' => variable_get('biblio_no_year_text', t('Submitted')),
+ '#description' => t('The text that is displayed when no date of publication is given or it is deliberately set to 9999, it defaults to "Submitted".')
+ );
+ $form['style']['biblio_inpress_year_text'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Text to display if year of publication is set to 9998'),
+ '#size' => 95,
+ '#default_value' => variable_get('biblio_inpress_year_text', t('In Press')),
+ '#description' => t('The text that is displayed when the date of publication is deliberately set to 9998, it defaults to "In Press".')
+ );
+ if (module_exists('biblio_citeproc')) {
+ $form['style']['biblio_citeproc_style'] = array(
+ '#type' => 'select',
+ '#title' => t('Style'),
+ '#default_value' => variable_get('biblio_citeproc_style', 'ieee.csl'),
+ '#options' => biblio_get_styles(),
+ '#description' => t('Set the bibliographic style of the "list" view.')
+ );
+ }
+ else {
+ $form['style']['biblio_style'] = array(
+ '#type' => 'select',
+ '#title' => t('Style'),
+ '#default_value' => variable_get('biblio_style', 'cse'),
+ '#options' => biblio_get_styles(),
+ '#description' => t('Set the bibliographic style of the "list" view.')
+ );
+ }
+ $form['style']['biblio_node_layout'] = array(
+ '#type' => 'radios',
+ '#title' => t('Node Layout'),
+ '#default_value' => variable_get('biblio_node_layout', 'tabular'),
+ '#options' => array(
+ 'orig' => t('Original'),
+ 'ft' => t('Only Fulltext if available'),
+ 'tabular' => t('Tabular'),
+ 'cite' => t('Bibliographic style choosen above')
+ ),
+ '#description' => t('This alters the layout of the "node" (full) view.')
+ );
+ $form['style']['biblio_annotations'] = array(
+ '#type' => 'select',
+ '#title' => t('Annotations'),
+ '#default_value' => variable_get('biblio_annotations', 'none'),
+ '#options' => array(
+ 'none' => t('none'),
+ 'biblio_notes' => t('notes'),
+ 'biblio_custom1' => t('custom1'),
+ 'biblio_custom2' => t('custom2'),
+ 'biblio_custom3' => t('custom3'),
+ 'biblio_custom4' => t('custom4'),
+ 'biblio_custom5' => t('custom5'),
+ 'biblio_custom6' => t('custom6'),
+ 'biblio_custom7' => t('custom7')
+ ),
+ '#description' => t('Select a field from which an annotation will be displayed below biblo entry in "short" listings'),
+ '#multiple' => FALSE,
+ '#size' => 0
+ );
+ $form['syndication'] = array(
+ '#type' => 'fieldset',
+ '#collapsible' => TRUE,
+ '#collapsed' => TRUE,
+ '#title' => t('Syndication'),
+ '#description' => t('You can set the RSS defaults here.'),
+ '#group' => 'biblio_settings',
+ '#weight' => 140,
+ );
+ $form['syndication']['biblio_rss'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Allow RSS feeds of new biblio entries'),
+ '#return_value' => 1,
+ '#default_value' => variable_get('biblio_rss', 0),
+ '#description' => t('This will create an rss feed of the 10 most recent biblio entries. It will be available at /biblio/rss.xml')
+ );
+ $form['syndication']['biblio_rss_number_of_entries'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Number of items in the RSS feed.'),
+ '#default_value' => variable_get('biblio_rss_number_of_entries', 10),
+ '#size' => 6,
+ '#maxlength' => 6,
+ '#description' => t('Limits the number of items in the /biblio/rss.xml feed to this number.')
+ );
+
+ $form = system_settings_form($form);
+ $form['#submit'][] = 'biblio_admin_settings_form_submit';
+ // our submit handler is added after the call to system settings form so that it gets
+ // called after system_settings_form_submit, and thus the variables have been stored already
+ // and the menu will be rebuilt correctly.
+ return ($form);
+}
+/**
+ * Form handler for biblio_admin_settings
+ *
+ */
+function biblio_admin_settings_form_submit($form, &$form_state) {
+// if ($form_state['values']['biblio_keyword_freetagging'] && $form_state['values']['biblio_keyword_vocabulary']) {
+// if ($vocabulary = taxonomy_vocabulary_load(variable_get('biblio_keyword_vocabulary', 0))) {
+// $vocabulary = (array) $vocabulary;
+// $vocabulary['nodes']['biblio'] = 1;
+// taxonomy_save_vocabulary($vocabulary);
+// }
+// }
+
+ if (($form['#biblio_base'] != $form_state['values']['biblio_base']) ||
+ ($form['biblio_profile']['#biblio_show_profile'] != $form_state['values']['biblio_show_profile']) ||
+ ($form['biblio_profile']['#biblio_my_pubs_menu'] != $form_state['values']['biblio_my_pubs_menu']) )
+ {
+ menu_rebuild();
+ }
+}
+/**
+ * Form constructor for the Publication type edit form.
+ *
+ * @param int $tid
+ * The publication type.
+ * @return array $form
+ */
+function biblio_admin_types_edit_form($form, &$form_state, $tid = 0) {
+ // $form['#theme'] = 'biblio_admin_types_edit_form';
+ // $form['#tree'] = TRUE;
+ $form['#cache'] = TRUE;
+ $tid = (isset($form_state['pub_type']) ? $form_state['pub_type'] : (int)$tid);
+ $msg = '
' . t('On this page you can set type specific "Titles" and "Hints" which will display on the input form.');
+ if ($tid) {
+ $msg .= ' ' . t('Checking the "Visible" box will add the field to the input form, checking "Required" will force the user to supply a value for this field and the weight value changes the order which it is rendered on the form with smaller values floating to the top of the form.
+
Fields which are grayed out on this page have been set to "common" on the !linktobiblioadmin page.
', array('!linktobiblioadmin' => l("admin/config/content/biblio/fields", "admin/config/content/biblio/fields")));
+
+ }
+ else {
+ $msg .= ' ' . t('Checking the "Common" box will add the field to all the different publication types. Checking "Required" will force the user to supply a value for the field, checking "Autocomplete" will enable AJAX type auto complete look up for the field when the user is entering data and the weight value changes the order which it is rendered on the form with smaller values floating to the top of the form.');
+ }
+ $msg .= t('Finally, for each author field you can choose a set of author roles. Assigning different roles to authors within the same field, e.g. primary and secondary authors within the authors field, allows to theme them differently.');
+ $msg .= '
';
+
+ $form['#redirect'] = 'admin/config/content/biblio/fields';
+ $form['help'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Help'),
+ '#collapsible' => TRUE,
+ '#collapsed' => TRUE
+ );
+ $form['help']['message'] = array(
+ '#markup' => $msg
+ );
+ // get author types
+ $result = db_query("SELECT * FROM {biblio_contributor_type_data} b");
+ $contrib_options = array();
+ foreach ($result as $contrib_type) {
+ $contrib_options[$contrib_type->auth_type] = $contrib_type->title;
+ $contrib_hints[$contrib_type->auth_type] = $contrib_type->hint;
+ }
+
+ // first get all of the field info
+ if ($tid) {
+ $result = db_query("SELECT bf.*, bftd.*, bft.vtab, bft.common, bft.visible, bft.autocomplete, bft.weight, bft.required, bt.name AS type_name
+ FROM {biblio_fields} AS bf
+ INNER JOIN {biblio_field_type} AS bft ON bft.fid=bf.fid
+ INNER JOIN {biblio_field_type_data} AS bftd ON bftd.ftdid=bft.ftdid
+ INNER JOIN {biblio_types} AS bt ON bt.tid=bft.tid
+ WHERE bft.tid=:tid", array(':tid' => $tid), array('fetch' => PDO::FETCH_ASSOC));
+ }
+ else {
+ $result = db_query("SELECT bf.*, bftd.*, bft.vtab, bft.common, bft.visible, bft.autocomplete, bft.weight, bft.required
+ FROM {biblio_fields} AS bf
+ INNER JOIN {biblio_field_type} AS bft ON bft.fid=bf.fid
+ INNER JOIN {biblio_field_type_data} AS bftd ON bftd.ftdid=bft.ftdid
+ WHERE bft.tid=:tid", array(':tid' => $tid), array('fetch' => PDO::FETCH_ASSOC));
+ }
+
+ foreach ($result as $row) {
+ $fields[$row['fid']] = $row;
+ }
+
+ $types = db_query("SELECT * from {biblio_types} WHERE visible=1 ORDER BY name ASC");
+ $types_options[0] = t('Common');
+ foreach ($types as $type) {
+ $types_options[$type->tid] = $type->name;
+ }
+
+ $form['pub_type'] = array(
+ '#title' => t('Publication type'),
+ '#type' => 'select',
+ '#options' => $types_options,
+ '#attributes' => array('onchange' => 'document.getElementById(\'edit-change-type\').click()'),
+ '#default_value' => $tid,
+ );
+
+ $no_js = (!isset($_COOKIE['has_js']) || empty($_COOKIE['has_js']));
+
+ $form['change_type'] = array(
+ '#type' => 'submit',
+ '#value' => t('Change Publication Type'),
+ '#weight' => -10,
+ '#prefix' => $no_js ? '' : '
';
+ }
+
+ return $name;
+}
+
+function _biblio_author_edit_links($author) {
+ static $path = '';
+ $destination = drupal_get_destination();
+ if (empty($path)) {
+ $path = (ord(substr($_GET['q'], -1)) > 97) ? $_GET['q'] . "/" : substr($_GET['q'], 0, -1);
+ $path = (strpos($path, 'list/')) ? str_replace('list/', '', $path) : $path;
+ }
+ return l(' [' . t('edit') . ']', $path . $author->cid . "/edit" );
+}
+
+function biblio_keyword_page() {
+ $uri = drupal_parse_url(request_uri());
+// $uri['path'] = variable_get('biblio_base', 'biblio');
+ $filter = isset($uri['query']['f']['keyword']) ? $uri['query']['f']['keyword'] : '';
+ $keywords = _biblio_get_keywords($filter);
+ return _biblio_format_keyword_page($uri, $filter, $keywords);
+}
+
+function _biblio_get_keywords($filter = NULL) {
+ global $user;
+ $keywords = array();
+ $where = array();
+ $where_clause = '';
+ if ($filter) {
+ $filter = strtoupper($filter);
+ $where[] = "UPPER(SUBSTRING(word,1,1)) = :filter ";
+ $header_ext = t(' (which start with the letter "@letter") ', array('@letter' => $filter ));
+ }
+ else {
+ $query_ext = NULL;
+ $header_ext = NULL;
+ }
+
+ if ($user->uid != 1 ) {
+ $where[] = 'n.status = 1 ';
+ }//show only published entries to everyone except admin
+
+ if (count($where)) {
+ $where_clause = count($where) > 1 ? 'WHERE (' . implode(') AND (', $where) . ')': 'WHERE ' . $where[0];
+ }
+
+ $db_result = db_query('SELECT bkd.kid, bkd.word, COUNT(*) AS cnt
+ FROM {biblio_keyword} bk
+ LEFT JOIN {biblio_keyword_data} bkd ON bkd.kid = bk.kid
+ INNER JOIN {node} n ON n.vid = bk.vid
+ '. $where_clause . '
+ GROUP BY bkd.kid, bkd.word
+ ORDER BY word ASC', array(':filter' => $filter));
+
+ foreach ($db_result as $keyword) {
+ $keywords[] = $keyword;
+ }
+ return $keywords;
+}
+
+function _biblio_format_keyword_page($uri, $filter, $keywords) {
+ $rows[] = array(array('data' => theme('biblio_alpha_line', array('type' => 'keywords', 'current' => $filter, 'path' => $uri['path'])), 'colspan' => 3));
+ for ($i=0; $i < count($keywords); $i+=3) {
+ $rows[] = array( array('data' => _biblio_format_keyword($uri, $keywords[$i]) ),
+ array('data' => isset($keywords[$i+1]) ? _biblio_format_keyword($uri, $keywords[$i+1]) : '' ),
+ array('data' => isset($keywords[$i+2]) ? _biblio_format_keyword($uri, $keywords[$i+2]) : '' ));
+ }
+ //$header = array(array('data' => t('There are a total of @count keywords !header_ext in the database',array('@count' => count($keywords), '!header_ext' => $header_ext)), 'align' =>'center', 'colspan' => 3));
+ $output = theme('table', array('rows' => $rows));
+ return $output;
+}
+function _biblio_format_keyword($uri, $keyword) {
+ $base = variable_get('biblio_base', 'biblio');
+ $uri['path'] = $base;
+ $uri['query']['f']['keyword'] = $keyword->kid;
+ $format = l(trim($keyword->word), $base, $uri);
+ $format .= ' (' . $keyword->cnt . ') ' ;
+ $destination = drupal_get_destination();
+ $path = (ord(substr($_GET['q'], -1)) > 97) ? $_GET['q'] . "/" : substr($_GET['q'], 0, -1);
+ $edit_link = ' [' . l(t('edit'), $path . $keyword->kid . "/edit", array('query' => $destination)) . '] ';
+ $format .= (user_access('administer biblio')) ? $edit_link : '';
+
+ return $format;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/includes/biblio.search.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/includes/biblio.search.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,303 @@
+ 'Content',
+ 'path' => 'node',
+ 'conditions_callback' => 'sample_search_conditions_callback',
+ );
+}
+
+function sample_search_conditions_callback($keys) {
+ $conditions = array();
+
+ if (!empty($_REQUEST['keys'])) {
+ $conditions['keys'] = $_REQUEST['keys'];
+ }
+ if (!empty($_REQUEST['sample_search_keys'])) {
+ $conditions['sample_search_keys'] = $_REQUEST['sample_search_keys'];
+ }
+ if ($force_keys = variable_get('sample_search_force_keywords', '')) {
+ $conditions['sample_search_force_keywords'] = $force_keys;
+ }
+ return $conditions;
+}
+
+function _biblio_search_access() {
+ return user_access('access content');
+}
+
+/**
+ * Take action when the search index is going to be rebuilt.
+ *
+ * Modules that use hook_update_index() should update their indexing
+ * bookkeeping so that it starts from scratch the next time
+ * hook_update_index() is called.
+ *
+ * @ingroup search
+ */
+function _biblio_search_reset() {
+ db_update('search_dataset')
+ ->fields(array('reindex' => REQUEST_TIME))
+ ->condition('type', 'node')
+ ->execute();
+}
+
+/**
+ * Report the status of indexing.
+ *
+ * @return
+ * An associative array with the key-value pairs:
+ * - 'remaining': The number of items left to index.
+ * - 'total': The total number of items to index.
+ *
+ * @ingroup search
+ */
+function _biblio_search_status() {
+ $total = db_query('SELECT COUNT(*) FROM {node} WHERE status = 1')->fetchField();
+ $remaining = db_query("SELECT COUNT(*) FROM {node} n LEFT JOIN {search_dataset} d ON d.type = 'node' AND d.sid = n.nid WHERE n.status = 1 AND d.sid IS NULL OR d.reindex <> 0")->fetchField();
+ return array('remaining' => $remaining, 'total' => $total);
+}
+
+/**
+ * Add elements to the search settings form.
+ *
+ * @return
+ * Form array for the Search settings page at admin/config/search/settings.
+ *
+ * @ingroup search
+ */
+function _biblio_search_admin() {
+ // Output form for defining rank factor weights.
+ $form['content_ranking'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Content ranking'),
+ );
+ $form['content_ranking']['#theme'] = 'node_search_admin';
+ $form['content_ranking']['info'] = array(
+ '#value' => '' . t('The following numbers control which properties the content search should favor when ordering the results. Higher numbers mean more influence, zero means the property is ignored. Changing these numbers does not require the search index to be rebuilt. Changes take effect immediately.') . ''
+ );
+
+ // Note: reversed to reflect that higher number = higher ranking.
+ $options = drupal_map_assoc(range(0, 10));
+ foreach (module_invoke_all('ranking') as $var => $values) {
+ $form['content_ranking']['factors']['node_rank_' . $var] = array(
+ '#title' => $values['title'],
+ '#type' => 'select',
+ '#options' => $options,
+ '#default_value' => variable_get('node_rank_' . $var, 0),
+ );
+ }
+ return $form;
+}
+
+/**
+ * Execute a search for a set of key words.
+ *
+ * Use database API with the 'PagerDefault' query extension to perform your
+ * search.
+ *
+ * If your module uses hook_update_index() and search_index() to index its
+ * items, use table 'search_index' aliased to 'i' as the main table in your
+ * query, with the 'SearchQuery' extension. You can join to your module's table
+ * using the 'i.sid' field, which will contain the $sid values you provided to
+ * search_index(). Add the main keywords to the query by using method
+ * searchExpression(). The functions search_expression_extract() and
+ * search_expression_insert() may also be helpful for adding custom search
+ * parameters to the search expression.
+ *
+ * See node_search_execute() for an example of a module that uses the search
+ * index, and user_search_execute() for an example that doesn't ues the search
+ * index.
+ *
+ * @param $keys
+ * The search keywords as entered by the user.
+ * @param $conditions
+ * An optional array of additional conditions, such as filters.
+ *
+ * @return
+ * An array of search results. To use the default search result
+ * display, each item should have the following keys':
+ * - 'link': Required. The URL of the found item.
+ * - 'type': The type of item (such as the content type).
+ * - 'title': Required. The name of the item.
+ * - 'user': The author of the item.
+ * - 'date': A timestamp when the item was last modified.
+ * - 'extra': An array of optional extra information items.
+ * - 'snippet': An excerpt or preview to show with the result (can be
+ * generated with search_excerpt()).
+ * - 'language': Language code for the item (usually two characters).
+ *
+ * @ingroup search
+ */
+function _biblio_search_execute($keys = NULL, $conditions = NULL) {
+ // Build matching conditions
+ $query = db_select('search_index', 'i', array('target' => 'slave'))->extend('SearchQuery')->extend('PagerDefault');
+ $query->join('node', 'n', 'n.nid = i.sid');
+ $query
+ ->condition('n.status', 1)
+ ->addTag('node_access')
+ ->searchExpression($keys, 'node');
+
+ // Insert special keywords.
+ $query->setOption('type', 'n.type');
+ $query->setOption('language', 'n.language');
+ if ($query->setOption('term', 'ti.tid')) {
+ $query->join('taxonomy_index', 'ti', 'n.nid = ti.nid');
+ }
+ // Only continue if the first pass query matches.
+ if (!$query->executeFirstPass()) {
+ return array();
+ }
+
+ // Add the ranking expressions.
+ _node_rankings($query);
+
+ // Load results.
+ $find = $query
+ ->limit(10)
+ ->execute();
+ $results = array();
+ foreach ($find as $item) {
+ // Build the node body.
+ $node = node_load($item->sid);
+ node_build_content($node, 'search_result');
+ $node->body = drupal_render($node->content);
+
+ // Fetch comments for snippet.
+ $node->rendered .= ' ' . module_invoke('comment', 'node_update_index', $node);
+ // Fetch terms for snippet.
+ $node->rendered .= ' ' . module_invoke('taxonomy', 'node_update_index', $node);
+
+ $extra = module_invoke_all('node_search_result', $node);
+
+ $results[] = array(
+ 'link' => url('node/' . $item->sid, array('absolute' => TRUE)),
+ 'type' => check_plain(node_type_get_name($node)),
+ 'title' => $node->title,
+ 'user' => theme('username', array('account' => $node)),
+ 'date' => $node->changed,
+ 'node' => $node,
+ 'extra' => $extra,
+ 'score' => $item->calculated_score,
+ 'snippet' => search_excerpt($keys, $node->body),
+ );
+ }
+ return $results;
+}
+
+/**
+ * Override the rendering of search results.
+ *
+ * A module that implements hook_search_info() to define a type of search
+ * may implement this hook in order to override the default theming of
+ * its search results, which is otherwise themed using theme('search_results').
+ *
+ * Note that by default, theme('search_results') and theme('search_result')
+ * work together to create an ordered list (OL). So your hook_search_page()
+ * implementation should probably do this as well.
+ *
+ * @see search-result.tpl.php, search-results.tpl.php
+ *
+ * @param $results
+ * An array of search results.
+ *
+ * @return
+ * A renderable array, which will render the formatted search results with
+ * a pager included.
+ */
+function _biblio_search_page($results) {
+ $output['prefix']['#markup'] = '';
+
+ foreach ($results as $entry) {
+ $output[] = array(
+ '#theme' => 'search_result',
+ '#result' => $entry,
+ '#module' => 'my_module_name',
+ );
+ }
+ $output['suffix']['#markup'] = '' . theme('pager');
+
+ return $output;
+}
+
+/**
+ * Preprocess text for search.
+ *
+ * This hook is called to preprocess both the text added to the search index and
+ * the keywords users have submitted for searching.
+ *
+ * Possible uses:
+ * - Adding spaces between words of Chinese or Japanese text.
+ * - Stemming words down to their root words to allow matches between, for
+ * instance, walk, walked, walking, and walks in searching.
+ * - Expanding abbreviations and acronymns that occur in text.
+ *
+ * @param $text
+ * The text to preprocess. This is a single piece of plain text extracted
+ * from between two HTML tags or from the search query. It will not contain
+ * any HTML entities or HTML tags.
+ *
+ * @return
+ * The text after preprocessing. Note that if your module decides not to alter
+ * the text, it should return the original text. Also, after preprocessing,
+ * words in the text should be separated by a space.
+ *
+ * @ingroup search
+ */
+function _biblio_search_preprocess($text) {
+ // Do processing on $text
+ return $text;
+}
+
+/**
+ * Update the search index for this module.
+ *
+ * This hook is called every cron run if search.module is enabled, your
+ * module has implemented hook_search_info(), and your module has been set as
+ * an active search module on the Search settings page
+ * (admin/config/search/settings). It allows your module to add items to the
+ * built-in search index using search_index(), or to add them to your module's
+ * own indexing mechanism.
+ *
+ * When implementing this hook, your module should index content items that
+ * were modified or added since the last run. PHP has a time limit
+ * for cron, though, so it is advisable to limit how many items you index
+ * per run using variable_get('search_cron_limit') (see example below). Also,
+ * since the cron run could time out and abort in the middle of your run, you
+ * should update your module's internal bookkeeping on when items have last
+ * been indexed as you go rather than waiting to the end of indexing.
+ *
+ * @ingroup search
+ */
+function _biblio_update_index() {
+ $limit = (int)variable_get('search_cron_limit', 100);
+
+ $result = db_query_range("SELECT n.nid FROM {node} n LEFT JOIN {search_dataset} d ON d.type = 'node' AND d.sid = n.nid WHERE d.sid IS NULL OR d.reindex <> 0 ORDER BY d.reindex ASC, n.nid ASC", 0, $limit);
+
+ foreach ($result as $node) {
+ $node = node_load($node->nid);
+
+ // Save the changed time of the most recent indexed node, for the search
+ // results half-life calculation.
+ variable_set('node_cron_last', $node->changed);
+
+ // Render the node.
+ node_build_content($node, 'search_index');
+ $node->rendered = drupal_render($node->content);
+
+ $text = '
' . check_plain($node->title) . '
' . $node->rendered;
+
+ // Fetch extra data normally not visible
+ $extra = module_invoke_all('node_update_index', $node);
+ foreach ($extra as $t) {
+ $text .= $t;
+ }
+
+ // Update index
+ search_index($node->nid, 'node', $text);
+ }
+}
+/**
+ * @} End of "addtogroup hooks".
+ */
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/includes/biblio.util.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/includes/biblio.util.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,387 @@
+ and the file's
+ // original author.
+ // Original Author: Richard Karnesky //
+ // Adapted for biblio: Ron Jerome
+ // fmt_info (type)
+ $fmt = "info:ofi/fmt:kev:mtx:";
+ // 'dissertation' is compatible with the 1.0 spec, but not the 0.1 spec
+ if ($node->biblio_type == 108) {
+ $fmt .= "dissertation";
+ }
+ elseif ($node->biblio_type == 102) {
+ $fmt .= "journal";
+ }
+ elseif ($node->biblio_type == 100 || $node->biblio_type == 101) {
+ $fmt .= "book";
+ }
+ // 'dc' (dublin core) is compatible with the 1.0 spec, but not the 0.1 spec.
+ // We default to this, as it is the most generic type.
+ else {
+ $fmt .= "dc";
+ }
+
+ $co = biblio_contextObject($node);
+ $coins = "ctx_ver=Z39.88-2004&rft_val_fmt=" . urlencode($fmt);
+ foreach ($co as $coKey => $coValue) {
+ // 'urlencode()' differs from 'rawurlencode() (i.e., RFC1738 encoding)
+ // in that spaces are encoded as plus (+) signs
+ $coKey = preg_replace("/au[0-9]*/", "au", $coKey);
+ $coins .= "&" . $coKey . "=" . urlencode($coValue);
+ }
+ $coinsSpan = "";
+ return $coinsSpan;
+}
+
+function biblio_contextObject($node) {
+ // Copyright: Matthias Steffens and the file's
+ // original author.
+ // Original Author: Richard Karnesky //
+ // Adapted for biblio: Ron Jerome
+ global $base_url;
+ $i = 0;
+ // $openurl_base = variable_get('biblio_baseopenurl', '');
+ $co = array();
+ // rfr_id
+// $co["rfr_id"] = "info:sid/". ereg_replace("http://", "", $base_url);
+// // genre (type)
+// if (isset($node->biblio_type)) {
+// if ($node->biblio_type == 102)
+// $co["rft.genre"] = "article";
+// elseif ($node->biblio_type == 101) $co["rft.genre"] = "bookitem";
+// elseif ($node->biblio_type == 100) $co["rft.genre"] = "book";
+// elseif ($node->biblio_type == "Journal") $co["rft.genre"] = "journal";
+// }
+ // atitle, btitle, title (title, publication)
+ if (($node->biblio_type == 102) || ($node->biblio_type == 101)) {
+ if (!empty($node->title)) $co["rft.atitle"] = check_plain($node->title);
+ if (!empty($node->biblio_secondary_title)) {
+ $co["rft.title"] = check_plain($node->biblio_secondary_title);
+ if ($node->biblio_type == 101)
+ $co["rft.btitle"] = check_plain($node->biblio_secondary_title);
+ }
+ }
+ elseif (!empty($node->title)) {
+ $co["rft.title"] = check_plain($node->title);
+ }
+ if (($node->biblio_type == 100) && (!empty($node->biblio_secondary_title))) $co["rft.btitle"] = check_plain($node->biblio_secondary_title);
+ // stitle (abbrev_journal)
+ if (!empty($node->biblio_short_title)) $co["rft.stitle"] = check_plain($node->biblio_short_title);
+ // series (series_title)
+ if (!empty($node->biblio_tertiary_title)) $co["rft.series"] = check_plain($node->biblio_tertiary_title);
+ // issn
+ if (!empty($node->biblio_issn)) $co["rft.issn"] = check_plain($node->biblio_issn);
+ // isbn
+ if (!empty($node->biblio_isbn)) $co["rft.isbn"] = check_plain($node->biblio_isbn);
+ // date (year)
+ if (!empty($node->biblio_year)) $co["rft.date"] = check_plain($node->biblio_year);
+ // volume
+ if (!empty($node->biblio_volume)) $co["rft.volume"] = check_plain($node->biblio_volume);
+ // issue
+ if (!empty($node->biblio_issue)) $co["rft.issue"] = check_plain($node->biblio_issue);
+ // spage, epage, tpages (pages)
+ // NOTE: lifted from modsxml.inc.php--should throw some into a new include file
+ if (!empty($node->biblio_pages)) {
+ if (preg_match("/[0-9] *- *[0-9]/", $node->biblio_pages)) {
+ list ($pagestart, $pageend) = preg_split('/\s*[-]\s*/', $node->biblio_pages);
+ if ($pagestart < $pageend) {
+ $co["rft.spage"] = check_plain($pagestart);
+ $co["rft.epage"] = check_plain($pageend);
+ }
+ }
+ elseif ($node->biblio_type == 100) { //"Book Whole") {
+ $pagetotal = preg_replace('/^(\d+)\s*pp?\.?$/', "\\1", $node->biblio_pages);
+ $co["rft.tpages"] = check_plain($pagetotal);
+ }
+ else {
+ $co["rft.spage"] = check_plain($node->biblio_pages);
+ }
+ }
+ // aulast, aufirst, author (author)
+ if (!empty($node->biblio_contributors)) {
+ if (!empty($node->biblio_contributors[0]['lastname'])) {
+ $co["rft.aulast"] = check_plain($node->biblio_contributors[0]['lastname']);
+ }
+ if (!empty($node->biblio_contributors[0]['firstname'])) {
+ $co["rft.aufirst"] = check_plain($node->biblio_contributors[0]['firstname']);
+ }
+ elseif (!empty($node->biblio_contributors[0]['initials'])) {
+ $co["rft.auinit"] = check_plain($node->biblio_contributors[0]['initials']);
+ }
+ for($i = 1; $i < count($node->biblio_contributors); $i++) {
+ $author = $node->biblio_contributors[$i];
+ if ($author['auth_category'] == 1) {
+ if (!empty($author['lastname'])) {
+ $au = $author['lastname'];
+ if (!empty($author['firstname']) || !empty($author['initials'])) $au .= ", ";
+ }
+ if (!empty($author['firstname'])) {
+ $au .= $author['firstname'];
+ }
+ elseif (!empty($author['initials'])) {
+ $au .= $author['initials'];
+ }
+ if (!empty($au)) $co["rft.au" . $i] = $au;
+ }
+ }
+ }
+ // pub (publisher)
+ if (!empty($node->biblio_publisher)) $co["rft.pub"] = check_plain($node->biblio_publisher);
+ // place
+ if (!empty($node->biblio_place_published)) $co["rft.place"] = check_plain($node->biblio_place_published);
+ // id (doi, url)
+ if (!empty($node->biblio_doi)) {
+ $co["rft_id"] = "info:doi/" . check_plain($node->biblio_doi);
+ }
+// elseif (!empty($node->biblio_url)) {
+// $co["rft_id"] = $node->biblio_url;
+// }
+
+ return $co;
+}
+
+function biblio_coins_generate(& $node) {
+ if (!isset($node->vid)) {
+ $node->biblio_coins = biblio_coins($node);
+ return;
+ }
+ if ($node) {
+ $node->biblio_coins = biblio_coins($node);
+ db_update('biblio')
+ ->fields(array('biblio_coins' => $node->biblio_coins))
+ ->condition('vid', $node->vid)
+ ->execute();
+ }
+ else {
+ $result = db_query("SELECT nr.*, b.*
+ FROM {node} AS n
+ LEFT JOIN {node_revision} AS nr ON n.vid = nr.vid LEFT JOIN {biblio} AS b ON n.vid = b.vid
+ WHERE n.type = 'biblio' ");
+
+ foreach ($result as $node) {
+ $node->biblio_coins = biblio_coins($node);
+ db_update('biblio')
+ ->fields(array('biblio_coins' => $node->biblio_coins))
+ ->condition('vid', $node->vid)
+ ->execute();
+ }
+ drupal_goto('');
+ }
+}
+
+function _strip_punctuation($text) {
+ return preg_replace("/[[:punct:]]/", '', $text);
+}
+/**
+ * Copyright (c) 2008, David R. Nadeau, NadeauSoftware.com.
+ * All rights reserved.
+ *
+ * Strip punctuation characters from UTF-8 text.
+ *
+ * Characters stripped from the text include characters in the following
+ * Unicode categories:
+ *
+ * Separators
+ * Control characters
+ * Formatting characters
+ * Surrogates
+ * Open and close quotes
+ * Open and close brackets
+ * Dashes
+ * Connectors
+ * Numer separators
+ * Spaces
+ * Other punctuation
+ *
+ * Exceptions are made for punctuation characters that occur withn URLs
+ * (such as [ ] : ; @ & ? and others), within numbers (such as . , % # '),
+ * and within words (such as - and ').
+ *
+ * Parameters:
+ * text the UTF-8 text to strip
+ *
+ * Return values:
+ * the stripped UTF-8 text.
+ *
+ * See also:
+ * http://nadeausoftware.com/articles/2007/9/php_tip_how_strip_punctuation_characters_web_page
+ */
+function _strip_punctuation_utf8( $text )
+{
+ $urlbrackets = '\[\]\(\)';
+ $urlspacebefore = ':;\'_\*%@&?!' . $urlbrackets;
+ $urlspaceafter = '\.,:;\'\-_\*@&\/\\\\\?!#' . $urlbrackets;
+ $urlall = '\.,:;\'\-_\*%@&\/\\\\\?!#' . $urlbrackets;
+
+ $specialquotes = '\'"\*<>';
+
+ $fullstop = '\x{002E}\x{FE52}\x{FF0E}';
+ $comma = '\x{002C}\x{FE50}\x{FF0C}';
+ $arabsep = '\x{066B}\x{066C}';
+ $numseparators = $fullstop . $comma . $arabsep;
+
+ $numbersign = '\x{0023}\x{FE5F}\x{FF03}';
+ $percent = '\x{066A}\x{0025}\x{066A}\x{FE6A}\x{FF05}\x{2030}\x{2031}';
+ $prime = '\x{2032}\x{2033}\x{2034}\x{2057}';
+ $nummodifiers = $numbersign . $percent . $prime;
+
+ return preg_replace(
+ array(
+ // Remove separator, control, formatting, surrogate,
+ // open/close quotes.
+ '/[\p{Z}\p{Cc}\p{Cf}\p{Cs}\p{Pi}\p{Pf}]/u',
+ // Remove other punctuation except special cases
+ '/\p{Po}(?]*?>.*?@siu',
+ '@@siu',
+ '@@siu',
+ '@@siu',
+ '@@siu',
+ '@@siu',
+ '@]*?.*?@siu',
+ '@@siu',
+ '@]*?.*?@siu',
+ // Add line breaks before and after blocks
+ '@?((address)|(blockquote)|(center)|(del))@iu',
+ '@?((div)|(h[1-9])|(ins)|(isindex)|(p)|(pre))@iu',
+ '@?((dir)|(dl)|(dt)|(dd)|(li)|(menu)|(ol)|(ul))@iu',
+ '@?((table)|(th)|(td)|(caption))@iu',
+ '@?((form)|(button)|(fieldset)|(legend)|(input))@iu',
+ '@?((label)|(select)|(optgroup)|(option)|(textarea))@iu',
+ '@?((frameset)|(frame)|(iframe))@iu',
+ ),
+ array(
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ "\n\$0", "\n\$0", "\n\$0", "\n\$0", "\n\$0", "\n\$0",
+ "\n\$0", "\n\$0",
+ ),
+ $text );
+ return strip_tags( $text );
+}
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/includes/biblio_theme.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/includes/biblio_theme.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,1255 @@
+
+
+ Style and Locale Metadata
+
+
+
+ Set the CSL version of the style ("1.0" for CSL 1.0-compatible
+styles).
+ 1.0
+
+
+
+ Metadata for independent styles.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Metadata for dependent styles.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Metadata for locale files.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specify the citation format of the style (using the "citation-format"
+attribute) or the fields and disciplines for which the style is
+relevant (using the "field" attribute).
+
+
+
+
+
+
+
+
+
+
+
+
+ Specify the URI to establish the identity of the style. The URI
+should be stable, unique and dereferenceable URI.
+
+
+
+
+
+ Specify the journal's ISSN(s) for journal-specific styles. An ISSN
+must consist of four digits, a hyphen, three digits, and a check
+digit (a numeral digit or roman X), e.g. "1234-1231".
+
+ \d{4}\-\d{3}(\d|x|X)
+
+
+
+
+
+ Specify the journal's eISSN for journal-specific styles.
+
+ \d{4}\-\d{3}(\d|x|X)
+
+
+
+
+
+ Specify the journal's ISSN-L for journal-specific styles.
+
+ \d{4}\-\d{3}(\d|x|X)
+
+
+
+
+
+
+
+
+
+ Specify how the URL relates to the style.
+
+ self
+ The URI of the CSL style itself.
+ template
+ URI of the style from which the current style is derived.
+ documentation
+ URI of style documentation.
+ independent-parent
+ Obsolete for independent styles. Will be disallowed with
+CSL 1.1.
+
+
+
+
+
+
+
+
+
+
+
+ Specify how the URL relates to the style.
+
+ self
+ The URI of the CSL style itself.
+ independent-parent
+ URI of the CSL style whose content should be used for
+processing. Required for dependent styles.
+ documentation
+ URI of style documentation.
+ template
+ Obsolete for dependent styles. Will be disallowed with CSL
+1.1.
+
+
+
+
+
+
+
+ Specify when the style was initially created or made available.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specify an abbreviated style title (e.g., "APA")
+
+
+
+
+
+ Specify when the style was last updated (e.g.,
+"2007-10-26T21:32:52+02:00")
+
+
+
+
+
+
+
+
+
+
+
+
+ Obsolete for dependent styles. Will be disallowed with CSL 1.1.
+
+
+
+ in-text
+ note
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Localization
+
+
+ CSL locale file (locales-xx-XX.xml)
+
+
+ Specify the locale of the locale file.
+
+
+
+ Set the CSL version of the locale file ("1.0" for CSL
+1.0-compatible locale files).
+ 1.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Use to (re)define localized terms, dates and options.
+
+
+ Specify the affected locale(s). If "xml:lang" is not set, the
+"cs:locale" element affects all locales.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ long
+
+
+
+
+ masculine
+ feminine
+
+
+
+
+
+
+
+
+
+ long
+
+
+
+
+ masculine
+ feminine
+
+
+
+
+
+
+ "verb-short" reverts to "verb" if the "verb-short" form is not available
+"symbol" reverts to "short" if the "symbol" form is not available
+"verb" and "short" revert to "long" if the specified form is not available
+
+ long
+ verb
+ short
+ verb-short
+ symbol
+
+
+
+
+ Extension structures. You may override these in a customization schema.
+If you do, please contact the CSL project team to add the term or form to
+the official schema.
+
+
+
+
+
+
+
+
+ Simple terms are basic strings, used to represent genres, media, etc.
+
+
+
+
+
+
+ Compound terms are those whose output can be either singular or plural.
+Typically used for things like page number or editor labels.
+
+
+
+
+
+
+
+
+ Plural version of the term.
+
+
+
+
+
+ Singular version of the term.
+
+
+
+
+
+
+ Select the localized date format ("text" or "numeric") that will
+be defined.
+
+ text
+ Text date form (e.g., "December 15, 2005" for "en-US").
+ numeric
+ Numeric date form (e.g., "12-15-2005" for "en-US").
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Localized global options are specified as attributes in the
+cs:style-options element. If future versions of CSL include localized
+options that are citation or bibliography specific, the elements
+cs:citation-options and cs:bibliography-options can be added.
+
+
+
+ Specify whether punctuation (a period or comma) is placed within
+or outside (default) the closing quotation mark.
+
+
+
+
+
+
+
+
+ Macros
+
+
+
+ Use to create collections of (reusable) formatting instructions.
+
+
+
+
+
+
+
+
+
+ Citation and Bibliography
+
+
+
+ Use to describe the formatting of citations.
+
+
+
+
+
+
+
+
+
+
+
+ Use to describe the formatting of the bibliography.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contributor Names
+
+
+ Options affecting cs:names, for cs:style, cs:citation and cs:bibliography.
+
+
+ Inheritable name option, companion for "delimiter" on cs:names.
+
+
+
+
+
+
+
+
+ Specify the delimiter for name lists of name variables rendered by
+the same cs:names element.
+
+
+
+
+
+
+
+
+
+
+ Options affecting cs:name, for cs:style, cs:citation and cs:bibliography.
+
+
+
+ Inheritable name option, companion for "form" on cs:name.
+
+ long
+ short
+ count
+
+
+
+
+
+ Inheritable name option, companion for "delimiter" on cs:name.
+
+
+
+
+
+
+ Use to separate the second-to-last and last name of a name list by
+the "and" term or ampersand.
+
+ text
+ Use the "and" term (e.g., "Doe, Johnson and Smith").
+ symbol
+ Use the "ampersand" (e.g., "Doe, Johnson & Smith").
+
+
+
+
+
+ Specify when the name delimiter is used between a truncated name list
+and the "et-al" (or "and others") term in case of et-al abbreviation
+(e.g., "Smith, Doe et al." or "Smith, Doe, et al.").
+
+ contextual
+ The name delimiter is only used when the truncated name list
+consists of two or more names.
+ always
+ The name delimiter is always used.
+ never
+ The name delimiter is never used.
+
+
+
+
+
+ Specify when the name delimiter is used between the second-to-last
+and last name of a non-truncated name list. Only has an effect when
+the "and" term or ampersand is used (e.g., "Doe and Smith" or "Doe,
+and Smith").
+
+ contextual
+ The name delimiter is only used when the name list consists of
+three or more names.
+ always
+ The name delimiter is always used.
+ never
+ The name delimiter is never used.
+
+
+
+
+
+ Set the minimum number of names needed in a name variable to activate
+et-al abbreviation.
+
+
+
+
+
+ Set the number of names to render when et-al abbreviation is active.
+
+
+
+
+
+ As "et-al-min", but only affecting subsequent citations to an item.
+
+
+
+
+
+ As "et-al-use-first", but only affecting subsequent citations to an
+item.
+
+
+
+
+
+ If set to "true", the "et-al" (or "and others") term is replaced by
+an ellipsis followed by the last name of the name variable.
+
+
+
+
+
+ If set to "false", names are not initialized and "initialize-with"
+only affects initials already present in the input data.
+
+
+
+
+
+ Activate initializing of given names. The attribute value is appended
+to each initial (e.g., with ". ", "Orson Welles" becomes "O. Welles").
+
+
+
+
+ Specify whether (and which) names should be rendered in their sort
+order (e.g., "Doe, John" instead of "John Doe").
+
+ first
+ Render the first name of each name variable in sort order.
+ all
+ Render all names in sort order.
+
+
+
+
+
+ Sets the delimiter for name-parts that have switched positions as a
+result of "name-as-sort-order" (e.g., ", " in "Doe, John").
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Short version of "names" element, without children, allowed in <substitute/>
+
+
+
+
+
+
+
+
+
+
+
+ Select the "long" (first name + last name, for Western names),
+"short" (last name only, for Western names), or "count" name form
+(returning the number of names in the name variable, which can be
+useful for some sorting algorithms).
+
+ long
+ short
+ count
+
+
+
+
+ Set the delimiter for names in a name variable (e.g., ", " in
+"Doe, Smith")
+
+
+
+ Use to format individual name parts (e.g., "Jane DOE").
+
+
+ family
+ given
+
+
+
+
+
+
+
+
+
+
+ Inherits variable from the parent cs:names element.
+
+
+
+
+
+
+
+
+
+
+
+ Specify the term used for et-al abbreviation and its formatting.
+
+
+ Select the term to use for et-al abbreviation.
+
+ et-al
+ and others
+
+
+
+
+
+
+
+
+
+ Specify substitution options when the name variables selected on the
+parent cs:names element are empty.
+
+
+
+
+
+
+
+
+
+
+
+ Dates
+
+
+
+
+
+
+
+
+
+ Use to select a localized date format.
+
+ text
+ Use the localized text form of the date (e.g., "December
+15, 2005" for en-US).
+ numeric
+ Use the localized numeric form of the date (e.g.,
+"12-15-2005" for en-US)
+
+
+
+
+ Limit the date parts rendered.
+
+ year-month-day
+ Year, month and day
+ year-month
+ Year and month
+ year
+ Year only
+
+
+
+
+
+ Specify overriding formatting for localized dates (affixes
+cannot be overridden, as these are considered locale-specific).
+Example uses are forcing the use of leading-zeros, or of the
+"short" month form. Has no effect on which, and in what order,
+date parts are rendered.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specify, in the desired order, the date parts that should be
+rendered and their formatting.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specify a delimiter for date ranges (by default the en-dash). A custom
+delimiter is retrieved from the largest date part ("day", "month" or
+"year") that differs between the two dates.
+
+
+
+
+
+ day
+
+
+
+ Day forms: "numeric" ("5"), "numeric-leading-zeros" ("05"), "ordinal"
+("5th").
+
+ numeric
+ numeric-leading-zeros
+ ordinal
+
+
+
+
+
+
+
+ month
+
+
+
+ Months forms: "long" (e.g., "January"), "short" ("Jan."), "numeric"
+("1"), and "numeric-leading-zeros" ("01").
+
+ long
+ short
+ numeric
+ numeric-leading-zeros
+
+
+
+
+
+
+
+
+ year
+
+
+
+ Year forms: "long" ("2005"), "short" ("05").
+
+ short
+ long
+
+
+
+
+
+
+
+
+ Formatting Text
+
+
+
+ Use to call macros, render variables, terms, or verbatim text.
+
+
+
+
+
+
+
+
+ Select a macro.
+
+
+
+
+ Select a term.
+
+
+
+
+
+
+
+
+
+ Specify term plurality: singular ("false") or plural ("true").
+
+
+
+
+
+ Specify verbatim text.
+
+
+
+ Select a variable.
+
+
+
+
+
+ short
+ long
+
+
+
+
+
+
+
+
+
+ Use to render a number variable.
+
+
+
+
+
+
+
+
+
+ Number forms: "numeric" ("4"), "ordinal" ("4th"), "long-ordinal"
+("fourth"), "roman" ("iv").
+
+ numeric
+ ordinal
+ long-ordinal
+ roman
+
+
+
+
+
+
+
+
+ Label Text
+
+
+
+ Use to render a term whose pluralization depends on the content of a
+variable. E.g., if "page" variable holds a range, the plural label
+"pp." is selected instead of the singular "p.".
+
+
+
+
+ locator
+ page
+
+
+
+
+
+ long
+ short
+ symbol
+
+
+
+
+
+
+
+
+
+
+
+
+ Specify when the plural version of a term is selected.
+
+ always
+ never
+ contextual
+
+
+
+
+
+
+
+ Groups
+
+
+
+ Use to group rendering elements. Groups are useful for setting a
+delimiter for the group children, for organizing the layout of
+bibliographic entries (using the "display" attribute), and for
+suppressing the rendering of terms and verbatim text when variables
+are empty.
+
+
+
+
+
+
+
+
+
+
+
+
+ Options
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specify whether the non-dropping particle is demoted in inverted
+names (e.g., "Koning, W. de").
+
+ never
+ sort-only
+ display-and-sort
+
+
+
+
+
+
+
+ Specify whether compound given names (e.g., "Jean-Luc") are
+initialized with ("J-L") or without a hyphen ("JL").
+
+
+
+
+
+
+
+ Reformat page ranges in the "page" variable.
+
+ expanded
+ minimal
+ chicago
+
+
+
+
+
+
+
+ Activate cite grouping and specify the delimiter for cites within a
+cite group.
+
+
+
+
+
+
+ Activate cite grouping and specify the method of citation collapsing.
+
+ citation-number
+ Collapse ranges of numeric cites, e.g. from "[1,2,3]" to "[1-3]".
+ year
+ Collapse cites by suppressing repeated names, e.g. from "(Doe
+2000, Doe 2001)" to "(Doe 2000, 2001)".
+ year-suffix
+ Collapse cites as with "year", but also suppresses repeated
+years, e.g. from "(Doe 2000a, Doe 2000b)" to "(Doe 2000a, b)".
+ year-suffix-ranged
+ Collapses cites as with "year-suffix", but also collapses
+ranges of year-suffixes, e.g. from "(Doe 2000a, Doe 2000b,
+Doe 2000c)" to "(Doe 2000a-c)".
+
+
+
+
+
+ Specify the delimiter between year-suffixes. Defaults to the cite
+delimiter.
+
+
+
+
+ Specify the delimiter following a group of collapsed cites. Defaults
+to the cite delimiter.
+
+
+
+
+
+
+ Set to "true" to activate disambiguation by showing names that were
+originally hidden as a result of et-al abbreviation.
+
+
+
+
+
+ Set to "true" to activate disambiguation by expanding names, showing
+initials or full given names.
+
+
+
+
+
+ Set to "true" to activate disambiguation by adding year-suffixes
+(e.g., "(Doe 2007a, Doe 2007b)") for items from the same author(s)
+and year.
+
+
+
+
+
+ Specify how name are expanded for disambiguation.
+
+ all-names
+ Each ambiguous names is progressively transformed until
+disambiguated (when disambiguation is not possible, the name
+remains in its original form).
+ all-names-with-initials
+ As "all-names", but name expansion is limited to showing
+initials.
+ primary-name
+ As "all-names", but disambiguation is limited to the first name
+of each cite.
+ primary-name-with-initials
+ As "all-names-with-initials", but disambiguation is limited to
+the first name of each cite.
+ by-cite
+ As "all-names", but only ambiguous names in ambiguous cites are
+expanded.
+
+
+
+
+
+
+
+ Set the number of preceding notes (footnotes or endnotes) within
+which the current item needs to have been previously cited in order
+for the "near-note" position to be "true".
+
+
+
+
+
+
+
+ Set to "true" to render bibliographic entries with hanging indents.
+
+
+
+
+
+
+
+ Set the spacing between bibliographic entries.
+
+
+
+
+
+ Set the spacing between bibliographic lines.
+
+ 0
+
+
+
+
+
+
+
+ Use to align any subsequent lines of bibliographic entries with the
+beginning of the second field.
+
+ flush
+ Align the first field with the margin.
+ margin
+ Put the first field in the margin and align all subsequent
+lines of text with the margin.
+
+
+
+
+
+
+
+ Substitute names that repeat in subsequent bibliographic entries by
+the attribute value.
+
+
+
+
+ Specify the method of substitution of names repeated in subsequent
+bibliographic entries.
+
+ complete-all
+ Requires a match of all rendered names in the name variable, and
+substitutes once for all names.
+ complete-each
+ Requires a match of all rendered names in the name variable,
+and substitutes for each name.
+ partial-each
+ Substitutes for each name, until the first mismatch.
+ partial-first
+ Substitutes the first name if it matches.
+
+
+
+
+
+
+
+ Sorting
+
+
+
+
+
+
+
+
+
+
+ Specify how cites and bibliographic entries should be sorted. By
+default, items appear in the order in which they were cited.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Select between an ascending and descending sort.
+
+ ascending
+ descending
+
+
+
+
+
+ The minimum number of names needed in a name variable to activate
+name list truncation. Overrides the values set on any
+"et-al-(subsequent-)min" attributes.
+
+
+
+
+
+ The number of names to render when name list truncation is
+activated. Overrides the values set on the
+"et-al-(subsequent-)use-first" attributes.
+
+
+
+
+
+ Use to override the value of the "et-at-use-last" attribute.
+
+
+
+
+
+
+
+
+ Conditional Statements
+
+
+
+ Use to conditionally render rendering elements.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ If used, the element content is only rendered if it disambiguates two
+otherwise identical citations. This attempt at disambiguation is only
+made after all other disambiguation methods have failed.
+ true
+
+
+ Tests whether the given variables contain numeric text.
+
+
+
+
+
+
+
+ Tests whether the given date variables contain approximate dates.
+
+
+
+
+
+
+
+ Tests whether the locator matches the given locator types.
+
+
+
+
+ sub-verbo
+
+
+
+
+
+ Tests whether the cite position matches the given positions.
+
+
+
+ first
+ subsequent
+ ibid
+ ibid-with-locator
+ near-note
+
+
+
+
+
+ Tests whether the item matches the given types.
+
+
+
+
+
+
+
+ Tests whether the default ("long") forms of the given variables
+contain non-empty values.
+
+
+
+
+
+
+
+
+
+
+
+ Set the testing logic.
+
+ all
+ Element only tests "true" when all conditions test "true" for all
+given test values.
+ any
+ Element tests "true" when any condition tests "true" for any given
+test value.
+ none
+ Element only tests "true" when none of the conditions test "true"
+for any given test value.
+
+
+
+
+
+
+ Formatting attributes.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ By default, bibliographic entries consist of continuous runs of text.
+With the "display" attribute, portions of each entry can be
+individually positioned.
+
+ block
+ Places the content in a block stretching from margin to margin.
+ left-margin
+ Places the content in a block starting at the left margin.
+ right-inline
+ Places the content in a block to the right of a preceding
+"left-margin" block.
+ indent
+ Places the content in a block indented to the right by a standard
+amount.
+
+
+
+
+
+ The font-formatting attributes are based on those of CSS and XSL-FO.
+
+
+
+ italic
+ normal
+ oblique
+
+
+
+
+
+
+ normal
+ small-caps
+
+
+
+
+
+
+ normal
+ bold
+ light
+
+
+
+
+
+
+ none
+ underline
+
+
+
+
+
+
+ baseline
+ sup
+ sub
+
+
+
+
+
+
+
+ When set to "true", quotes are placed around the rendered text.
+
+
+
+
+
+
+
+ When set to "true", periods are removed from the rendered text.
+
+
+
+
+
+
+
+
+ lowercase
+ Renders text in lowercase.
+ uppercase
+ Renders text in uppercase.
+ capitalize-first
+ Capitalizes the first character (other characters remain in
+their original case).
+ capitalize-all
+ Capitalizes the first character of every word (other characters
+remain in their original case).
+ title
+ Renders text in title case.
+ sentence
+ Renders text in sentence case.
+
+
+
+
+
';
+
+}
+
+function _biblio_ris_import_string($string) {
+ $tag = '';
+ $node = new stdClass();
+ $unmapped = array();
+
+ $lines = preg_split('/[\r\n]/', $string, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($lines as $line) {
+ $line_len = strlen($line);
+ if ($line_len > 3) {
+ $start = strpos($line, ' -'); // There could be some unprintables at the beginning of the line so fine the location of the %
+ if ($start !== FALSE) {
+ $tag = drupal_substr($line, $start -2, 2);
+ $data = trim(drupal_substr($line, $start +3));
+ }
+ else {
+ $data = $line;
+ }
+ }
+ if ($line_len > 3 && !empty($tag)) { // if this is not a blank line
+ if ($tag == 'ER') {
+ if (!empty($node)) {
+ $node->biblio_ris_md5 = md5(serialize($node));
+ if (empty ($node->title )) $node->title = t("Untitled");
+ if (! ($dup = biblio_ris_check_md5($node->biblio_ris_md5))) {
+ return $node;
+ }
+ else {
+ $message = t('The RIS node that you are trying to paste into the form already exists in the database, see !url', array('!url' => l('node/' . $dup, 'node/' . $dup)));
+ form_set_error('paste_data_ris', $message);
+ return;
+ }
+ }
+ }
+ else {
+ _biblio_ris_parse_line($tag, $data, $node, $unmapped);
+ }
+ }
+ } // end while
+ if (!empty($unmapped)) {
+ $ignored_tags = array_unique($unmapped);
+ $message = t("The following elements were ignored because they do not map to any biblio fields:") . ' ';
+ $message .= implode(', ', $ignored_tags);
+ if (user_access('administer biblio')) {
+ $message .= '. ' . t('Click !url if you wish to check the field mapping', array('!url' => l(t('here'), 'admin/config/content/biblio/iomap/edit/ris')));
+ }
+ drupal_set_message($message, 'warning');
+ }
+}
+
+function _biblio_ris_import($file, $terms = array(), $batch = FALSE, $session_id = NULL) {
+ ini_set('auto_detect_line_endings', TRUE);
+ if (!($fp = fopen($file->uri, "r"))) {
+ drupal_set_message(t("Could not open RIS input file for reading."), 'error');
+ return;
+ }
+
+ $tag = '';
+ $nids = array();
+ $dups = array();
+ $unmapped = array();
+ $node = new stdClass();
+
+ while (!feof($fp)) {
+ $line = fgets($fp);
+ // Remove any character other than: carriage return, line feed, tab, or ANSI/ASCII character codes 32-255
+ $line = preg_replace('/[^\r\n\t\x20-\xFF]/', '', $line);
+ $line_len = strlen($line);
+ if ($line_len > 3) {
+ $start = strpos($line, ' -'); // There could be some unprintables at the beginning of the line so fine the location of the %
+ if ($start !== FALSE) {
+ $tag = drupal_substr($line, $start -2, 2);
+ $data = trim(drupal_substr($line, $start +3));
+ }
+ else {
+ $data = $line;
+ }
+ }
+ if ($line_len > 3 && !empty($tag)) { // if this is not a blank line
+ if ($tag == 'ER') {
+ if (!empty($node)) {
+ $node->biblio_ris_md5 = md5(serialize($node));
+ if (empty ($node->title )) $node->title = t("Untitled");
+ if (! ($dup = biblio_ris_check_md5($node->biblio_ris_md5))) {
+ biblio_save_node($node, $terms, $batch, $session_id);
+ if (!empty($node->nid)) $nids[] = $node->nid;
+ }
+ else {
+ $dups[] = $dup;
+ }
+ }
+
+ $node = new stdClass();
+ $node->biblio_contributors = array();
+ }
+ else {
+ _biblio_ris_parse_line($tag, $data, $node, $unmapped);
+ }
+
+ }
+ } // end while
+
+ fclose($fp);
+
+ if (!empty($unmapped)) {
+ $ignored_tags = array_unique($unmapped);
+ $message = t('The following elements were ignored because they do not map to any biblio fields:') . ' ';
+ $message .= implode(', ', $ignored_tags);
+ if (user_access('administer biblio')) {
+ $message .= '. ' . t('Click !url if you wish to check the field mapping', array('!url' => l(t('here'), 'admin/config/content/biblio/iomap/edit/ris')));
+ }
+ drupal_set_message($message, 'warning');
+ }
+
+ return array($nids, $dups);
+}
+
+function _biblio_ris_parse_line($tag, $data, $node, &$unmapped) {
+ switch ($tag) {
+ case 'TY' :
+ $node->biblio_type = _biblio_ris_type_map($data);
+ break;
+ case 'A1' :
+ case 'AU' :
+ $node->biblio_contributors[] = array(
+ 'name' => $data,
+ 'auth_category' => 1,
+ 'auth_type' => _biblio_get_auth_type(1, $node->biblio_type));
+ break;
+ case 'DA' :
+ if (!isset($node->biblio_year) || empty($node->biblio_year)) {
+ $node->biblio_year = ($end = strpos($data, "/")) ? substr($data, 0, $end) : $data;
+ }
+ $node->biblio_date = $data;
+ break;
+ case 'Y1' :
+ case 'PY' :
+ if (!isset($node->biblio_year) || empty($node->biblio_year)) {
+ $node->biblio_year = ($end = strpos($data, "/")) ? substr($data, 0, $end) : $data;
+ }
+ if (!isset($node->biblio_date) || empty($node->biblio_date)) {
+ $node->biblio_date = $data;
+ }
+ break;
+ case 'A2' :
+ case 'ED' :
+ $node->biblio_contributors[] = array(
+ 'name' => $data,
+ 'auth_category' => 2,
+ 'auth_type' => _biblio_get_auth_type(2, $node->biblio_type));
+ break;
+ case 'KW' :
+ $node->biblio_keywords[] = $data;
+ break;
+ case 'SP' :
+ case 'EP' :
+ $node->biblio_pages .= ($tag == "SP") ? $data : " - " . $data;
+ break;
+ case 'A3' :
+ $node->biblio_contributors[] = array(
+ 'name' => $data,
+ 'auth_category' => 5,
+ 'auth_type' => _biblio_get_auth_type(5, $node->biblio_type));
+ break;
+ case 'BT' :
+ if ($node->biblio_type == 100) {
+ $node->title = $data;
+ }
+ else {
+ $node->biblio_secondary_title = $data;
+ }
+ break;
+ default :
+ if ($field = _biblio_ris_field_map($tag)) {
+ $node->$field .= $data;
+ }
+ else {
+ if (!in_array($tag, $unmapped)) {
+ $unmapped[] = $tag;
+ }
+ }
+ }
+}
+
+function _biblio_ris_export($node) {
+ $reverse = TRUE;
+ $ris = "";
+ $ris .= "TY - " . _biblio_ris_type_map($node->biblio_type, $reverse) . "\r\n";
+ if (!empty($node->title)) $ris .= "T1 - " . trim($node->title) . "\r\n";
+ switch ($node->biblio_type) {
+ case 100 :
+ case 101 :
+ case 103 :
+ case 104 :
+ case 105 :
+ case 108 :
+ case 119 :
+ if (!empty($node->biblio_secondary_title))
+ $ris .= "T2 - " . trim($node->biblio_secondary_title) . "\r\n";
+ break;
+ case 102 :
+ if (!empty($node->biblio_secondary_title))
+ $ris .= "JF - " . trim($node->biblio_secondary_title) . "\r\n";
+ unset($node->biblio_secondary_title);
+ break; // journal
+ }
+ if (isset($node->biblio_year) && $node->biblio_year < 9998) {
+ $ris .= "Y1 - " . trim($node->biblio_year) . "\r\n";
+ }
+
+ foreach (biblio_get_contributor_category($node->biblio_contributors, 1) as $auth) {
+ $ris .= "A1 - " . trim($auth['name']) . "\r\n";
+ }
+ foreach (biblio_get_contributor_category($node->biblio_contributors, 2) as $auth) {
+ $ris .= "ED - " . trim($auth['name']) . "\r\n";
+ }
+
+ $kw_array = array();
+ if (!empty($node->terms)) {
+ foreach ($node->terms as $term) {
+ $kw_array[] = $term->name;
+ }
+ }
+ if (!empty($node->biblio_keywords)) {
+ foreach ($node->biblio_keywords as $term) {
+ $kw_array[] = $term;
+ }
+ }
+ if (!empty($kw_array)) {
+ $kw_array = array_unique($kw_array);
+ foreach ($kw_array as $term) {
+ $ris .= "KW - " . trim($term) . "\r\n";
+ }
+ }
+ $abst = "";
+ if (!empty($node->biblio_abst_e)) $abst .= trim($node->biblio_abst_e);
+ if ($abst) {
+ $search = array("/\r/", "/\n/");
+ $replace = " ";
+ $abst = preg_replace($search, $replace, $abst);
+ $ris .= "AB - " . $abst . "\r\n";
+ }
+ $skip_fields = array('biblio_year', 'biblio_abst_e', 'biblio_abst_f', 'biblio_type' );
+ $fields = drupal_schema_fields_sql('biblio');
+ $fields = array_diff($fields, $skip_fields);
+ foreach ($fields as $field) {
+ if (!empty($node->$field)) {
+ $ris .= _biblio_ris_format_entry($field, $node->$field);
+ }
+ }
+ $ris .= "ER - \r\n\r\n";
+ return $ris;
+}
+
+function _biblio_ris_format_entry($key, $value) {
+ $reverse = TRUE;
+ $tag = _biblio_ris_field_map($key, $reverse);
+ if (!empty($tag)) {
+ return "$tag - " . trim($value) . "\r\n";
+ }
+
+}
+
+function _biblio_ris_type_map($type, $reverse = FALSE) {
+ static $map = array();
+ if (empty($map)) {
+ $map = biblio_get_map('type_map', 'ris');
+ }
+
+ if ($reverse) {
+ return ($tag = array_search($type, $map)) ? $tag : 'Generic'; //return the biblio type or 129 (Misc) if type not found
+ }
+ return (isset($map[$type]))?$map[$type]:129; //return the biblio type or 129 (Misc) if type not found
+}
+
+function _biblio_ris_field_map($field, $reverse = FALSE) {
+ static $fmap = array();
+ if (empty($fmap)) {
+ $fmap = biblio_get_map('field_map', 'ris');
+ }
+ if ($reverse) {
+ return ($tag = array_search($field, $fmap)) ? $tag : '';
+
+ }
+ return (!empty($fmap[$field])) ? $fmap[$field] : '';
+
+}
+function biblio_ris_ris_map_reset($type = NULL) {
+ module_load_include('install', 'biblio_ris', 'biblio_ris');
+ _reset_ris_map($type);
+}
+
+function biblio_ris_check_md5($md5) {
+ static $ris_md5s = array();
+ if (empty($ris_md5s)) {
+ $result = db_query("SELECT * FROM {biblio_ris} ");
+ foreach ($result as $row) {
+ $ris_md5s[$row->biblio_ris_md5] = $row->nid;
+ }
+ }
+ if (isset($ris_md5s[$md5])) {
+ return $ris_md5s[$md5];
+ }
+ else {
+ $ris_md5s[$md5] = TRUE; // gaurd against duplicates in the same import
+ return;
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/modules/bibtexParse/CHANGELOG
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/modules/bibtexParse/CHANGELOG Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,83 @@
+CHANGELOG
+
+Released through http://bibliophile.sourceforge.net under the GPL licence.
+Do whatever you like with this -- some credit to the author(s) would be appreciated.
+
+A collection of PHP classes to manipulate bibtex files.
+
+If you make improvements, please consider contacting the administrators at bibliophile.sourceforge.net so that your improvements can be added to the release package.
+
+Mark Grimshaw 2004/2005/2006
+http://bibliophile.sourceforge.net
+
+################################################
+v2.2
+24/April/2006 - Esteban Zimanyi and Mark Grimshaw
+1/ A 4th array, $this->undefinedStrings, is now returned that holds field values that are judged to be undefined strings. i.e. they are a non-numeric value that is not defined in a @string{...} entry and not enclosed by braces or double-quotes. This array will be empty unless the following condition is met:
+($this->removeDelimit || $this->expandMacro && $this->fieldExtract)
+2/ When an undefined string is found in function removeDelimiters return the empty string. Return $this->undefinedStrings in the last position to allow compatibility with previous versions.
+3/ Fix management of preamble in function returnArrays.
+
+v2.1
+7/February/2006 - Esteban Zimanyi and Mark Grimshaw
+Minor debugging to catch more unusually formatted entries.
+
+
+v2.0
+3/February/2006 - Esteban Zimanyi and Mark Grimshaw
+Substantial work on PARSEENTRES.php (mainly by Esteban) to:
+1/ handle @strings concatenated from other @strings.
+2/ handle all different types of comments possible.
+3/ clean-up the code.
+4/ handles more unusual formatting of white space between and inside entries.
+
+v1.5.4
+17/June/2005 - Mark Grimshaw
+month fields that have multiple dates (e.g. dec # " 5--9," or nov # " 29" # "--" # dec # " 2") are correctly parsed. (list($startMonth, $startDay, $endMonth, $endDay) = $parseMonth->init($monthField);)
+
+v1.5.3
+10/June/2005 - Mark Grimshaw
+Fixed excessive expansion of @strings in bibtex imports.
+
+v1.5.2
+5/May/2005 - Mark Grimshaw and Guillaume Gardey.
+1/ Corrections to PARSEENTRIES when handling concatenations using '#'
+2/ Corrections to the example commandline code for PARSECREATORS.
+
+v1.5.1
+30th April 2005 - Mark Grimshaw
+1/ Ensure entries such as journal = {{Journal of } # JRNL23} are properly parsed and expanded with a hanging '}' removed.
+
+v1.5
+28th April 2005 - Mark Grimshaw
+1/ Fixed a bug when parsing @preamble in PARSEENTRIES.php
+2/ Made efficiency and accuracy improvements in PARSECREATORS.php
+3/ Added class PARSEMONTH to split a bibtex month field into day and month components.
+ list($month, $day) = $parseMonth->init($monthField);
+4/ Added class PARSEPAGE to split a bibtex pages field into page start and page end components.
+ list($start, $end) = $parsePage->init($pagesField);
+
+v1.4
+25th August 2004
+1/ Expand macros added by Guillaume Gardey.
+2/ Discard comments on same line as @string.
+3/ A few bug fixes.
+4/ PARSEENTRIES can parse PHP strings. (loadBibTeXString)
+5/ Supports user defined BibTeX macro. (loadStringMacro)
+
+v1.3
+20th August 2004
+1/ @string{...} now correctly parsed.
+2/ Any final "," left on the end of the last field in an entry is now removed.
+
+v1.2
+15th August 2004
+Corrected bug in extraction of values from @string.
+v1.1
+15th August 2004
+1/ Added another flag to PARSEENTRIES to decide whether to remove enclosing "..." or {...} from string and entry fields.
+2/ Some debugging and simplification. Both flags now have a default value of TRUE.
+
+v1.0
+14th August 2004
+Initial release: PARSEENTRIES.php, PARSECREATORS.php
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/modules/bibtexParse/LICENSE
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/modules/bibtexParse/LICENSE Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,251 @@
+The GNU General Public License (GPL)
+
+Version 2, June 1991
+
+
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+
+59 Temple Place, Suite 330, Boston, MA 02111-1307 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 Library 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.
+
+
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+
+
+0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".
+
+
+
+Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.
+
+
+
+1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.
+
+
+
+You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
+
+
+
+2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
+
+
+
+ a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
+
+
+
+ b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
+
+
+
+ c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)
+
+
+
+These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
+
+
+
+Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.
+
+
+
+In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
+
+
+
+3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:
+
+
+
+ a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
+
+
+
+ b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
+
+
+
+ c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)
+
+
+
+The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
+
+
+
+If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.
+
+
+
+4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
+
+
+
+5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.
+
+
+
+6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.
+
+
+
+7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.
+
+
+
+If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.
+
+
+
+It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
+
+
+
+This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
+
+
+
+8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
+
+
+
+9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
+
+
+
+Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.
+
+
+
+10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
+
+
+
+NO WARRANTY
+
+
+
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+
+
+END OF TERMS AND CONDITIONS
+
+
+
+How to Apply These Terms to Your New Programs
+
+
+
+If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
+
+
+
+To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.
+
+
+
+ one line to give the program's name and a brief idea of what it does.
+
+ Copyright (C)
+
+
+
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+
+
+If the program is interactive, make it output a short notice like this when it starts in an interactive mode:
+
+
+
+ Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.
+
+
+
+The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program.
+
+
+
+You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names:
+
+
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest
+
+ in the program `Gnomovision' (which makes passes at compilers)
+
+ written by James Hacker.
+
+
+
+ signature of Ty Coon, 1 April 1989
+
+ Ty Coon, President of Vice
+
+
+
+This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/modules/bibtexParse/PARSECREATORS.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/modules/bibtexParse/PARSECREATORS.php Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,319 @@
+buildTypeMap();
+ if (is_array($init))
+ {
+ $this->setCreators($init);
+ }elseif (is_numeric($init))
+ {
+ $this->loadCreators($init);
+ }
+
+ }
+
+ function buildTypeMap()
+ {
+ $result = db_query("SELECT * FROM {biblio_contributor_type} ;");
+ while ($type = db_fetch_object($result))
+ {
+ $this->typeMap[$type->type] = $type->ctid;
+ }
+ }
+ function getCreatorByName($name)
+ {
+ $result = db_query('SELECT *
+ FROM {biblio_contributor_data}
+ WHERE lastname RLIKE "[[:<:]]%s[[:>:]]" ', $name);
+ }
+
+ function getCreatorCount()
+ {
+ return count($this->authors);
+ }
+
+ function getCreatorString()
+ {
+ foreach ($this->authors as $key => $author)
+ {
+ $author_array[$author['rank']] = $author['firstname'] .' '. $author['initials'].' '.$author['lastname'];
+ }
+ ksort($author_array);
+
+ return implode(', ' , $author_array);
+ }
+
+
+ private
+ function loadMD5()
+ {
+ $result = db_query('SELECT md5,cid FROM {biblio_contributor_data} ');
+ while ($row = db_fetch_array($result))
+ {
+ $this->md5[$row['cid']] = $row['md5'];
+ }
+ }
+
+ public
+ function loadCreators($vid)
+ {
+ $query = 'SELECT bcd.lastname, bcd.firstname, bcd.initials,
+ bcd.affiliation, bct.type, bc.rank
+ FROM {biblio_contributor} bc,
+ {biblio_contributor_data} bcd,
+ {biblio_contributor_type} bct
+ WHERE bc.vid = %d
+ AND bc.cid = bcd.cid
+ AND bc.ctid = bct.ctid
+ ORDER BY bc.ctid ASC, bc.rank ASC;';
+
+ $result = db_query($query, array($vid));
+ while($creator = db_fetch_array($result))
+ {
+ $this->authors[] = $creator;
+ }
+
+ }
+
+ public
+ function saveCreators($nid, $vid)
+ {
+ if (!empty($this->authors))
+ {
+ $this->loadMD5();
+ db_query('DELETE FROM {biblio_contributor} WHERE nid = %d AND vid = %d', $nid, $vid);
+ foreach ($this->authors as $rank => $author)
+ {
+ if (empty($author['cid']) && !empty($this->md5)) $author['cid'] = array_search($author['md5'], $this->md5);
+ if (empty($author['cid']) )
+ {
+ drupal_write_record('biblio_contributor_data', $author);
+ $cid = db_last_insert_id('biblio_contributor_data', 'cid');
+ }else
+ {
+ $cid = $author['cid'];
+ }
+
+ $link_array = array('nid' => $nid, 'vid' => $vid,
+ 'cid' => $cid, 'rank' => $rank,
+ 'ctid' => $author['type']);
+
+ drupal_write_record('biblio_contributor', $link_array );
+
+ }
+ }
+ }
+
+
+ function getAuthorArray()
+ {
+ return $this->authors;
+ }
+
+ function getAuthor($rank)
+ {
+ return $this->authors[$rank];
+ }
+
+/**
+ * update object with an array of authors
+ *
+ * @param $authors
+ * an array containing two keys "name" and "type"
+ * the name is the full name of the contributor which will be parsed into
+ * component pieces, and type contains a string indicating the author type
+ */
+ function setCreators($authors)
+ {
+ foreach ($authors as $author) {
+ if (strlen(trim($author['name'])))
+ {
+ $this->authors[] = $this->parseAuthor($author['name'], $author['type']);
+ }
+ }
+ }
+
+ function setCreator($author, $type = 'author')
+ {
+ $this->authors[] = $this->parseAuthor($author, $type);
+ }
+
+
+
+}
+
+/*
+Released through http://bibliophile.sourceforge.net under the GPL licence.
+Do whatever you like with this -- some credit to the author(s) would be appreciated.
+
+A collection of PHP classes to manipulate bibtex files.
+
+If you make improvements, please consider contacting the administrators at bibliophile.sourceforge.net so that your improvements can be added to the release package.
+
+Mark Grimshaw 2004/2005
+http://bibliophile.sourceforge.net
+
+28/04/2005 - Mark Grimshaw.
+ Efficiency improvements.
+
+11/02/2006 - Daniel Reidsma.
+ Changes to preg_matching to account for Latex characters in names such as {\"{o}}
+*/
+// For a quick command-line test (php -f PARSECREATORS.php) after installation, uncomment these lines:
+
+/***********************
+ $authors = "Mark \~N. Grimshaw and Bush III, G.W. & M. C. H{\\'a}mmer Jr. and von Frankenstein, Ferdinand Cecil, P.H. & Charles Louis Xavier Joseph de la Vallee P{\\\"{o}}ussin";
+ $creator = new PARSECREATORS();
+ $creatorArray = $creator->parse($authors);
+ print_r($creatorArray);
+***********************/
+
+class PARSECREATORS
+{
+ function PARSECREATORS()
+ {
+ }
+
+ function parse($input, $type = 'author')
+ {
+ $input = trim($input);
+ // split on ' and '
+ $authorArray = preg_split("/\s(and|&)\s/i", $input);
+ return $this->parseArray($authorArray, $type);
+ }
+
+ function parseArray($authorArray, $type = 'author')
+ {
+ foreach ($authorArray as $author)
+ {
+ $this->authors[] = $this->parseAuthor($author, $type);
+ }
+ }
+/* Create writer arrays from bibtex input.
+'author field can be (delimiters between authors are 'and' or '&'):
+1.
+2. ,
+3. , ,
+*/
+ function parseAuthor($value, $type = 'author')
+ {
+ $appellation = $prefix = $surname = $firstname = $initials = '';
+ $this->prefix = array();
+ $author = explode(",", preg_replace("/\s{2,}/", ' ', trim($value)));
+ $size = sizeof($author);
+// No commas therefore something like Mark Grimshaw, Mark Nicholas Grimshaw, M N Grimshaw, Mark N. Grimshaw
+ if ($size == 1)
+ {
+// Is complete surname enclosed in {...}, unless the string starts with a backslash (\) because then it is
+// probably a special latex-sign..
+// 2006.02.11 DR: in the last case, any NESTED curly braces should also be taken into account! so second
+// clause rules out things such as author="a{\"{o}}"
+//
+ if (preg_match("/(.*) {([^\\\].*)}/", $value, $matches) &&
+ !(preg_match("/(.*) {\\\.{.*}.*}/", $value, $matches2)))
+ {
+ $author = split(" ", $matches[1]);
+ $surname = $matches[2];
+ }
+ else
+ {
+ $author = split(" ", $value);
+// last of array is surname (no prefix if entered correctly)
+ $surname = array_pop($author);
+ }
+ }
+// Something like Grimshaw, Mark or Grimshaw, Mark Nicholas or Grimshaw, M N or Grimshaw, Mark N.
+ else if ($size == 2)
+ {
+// first of array is surname (perhaps with prefix)
+ list($surname, $prefix) = $this->grabSurname(array_shift($author));
+ }
+// If $size is 3, we're looking at something like Bush, Jr. III, George W
+ else
+ {
+// middle of array is 'Jr.', 'IV' etc.
+ $appellation = join(' ', array_splice($author, 1, 1));
+// first of array is surname (perhaps with prefix)
+ list($surname, $prefix) = $this->grabSurname(array_shift($author));
+ }
+ $remainder = join(" ", $author);
+ list($firstname, $initials) = $this->grabFirstnameInitials($remainder);
+ if (!empty($this->prefix))
+ $prefix = join(' ', $this->prefix);
+ $surname = $surname . ' ' . $appellation;
+ $creator = array('firstname' => utf8_encode(trim($firstname)), 'initials' => utf8_encode(trim($initials)), 'lastname' => utf8_encode(trim($surname)), 'prefix' => trim($prefix));
+ if (isset($creator))
+ {
+ $creator['type'] = $this->typeMap[$type];
+ $creator['md5'] = $this->md5sum($creator);
+ return $creator;
+ }
+ return FALSE;
+ }
+
+ function md5sum($creator)
+ {
+ $string = $creator['firstname'].$creator['initials'].$creator['lastname'];
+ $string = str_replace(' ', '', drupal_strtolower($string));
+
+ return md5($string);
+ }
+// grab firstname and initials which may be of form "A.B.C." or "A. B. C. " or " A B C " etc.
+ function grabFirstnameInitials($remainder)
+ {
+ $firstname = $initials = '';
+ $array = split(" ", $remainder);
+ foreach ($array as $value)
+ {
+ $firstChar = substr($value, 0, 1);
+ if ((ord($firstChar) >= 97) && (ord($firstChar) <= 122))
+ $this->prefix[] = $value;
+ else if (preg_match("/[a-zA-Z]{2,}/", trim($value)))
+ $firstnameArray[] = trim($value);
+ else
+ $initialsArray[] = str_replace(".", " ", trim($value));
+ }
+ if (isset($initialsArray))
+ {
+ foreach ($initialsArray as $initial)
+ $initials .= ' ' . trim($initial);
+ }
+ if (isset($firstnameArray))
+ $firstname = join(" ", $firstnameArray);
+ return array($firstname, $initials);
+ }
+// surname may have title such as 'den', 'von', 'de la' etc. - characterised by first character lowercased. Any
+// uppercased part means lowercased parts following are part of the surname (e.g. Van den Bussche)
+ function grabSurname($input)
+ {
+ $surnameArray = split(" ", $input);
+ $noPrefix = $surname = FALSE;
+ foreach ($surnameArray as $value)
+ {
+ $firstChar = substr($value, 0, 1);
+ if (!$noPrefix && (ord($firstChar) >= 97) && (ord($firstChar) <= 122))
+ $prefix[] = $value;
+ else
+ {
+ $surname[] = $value;
+ $noPrefix = TRUE;
+ }
+ }
+ if ($surname)
+ $surname = join(" ", $surname);
+ if (isset($prefix))
+ {
+ $prefix = join(" ", $prefix);
+ return array($surname, $prefix);
+ }
+ return array($surname, FALSE);
+ }
+}
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/modules/bibtexParse/PARSEENTRIES.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/modules/bibtexParse/PARSEENTRIES.php Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,561 @@
+undefinedStrings, is now returned that holds field values that are judged to be undefined strings.
+ i.e. they are a non-numeric value that is not defined in a @string{...} entry and not enclosed by braces or double-quotes.
+ This array will be empty unless the following condition is met:
+ ($this->removeDelimit || $this->expandMacro && $this->fieldExtract)
+
+ 24/04/2006 Esteban Zimanyi
+ - When an undefined string is found in function removeDelimiters return the empty string
+ - Return $this->undefinedStrings in the last position to allow compatibility with previous versions
+ - Fix management of preamble in function returnArrays
+ */
+
+// For a quick command-line test (php -f PARSEENTRIES.php) after installation, uncomment these lines:
+require_once(drupal_get_path('module', 'biblio') . '/includes/biblio.contributors.inc');
+
+/*************************
+ // Parse a file
+ $parse = NEW PARSEENTRIES();
+ $parse->expandMacro = TRUE;
+ // $array = array("RMP" =>"Rev., Mod. Phys.");
+ // $parse->loadStringMacro($array);
+ // $parse->removeDelimit = FALSE;
+ // $parse->fieldExtract = FALSE;
+ $parse->openBib("bib.bib");
+ $parse->extractEntries();
+ $parse->closeBib();
+ list($preamble, $strings, $entries, $undefinedStrings) = $parse->returnArrays();
+ print_r($preamble);
+ print "\n";
+ print_r($strings);
+ print "\n";
+ print_r($entries);
+ print "\n\n";
+ *************************/
+
+/************************
+ // Parse a bibtex PHP string
+ $bibtex_data = <<< END
+
+ @STRING{three = "THREE"}
+ @STRING{two = "TWO"}
+ @string{JRNL23 = {NatLA 23 } # " " # two # " " # three}
+
+ @article{klitzing.1,
+ author = "v. Klitzing and Dorda and Pepper",
+ title = "New method for high mark@sirfragalot.com accuracy determination of fine structure constant based on quantized hall resistance",
+ volume = "45",
+ journal = {Journal of } # JRNL23,
+ pages = "494",
+ citeulike-article-id = {12222
+ }
+ ,
+ ignoreMe = {blah}, }
+
+ @article
+ {
+ klitzing.2,
+ author = "Klaus von Klitzing",
+ title = "The Quantized Hall Effect",
+ volume = "58",
+ journal = two,
+ pages = "519",
+ }
+
+ END;
+
+ $parse = NEW PARSEENTRIES();
+ $parse->expandMacro = TRUE;
+ // $parse->removeDelimit = FALSE;
+ // $parse->fieldExtract = FALSE;
+ $array = array("RMP" =>"Rev., Mod. Phys.");
+ $parse->loadStringMacro($array);
+ $parse->loadBibtexString($bibtex_data);
+ $parse->extractEntries();
+ list($preamble, $strings, $entries, $undefinedStrings) = $parse->returnArrays();
+ print_r($preamble);
+ print "\n";
+ print_r($strings);
+ print "\n";
+ print_r($entries);
+ print "\n\n";
+
+ **********************/
+
+class PARSEENTRIES
+{
+ /**
+ * @return unknown_type
+ */
+ function PARSEENTRIES()
+ {
+ require_once(drupal_get_path('module', 'biblio_bibtex') . '/transtab_latex_unicode.inc.php');
+ $this->transtab_latex_unicode = get_transtab_latex_unicode();
+ $this->preamble = $this->strings = $this->undefinedStrings = $this->entries = array();
+ $this->count = 0;
+ $this->fieldExtract = TRUE;
+ $this->removeDelimit = TRUE;
+ $this->expandMacro = FALSE;
+ $this->parseFile = TRUE;
+ $this->outsideEntry = TRUE;
+ $this->translate_latex = TRUE;
+ }
+ // Open bib file
+ /**
+ * @param $file
+ * @return none
+ */
+ function openBib($file)
+ {
+ if (!is_file($file))
+ die;
+ ini_set('auto_detect_line_endings', true);
+ $this->fid = fopen ($file,'r');
+ $this->parseFile = TRUE;
+ }
+ // Load a bibtex string to parse it
+ function loadBibtexString($bibtex_string)
+ {
+ if (is_string($bibtex_string)) {
+ //$bibtex_string = $this->searchReplaceText($this->transtab_latex_unicode, $bibtex_string, FALSE);
+ $this->bibtexString = explode("\n",$bibtex_string);
+ } else {
+ $this->bibtexString = $bibtex_string;
+ }
+ $this->parseFile = FALSE;
+ $this->currentLine = 0;
+ }
+ function searchReplaceText($searchReplaceActionsArray, $sourceString, $includesSearchPatternDelimiters=FALSE)
+ {
+ $searchStrings = array_keys($searchReplaceActionsArray);
+ if (!$includesSearchPatternDelimiters) {
+ foreach ($searchStrings as $key => $value) {
+ $searchStrings[$key] = "/" . $value . "/"; // add search pattern delimiters
+ }
+ }
+
+ $replaceStrings= array_values($searchReplaceActionsArray);
+
+ // apply the search & replace actions defined in '$searchReplaceActionsArray' to the text passed in '$sourceString':
+ return preg_replace($searchStrings, $replaceStrings, $sourceString);
+ }
+
+ // Set strings macro
+ function loadStringMacro($macro_array)
+ {
+ $this->userStrings = $macro_array;
+ }
+ // Close bib file
+ function closeBib()
+ {
+ fclose($this->fid);
+ }
+ // Get a non-empty line from the bib file or from the bibtexString
+ function getLine()
+ {
+ if ($this->parseFile) {
+ if (!feof($this->fid)) {
+ do {
+ $line = trim(fgets($this->fid));
+ }
+ while(!feof($this->fid) && !$line);
+ return $line;
+ }
+ return FALSE;
+ }
+ else {
+ do {
+ $line = array_shift($this->bibtexString);
+ $line = trim($line);
+ $this->currentLine++;
+ }
+ while($this->bibtexString && !$line);
+ return $line;
+ }
+ } // Extract value part of @string field enclosed by double-quotes or braces.
+ // The string may be expanded with previously-defined strings
+ function extractStringValue($string)
+ {
+ // $string contains a end delimiter, remove it
+ $string = trim(substr($string,0,strlen($string)-1));
+ // remove delimiters and expand
+ $string = $this->removeDelimitersAndExpand($string);
+ return $string;
+ }
+ // Extract a field
+ function fieldSplit($seg)
+ {
+ // echo "**** ";print_r($seg);echo " ";
+ // handle fields like another-field = {}
+ $array = preg_split("/,\s*([-_.:,a-zA-Z0-9]+)\s*={1}\s*/U", $seg, PREG_SPLIT_DELIM_CAPTURE);
+ // echo "**** ";print_r($array);echo " ";
+ //$array = preg_split("/,\s*(\w+)\s*={1}\s*/U", $seg, PREG_SPLIT_DELIM_CAPTURE);
+ if (!array_key_exists(1, $array))
+ return array($array[0], FALSE);
+ return array($array[0], $array[1]);
+ }
+ // Extract and format fields
+ function reduceFields($oldString)
+ {
+ // 03/05/2005 G. Gardey. Do not remove all occurences, juste one
+ // * correctly parse an entry ended by: somefield = {aValue}}
+ $lg = strlen($oldString);
+ if ($oldString[$lg-1] == "}" || $oldString[$lg-1] == ")" || $oldString[$lg-1] == ",")
+ $oldString = substr($oldString,0,$lg-1);
+ // $oldString = rtrim($oldString, "}),");
+ $split = preg_split("/=/", $oldString, 2);
+ $string = $split[1];
+ while($string)
+ {
+ list($entry, $string) = $this->fieldSplit($string);
+ $values[] = $entry;
+ }
+ foreach ($values as $value)
+ {
+ $pos = strpos($oldString, $value);
+ $oldString = substr_replace($oldString, '', $pos, strlen($value));
+ }
+ $rev = strrev(trim($oldString));
+ if ($rev{0} != ',')
+ $oldString .= ',';
+ $keys = preg_split("/=,/", $oldString);
+ // 22/08/2004 - Mark Grimshaw
+ // I have absolutely no idea why this array_pop is required but it is. Seems to always be
+ // an empty key at the end after the split which causes problems if not removed.
+ array_pop($keys);
+ foreach ($keys as $key)
+ {
+ $value = trim(array_shift($values));
+ $rev = strrev($value);
+ // remove any dangling ',' left on final field of entry
+ if ($rev{0} == ',')
+ $value = rtrim($value, ",");
+ if (!$value)
+ continue;
+ // 21/08/2004 G.Gardey -> expand macro
+ // Don't remove delimiters now needs to know if the value is a string macro
+ // $this->entries[$this->count][strtolower(trim($key))] = trim($this->removeDelimiters(trim($value)));
+ $key = strtolower(trim($key));
+ $value = trim($value);
+ $this->entries[$this->count][$key] = $value;
+ }
+ // echo "**** ";print_r($this->entries[$this->count]);echo " ";
+ }
+ // Start splitting a bibtex entry into component fields.
+ // Store the entry type and citation.
+ function fullSplit($entry)
+ {
+ $matches = preg_split("/@(.*)[{(](.*),/U", $entry, 2, PREG_SPLIT_DELIM_CAPTURE);
+ $this->entries[$this->count]['bibtexEntryType'] = strtolower(trim($matches[1]));
+ // sometimes a bibtex entry will have no citation key
+ if (preg_match("/=/", $matches[2])) // this is a field
+ $matches = preg_split("/@(.*)\s*[{(](.*)/U", $entry, 2, PREG_SPLIT_DELIM_CAPTURE);
+ // print_r($matches); print "
";
+ $this->entries[$this->count]['bibtexCitation'] = $matches[2];
+ $this->reduceFields($matches[3]);
+ }
+
+ // Grab a complete bibtex entry
+ function parseEntry($entry)
+ {
+ set_time_limit(30); // reset the script timer to avoid timeouts
+ $entry = $this->translate_latex ? $this->searchReplaceText($this->transtab_latex_unicode, $entry, FALSE) : $entry;
+ $count = 0;
+ $lastLine = FALSE;
+ if (preg_match("/@(.*)([{(])/U", preg_quote($entry), $matches))
+ {
+ if (!array_key_exists(1, $matches))
+ return $lastLine;
+ if (preg_match("/string/i", trim($matches[1])))
+ $this->strings[] = $entry;
+ else if (preg_match("/preamble/i", trim($matches[1])))
+ $this->preamble[] = $entry;
+ else if (preg_match("/comment/i", $matches[1])); // MG (31/Jan/2006) -- ignore @comment
+ else
+ {
+ if ($this->fieldExtract)
+ $this->fullSplit($entry);
+ else
+ $this->entries[$this->count] = $entry;
+ $this->count++;
+ }
+ return $lastLine;
+ }
+ }
+
+ // Remove delimiters from a string
+ function removeDelimiters($string)
+ {
+ if ($string && ($string{0} == "\""))
+ {
+ $string = substr($string, 1);
+ $string = substr($string, 0, -1);
+ }
+ else if ($string && ($string{0} == "{"))
+ {
+ if (strlen($string) > 0 && $string[strlen($string)-1] == "}")
+ {
+ $string = substr($string, 1);
+ $string = substr($string, 0, -1);
+ }
+ }
+ else if (!is_numeric($string) && !array_key_exists($string, $this->strings)
+ && (array_search($string, $this->undefinedStrings) === FALSE))
+ {
+ $this->undefinedStrings[] = $string; // Undefined string that is not a year etc.
+ return '';
+ }
+ return $string;
+ }
+
+ // This function works like explode('#',$val) but has to take into account whether
+ // the character # is part of a string (i.e., is enclosed into "..." or {...} )
+ // or defines a string concatenation as in @string{ "x # x" # ss # {xx{x}x} }
+ function explodeString($val)
+ {
+ $openquote = $bracelevel = $i = $j = 0;
+ while ($i < strlen($val))
+ {
+ if ($val[$i] == '"')
+ $openquote = !$openquote;
+ elseif ($val[$i] == '{')
+ $bracelevel++;
+ elseif ($val[$i] == '}')
+ $bracelevel--;
+ elseif ( $val[$i] == '#' && !$openquote && !$bracelevel )
+ {
+ $strings[] = substr($val,$j,$i-$j);
+ $j=$i+1;
+ }
+ $i++;
+ }
+ $strings[] = substr($val,$j);
+ return $strings;
+ }
+
+ // This function receives a string and a closing delimiter '}' or ')'
+ // and looks for the position of the closing delimiter taking into
+ // account the following Bibtex rules:
+ // * Inside the braces, there can arbitrarily nested pairs of braces,
+ // but braces must also be balanced inside quotes!
+ // * Inside quotes, to place the " character it is not sufficient
+ // to simply escape with \": Quotes must be placed inside braces.
+ function closingDelimiter($val,$delimitEnd)
+ {
+ // echo "####>$delimitEnd $val ";
+ $openquote = $bracelevel = $i = $j = 0;
+ while ($i < strlen($val))
+ {
+ // a '"' found at brace level 0 defines a value such as "ss{\"o}ss"
+ if ($val[$i] == '"' && !$bracelevel)
+ $openquote = !$openquote;
+ elseif ($val[$i] == '{')
+ $bracelevel++;
+ elseif ($val[$i] == '}')
+ $bracelevel--;
+ if ( $val[$i] == $delimitEnd && !$openquote && !$bracelevel )
+ return $i;
+ $i++;
+ }
+ // echo "--> $bracelevel, $openquote";
+ return 0;
+ }
+
+ // Remove enclosures around entry field values. Additionally, expand macros if flag set.
+ function removeDelimitersAndExpand($string, $inpreamble = FALSE)
+ {
+ // only expand the macro if flag set, if strings defined and not in preamble
+ if (!$this->expandMacro || empty($this->strings) || $inpreamble)
+ $string = $this->removeDelimiters($string);
+ else
+ {
+ $stringlist = $this->explodeString($string);
+ $string = "";
+ foreach ($stringlist as $str)
+ {
+ // trim the string since usually # is enclosed by spaces
+ $str = trim($str);
+ // replace the string if macro is already defined
+ // strtolower is used since macros are case insensitive
+ if (isset($this->strings[strtolower($str)]))
+ $string .= $this->strings[strtolower($str)];
+ else
+ $string .= $this->removeDelimiters(trim($str));
+ }
+ }
+ return $string;
+ }
+
+ // This function extract entries taking into account how comments are defined in BibTeX.
+ // BibTeX splits the file in two areas: inside an entry and outside an entry, the delimitation
+ // being indicated by the presence of a @ sign. When this character is met, BibTex expects to
+ // find an entry. Before that sign, and after an entry, everything is considered a comment!
+ function extractEntries()
+ {
+ $inside = $possibleEntryStart = FALSE;
+ $entry="";
+ while($line=$this->getLine())
+ {
+ if ($possibleEntryStart)
+ $line = $possibleEntryStart . $line;
+ if (!$inside && strchr($line,"@"))
+ {
+ // throw all characters before the '@'
+ $line=strstr($line,'@');
+ if (!strchr($line, "{") && !strchr($line, "("))
+ $possibleEntryStart = $line;
+ elseif (preg_match("/@.*([{(])/U", preg_quote($line), $matches))
+ {
+ $inside = TRUE;
+ if ($matches[1] == '{')
+ $delimitEnd = '}';
+ else
+ $delimitEnd = ')';
+ $possibleEntryStart = FALSE;
+ }
+ }
+ if ($inside)
+ {
+ $entry .= " ".$line;
+ if ($j=$this->closingDelimiter($entry,$delimitEnd))
+ {
+ // all characters after the delimiter are thrown but the remaining
+ // characters must be kept since they may start the next entry !!!
+ $lastLine = substr($entry,$j+1);
+ $entry = substr($entry,0,$j+1);
+ // Strip excess whitespaces from the entry
+ $entry = preg_replace('/\s\s+/', ' ', $entry);
+ $this->parseEntry($entry);
+ $entry = strchr($lastLine,"@");
+ if ($entry)
+ $inside = TRUE;
+ else
+ $inside = FALSE;
+ }
+ }
+ }
+ }
+
+ // Return arrays of entries etc. to the calling process.
+ function returnArrays()
+ {
+ // global $transtab_latex_unicode; // defined in 'transtab_latex_unicode.inc.php'
+ foreach ($this->preamble as $value)
+ {
+ preg_match("/.*?[{(](.*)/", $value, $matches);
+ $preamble = substr($matches[1], 0, -1);
+ $preambles['bibtexPreamble'] = trim($this->removeDelimitersAndExpand(trim($preamble), TRUE));
+ }
+ if (isset($preambles))
+ $this->preamble = $preambles;
+ if ($this->fieldExtract)
+ {
+ // Next lines must take into account strings defined by previously-defined strings
+ $strings = $this->strings;
+ // $this->strings is initialized with strings provided by user if they exists
+ // it is supposed that there are no substitutions to be made in the user strings, i.e., no #
+ $this->strings = isset($this->userStrings) ? $this->userStrings : array() ;
+ foreach ($strings as $value)
+ {
+ // changed 21/08/2004 G. Gardey
+ // 23/08/2004 Mark G. account for comments on same line as @string - count delimiters in string value
+ $value = trim($value);
+ $matches = preg_split("/@\s*string\s*([{(])/i", $value, 2, PREG_SPLIT_DELIM_CAPTURE);
+ $delimit = $matches[1];
+ $matches = preg_split("/=/", $matches[2], 2, PREG_SPLIT_DELIM_CAPTURE);
+ // macros are case insensitive
+ $this->strings[strtolower(trim($matches[0]))] = $this->extractStringValue($matches[1]);
+ }
+ }
+ // changed 21/08/2004 G. Gardey
+ // 22/08/2004 Mark Grimshaw - stopped useless looping.
+ // removeDelimit and expandMacro have NO effect if !$this->fieldExtract
+ if ($this->removeDelimit || $this->expandMacro && $this->fieldExtract)
+ {
+ for($i = 0; $i < count($this->entries); $i++)
+ {
+ foreach ($this->entries[$i] as $key => $value)
+ // 02/05/2005 G. Gardey don't expand macro for bibtexCitation
+ // and bibtexEntryType
+ if ($key != 'bibtexCitation' && $key != 'bibtexEntryType')
+ $this->entries[$i][$key] = trim($this->removeDelimitersAndExpand($this->entries[$i][$key]));
+ }
+ }
+ // EZ: Remove this to be able to use the same instance for parsing several files,
+ // e.g., parsing a entry file with its associated abbreviation file
+ // if (empty($this->preamble))
+ // $this->preamble = FALSE;
+ // if (empty($this->strings))
+ // $this->strings = FALSE;
+ // if (empty($this->entries))
+ // $this->entries = FALSE;
+ return array($this->preamble, $this->strings, $this->entries, $this->undefinedStrings);
+ }
+
+ function &getEntries() {
+ if ($this->removeDelimit || $this->expandMacro && $this->fieldExtract)
+ {
+ for($i = 0; $i < count($this->entries); $i++)
+ {
+ foreach ($this->entries[$i] as $key => $value)
+ // 02/05/2005 G. Gardey don't expand macro for bibtexCitation
+ // and bibtexEntryType
+ if ($key != 'bibtexCitation' && $key != 'bibtexEntryType')
+ $this->entries[$i][$key] = trim($this->removeDelimitersAndExpand($this->entries[$i][$key]));
+ }
+ }
+ return $this->entries;
+ }
+
+}
+
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/modules/bibtexParse/PARSEMONTH.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/modules/bibtexParse/PARSEMONTH.php Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,117 @@
+startDay = $endMonth = $this->endDay = FALSE;
+ $date = split("#", $monthField);
+ foreach ($date as $field)
+ {
+ $field = ucfirst(strtolower(trim($field)));
+ if ($month = array_search($field, $this->monthToLongName()))
+ {
+ if (!$startMonth)
+ $startMonth = $month;
+ else
+ $endMonth = $month;
+ continue;
+ }
+ else if ($month = array_search($field, $this->monthToShortName()))
+ {
+ if (!$startMonth)
+ $startMonth = $month;
+ else
+ $endMonth = $month;
+ continue;
+ }
+ $this->parseDay($field);
+ }
+ if ($this->endDay && !$endMonth)
+ $endMonth = $startMonth;
+ return array($startMonth, $this->startDay, $endMonth, $this->endDay);
+ }
+// extract day of month from field
+ function parseDay($dayField)
+ {
+ preg_match("/([0-9]+).*([0-9]+)|([0-9]+)/", $dayField, $array);
+ if (array_key_exists(3, $array))
+ {
+ if (!$this->startDay)
+ $this->startDay = $array[3];
+ else if (!$this->endDay)
+ $this->endDay = $array[3];
+ }
+ else
+ {
+ if (array_key_exists(1, $array))
+ $this->startDay = $array[1];
+ if (array_key_exists(2, $array))
+ $this->endDay = $array[2];
+ }
+ }
+// Convert month to long name
+ function monthToLongName()
+ {
+ return array(
+ 1 => 'January',
+ 2 => 'February',
+ 3 => 'March',
+ 4 => 'April',
+ 5 => 'May',
+ 6 => 'June',
+ 7 => 'July',
+ 8 => 'August',
+ 9 => 'September',
+ 10 => 'October',
+ 11 => 'November',
+ 12 => 'December',
+ );
+ }
+// Convert month to short name
+ function monthToShortName()
+ {
+ return array(
+ 1 => 'Jan',
+ 2 => 'Feb',
+ 3 => 'Mar',
+ 4 => 'Apr',
+ 5 => 'May',
+ 6 => 'Jun',
+ 7 => 'Jul',
+ 8 => 'Aug',
+ 9 => 'Sep',
+ 10 => 'Oct',
+ 11 => 'Nov',
+ 12 => 'Dec',
+ );
+ }
+}
+?>
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/modules/bibtexParse/PARSEPAGE.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/modules/bibtexParse/PARSEPAGE.php Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,66 @@
+type1($item))
+ return $this->return;
+// else, return first number we can find
+ if (preg_match("/(\d+|[ivx]+)/i", $item, $array))
+ return array($array[1], FALSE);
+// No valid page numbers found
+ return array(FALSE, FALSE);;
+ }
+// "77--99" or '-'type?
+ function type1($item)
+ {
+ $start = $end = FALSE;
+ $array = preg_split("/--|-/", $item);
+ if (sizeof($array) > 1)
+ {
+ if (is_numeric(trim($array[0])))
+ $start = trim($array[0]);
+ else
+ $start = strtolower(trim($array[0]));
+ if (is_numeric(trim($array[1])))
+ $end = trim($array[1]);
+ else
+ $end = strtolower(trim($array[1]));
+ if ($end && !$start)
+ $this->return = array($end, $start);
+ else
+ $this->return = array($start, $end);
+ return TRUE;
+ }
+ return FALSE;
+ }
+}
+?>
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/modules/bibtexParse/README
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/modules/bibtexParse/README Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,96 @@
+Released through http://bibliophile.sourceforge.net under the GPL licence.
+Do whatever you like with this -- some credit to the author(s) would be appreciated.
+
+A collection of PHP classes to manipulate bibtex files.
+
+If you make improvements, please consider contacting the administrators at bibliophile.sourceforge.net so that your improvements can be added to the release package.
+
+Mark Grimshaw & Guillaume Gardey 2004 - 2006
+http://bibliophile.sourceforge.net
+
+################################################
+PARSEENTRIES
+############
+This reads the contents of a BibTeX .bib file or a PHP string and returns arrays of information representing @preamble, @string and valid BibTeX entries.
+
+Entries may be enclosed by {...} or (...). Fields values may be enclosed by "...", {...} or without enclosure.
+
+FLAGS can be set:
+$parse->fieldExtract;
+$parse->removeDelimit;
+$parse->expandMacro = FALSE/TRUE to expand macros within BibTeX entries ('#' and @string values).
+
+If $parse->fieldExtract == TRUE (default), the $entries array using the supplied example bib.bib file will be:
+Array
+(
+ [0] => Array
+ (
+ [bibtexEntryType] => article
+ [bibtexCitation] => klitzing:qhe
+ [author] => K. v. Klitzing and G. Dorda = "and M. Pepper
+ [title] => New method for h{\i}gh mark@sirfragalot.com accuracy determination of fine structure constant based on quantized hall resistance
+ [journal] => PRL
+ [volume] => 45
+ [pages] => 494
+ [blah] => bl"ah
+ [year] => 1980
+ )
+
+ [1] => Array
+ (
+ [bibtexEntryType] => article
+ [bibtexCitation] => klitzing:nobel
+ [author] => Klaus von Klitzing
+ [title] => The Quantized Hall Effect
+ [journal] => RMP
+ [volume] => 58
+ [pages] => 519
+ [year] => 1986
+ )
+)
+
+In other words, an array of separate BibTeX entries each one an array comprising the fields, entry type and given citation. @strings will be similarly formatted.
+
+If $parse->fieldExtract == FALSE, the $entries array using the supplied example bib.bib file will be:
+Array
+(
+ [0] => @ARTICLE{klitzing:qhe, AUTHOR="K. v. Klitzing and G. Dorda = "and M. Pepper", TITLE="New method for h{\i}gh mark@sirfragalot.com accuracy determination of fine structure constant based on quantized hall resistance", JOURNAL=PRL, VOLUME= 45, PAGES=494, blah=" bl"ah ", YEAR=1980 },
+ [1] => @ARTICLE(klitzing:nobel, AUTHOR={Klaus von Klitzing}, TITLE="The Quantized Hall Effect",JOURNAL=RMP, VOLUME=58, PAGES=519, YEAR=1986 )
+)
+
+In other words, an array of separate BibTeX entries with no further processing. @strings will be similarly formatted.
+NB - IF fieldExtract == FALSE, SETTINGS FOR expandMacro AND removeDelimit WILL HAVE NO EFFECT.
+
+If $parse->removeDelimit == TRUE (default), all double-quotes or braces that enclose field values of BibTeX entries/strings will be removed. Otherwise, they will be left in place. Setting this to TRUE only has an effect if $parse->fieldExtract is TRUE.
+
+In all cases, @preamble (from the given example bib.bib file) will be returned as:
+Array
+(
+ [bibtexPreamble] => Blah blah blah some preamble or other r
+)
+
+Additional BibTeX macro can be supplied to the parser:
+$more_macro = array("RMP" => "Rev., Mod. Phys.", "LNCS" => "Lecture Notes in Computer Science");
+$parse->loadStringMacro($more_macro);
+
+$parse->returnArrays() will then return $entries with all BibTeX macros (BibTeX file + $more_macro) expanded.
+
+
+################################################
+PARSECREATORS
+#############
+This takes a BibTeX author or editor field and splits it into the component writers returning a multidimensional array consisting of writer arrays comprised of array(firstname(s), initials, surname). It attempts to recognise 'et. al' or 'et. al.' and returns either FALSE or TRUE if that exists. If the input is 'Anon', 'anon', 'Anonymous' or 'anonymous' FALSE is returned.
+################################################
+
+
+################################################
+PARSEMONTH
+#############
+Split a bibtex month field into day and month components including date ranges.
+ list($startMonth, $startDay, $endMonth, $endDay) = $parseMonth->init($monthField);
+
+################################################
+PARSEPAGE
+#############
+Split a bibtex pages field into page start and page end components.
+ list($start, $end) = $parsePage->init($pagesField);
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/modules/bibtexParse/bib.bib
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/modules/bibtexParse/bib.bib Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,44 @@
+
+
+
+@STrinG{PRL="Phys. Rev.
+Lett."}
+
+@preAmbLE {"Blah blah blah some preamble or other
+r"}
+
+%%some comments
+
+
+ @ARTICLE{klitzing:qhe,
+ AUTHOR="K. v. Klitzing and G. Dorda = "and M.
+Pepper",
+
+
+ TITLE="New method for h{\i}gh mark@sirfragalot.com accuracy determination of fine structure
+constant based on quantized hall resistance",
+JOURNAL=PRL,
+%%some comments
+
+ VOLUME=
+
+45,
+
+PAGES=494,
+blah=" bl"ah ",
+YEAR=1980 # Aug
+}
+
+%% @stRING(
+%%RMP="Rev., Mod.
+%%Phys.")
+ @ARTICLE
+(klitzing:nobel,
+AUTHOR={Klaus von Klitzing},
+TITLE="The Quantized Hall Effect",JOURNAL=RMP,
+VOLUME=58,
+PAGES=519,
+YEAR=1986
+)
+
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/modules/bibtexParse/biblio_bibtex.info
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/modules/bibtexParse/biblio_bibtex.info Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,14 @@
+name = Biblio - BibTex
+description = Provides BibTex import and export to the Biblio module.
+core = 7.x
+package = Biblio
+dependencies[] = biblio
+files[] = PARSEENTRIES.php
+files[] = views/biblio_handler_field_export_link_bibtex.inc
+
+; Information added by drupal.org packaging script on 2013-07-20
+version = "7.x-1.0-rc7"
+core = "7.x"
+project = "biblio"
+datestamp = "1374290470"
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/modules/bibtexParse/biblio_bibtex.install
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/modules/bibtexParse/biblio_bibtex.install Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,165 @@
+condition('format', 'bibtex')
+ ->execute();
+ }
+}
+
+function biblio_bibtex_enable() {
+ biblio_bibtex_set_system_weight();
+}
+
+function biblio_bibtex_set_system_weight() {
+ db_update('system')
+ ->fields(array('weight' => 22))
+ ->condition('name', 'biblio_bibtex')
+ ->execute();
+}
+
+
+function _get_bibtex_type_map() {
+ $map['type_map'] = serialize(
+ array(
+ 'article' => 102,
+ 'book' => 100,
+ 'booklet' => 129,
+ 'conference' => 103,
+ 'inbook' => 101,
+ 'incollection' => 101,
+ 'inproceedings' => 103,
+ 'manual' => 129,
+ 'mastersthesis' => 108,
+ 'misc' => 129,
+ 'phdthesis' => 108,
+ 'proceedings' => 104,
+ 'techreport' => 129,
+ 'unpublished' => 124,
+ )
+ );
+ $map['format'] = 'bibtex';
+ return $map;
+
+}
+
+function _get_bibtex_type_names() {
+ $map['type_names'] = serialize(
+ array(
+ 'article' => 'An article from a journal',
+ 'book' => 'A book with an explicit publisher',
+ 'booklet' => 'A work that is printed and bound, but without a named publisher or sponsoring institution',
+ 'conference' => 'An article in a conference proceedings',
+ 'inbook' => 'A part of a book, usually untitled. May be a chapter (or section or whatever) and/or a range of pages',
+ 'incollection' => 'A part of a book having its own title',
+ 'inproceedings' => 'An article in a conference proceedings',
+ 'manual' => 'Technical documentation',
+ 'mastersthesis' => 'A Master\'s thesis',
+ 'misc' => 'For use when nothing else fits',
+ 'phdthesis' => 'A Ph.D. thesis',
+ 'proceedings' => 'The proceedings of a conference',
+ 'techreport' => 'A report published by a school or other institution, usually numbered within a series',
+ 'unpublished' => 'A document having an author and title, but not formally published',
+ )
+ );
+ $map['format'] = 'bibtex';
+ return $map;
+
+}
+function _get_bibtex_field_map() {
+
+ $map['field_map'] = serialize(
+ array(
+ 'journal' => 'biblio_secondary_title',
+ 'booktitle' => 'biblio_secondary_title',
+ 'series' => 'biblio_secondary_title',
+ 'volume' => 'biblio_volume',
+ 'number' => 'biblio_number',
+ 'year' => 'biblio_year',
+ 'note' => 'biblio_notes',
+ 'month' => 'biblio_date',
+ 'pages' => 'biblio_pages',
+ 'publisher' => 'biblio_publisher',
+ 'school' => 'biblio_publisher',
+ 'organization' => 'biblio_publisher',
+ 'institution' => 'biblio_publisher',
+ 'type' => 'biblio_type_of_work',
+ 'edition' => 'biblio_edition',
+ 'chapter' => 'biblio_section',
+ 'address' => 'biblio_place_published',
+ 'abstract' => 'biblio_abst_e',
+ 'keywords' => 'biblio_keywords',
+ 'isbn' => 'biblio_isbn',
+ 'issn' => 'biblio_issn',
+ 'doi' => 'biblio_doi',
+ 'url' => 'biblio_url',
+
+ )
+ );
+
+ $map['format'] = 'bibtex';
+ return $map;
+
+}
+
+function _save_bibtex_maps() {
+ $typemap = _get_bibtex_type_map();
+ $typenames = _get_bibtex_type_names();
+ $fieldmap = _get_bibtex_field_map();
+ $maps = array_merge($typemap, $typenames, $fieldmap);
+ biblio_save_map($maps);
+}
+
+function _reset_bibtex_map($type) {
+ $count = db_query("SELECT COUNT(*) FROM {biblio_type_maps} WHERE format='bibtex'")->fetchField();
+ if ($count && $type) { //update
+ $function = '_get_bibtex_' . $type;
+ if (!function_exists($function)) return;
+ $map = $function();
+ db_update('biblio_type_maps')
+ ->fields($map)
+ ->condition('format', 'bibtex')
+ ->execute();
+ }
+ else { // install
+ db_delete('biblio_type_maps')
+ ->condition('format', 'bibtex')
+ ->execute();
+ _save_bibtex_maps();
+ }
+}
+
+function biblio_bibtex_schema() {
+ $schema = array();
+ $schema['biblio_bibtex'] = array(
+ 'fields' => array(
+ 'nid' => array('type' => 'int', 'not null' => TRUE),
+ 'biblio_bibtex_md5' => array('type' => 'char', 'length' => 32, 'not null' => TRUE),
+ 'biblio_bibtex_id' => array('type' => 'varchar', 'length' => 255, 'not null' => FALSE),
+ ),
+ 'primary key' => array('nid'),
+ );
+ return $schema;
+}
+
+function biblio_bibtex_update_7001() {
+ if (!db_field_exists('biblio_bibtex', 'biblio_bibtex_id')) {
+ $spec = array('type' => 'varchar', 'length' => 255, 'not null' => FALSE);
+ db_add_field('biblio_bibtex', 'biblio_bibtex_id', $spec);
+ }
+}
+
+
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/modules/bibtexParse/biblio_bibtex.module
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/modules/bibtexParse/biblio_bibtex.module Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,455 @@
+ 2,
+ 'path' => drupal_get_path('module', 'biblio_bibtex') . '/views',
+ );
+}
+/*
+ * add the BibTex option to the option list of the biblio_import_form
+ * the key is the module name use by module_invoke to call hook_biblio_import
+ * module_invoke('biblio_bibtex', 'biblio_import',...)
+ */
+function biblio_bibtex_biblio_import_options() {
+ return array('biblio_bibtex' => t('BibTex'));
+}
+function biblio_bibtex_biblio_mapper_options() {
+ return array(
+ 'bibtex' => array(
+ 'title' => t('BibTex'),
+ 'export' => TRUE,
+ )
+ );
+}
+
+function biblio_bibtex_form_biblio_node_form_alter(&$form, &$form_state) {
+ global $user;
+ if (!$form_state['submitted'] && !isset($form_state['values']) && !isset($form['#node']->nid)) {
+ if (!$form_state['submitted']) {
+ $form['biblio_cut_paste'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Paste BibTex Record'),
+ '#weight' => -20,
+ '#collapsible' => TRUE,
+ '#collapsed' => TRUE,
+ );
+ $form['biblio_cut_paste']['paste_data_bibtex'] = array(
+ '#type' => 'textarea',
+ '#title' => t('BibTex'),
+ '#required' => FALSE,
+ '#default_value' => isset($form_state['values']['paste_data_bibtex']) ? $form_state['values']['paste_data_bibtex'] : '',
+ '#description' => t('Paste a BibTex entry here'),
+ '#size' => 60,
+ '#weight' => -4
+ );
+ $form['biblio_cut_paste']['paste_submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Populate using BibTex'),
+ '#submit' => array('biblio_bibtex_form_biblio_node_form_submit')
+ );
+ }
+ }
+ $biblio_bibtex_id = (isset($form_state['values']['biblio_bibtex_id'])) ? $form_state['values']['biblio_bibtex_id'] : '';
+ $biblio_bibtex_md5 = (isset($form_state['values']['biblio_bibtex_md5'])) ? $form_state['values']['biblio_bibtex_md5'] : '';
+ $form['biblio_bibtex_id'] = array('#type' => 'value', '#value' => $biblio_bibtex_id);
+ $form['biblio_bibtex_md5'] = array('#type' => 'value', '#value' => $biblio_bibtex_md5);
+}
+
+function biblio_bibtex_form_biblio_node_form_submit($form, &$form_state) {
+ global $user;
+ $node_data = array();
+ $dups = array();
+
+ if (strlen($form_state['values']['paste_data_bibtex'])) {
+ list($node_data, $dups) = biblio_bibtex_biblio_import($form_state['values']['paste_data_bibtex'], array(), FALSE, NULL, FALSE, TRUE);
+ }
+ if (!empty($node_data) && is_object($node_data[0])) {
+ $form_state['values'] = array_merge($form_state['values'], (array)$node_data[0]);
+ $form_state['input']['biblio_type'] = $form_state['biblio_type'] = $node_data[0]->biblio_type;
+
+// $form_state['storage']['biblio_type'] = $node_data[0]->biblio_type;
+ }
+ elseif (!empty($dups)) {
+ $message = t('The bibtex node that you are trying to paste into the form already exists in the database, see !url', array('!url' => l('node/' . $dups[0], 'node/' . $dups[0])));
+ form_set_error('paste_data_bibtex', $message);
+ }
+ $form_state['rebuild'] = TRUE;
+
+ return;
+}
+
+function biblio_bibtex_biblio_export_options() {
+ return array('bibtex' => t('BibTex'));
+}
+
+function biblio_bibtex_node_view($node, $view_mode) {
+ if ($node->type == 'biblio') {
+ switch ($view_mode) {
+ case 'full':
+ case 'teaser':
+ $links = biblio_bibtex_biblio_export_link($node->nid);
+ $node->content['links']['biblio_bibtex'] = array(
+ '#links' => $links,
+ '#attributes' => array('class' => array('links', 'inline')),
+ );
+ }
+ }
+}
+
+/**
+ * Creates a link to export a node (or view) in BibTEX format
+ *
+ * @param $base this is the base url (defaults to /biblio)
+ * @param $nid the node id, if NULL then the current view is exported
+ * @return a link (BibTEX)
+ */
+function biblio_bibtex_biblio_export_link($nid = NULL, $filter = array()) {
+ $show_link = variable_get('biblio_export_links', array('bibtex' => TRUE));
+ if (!isset($show_link['bibtex']) || !biblio_access('export')) return array();
+ $base = variable_get('biblio_base', 'biblio');
+
+ if (module_exists('popups') && !empty($nid)) {
+ $link = array(
+ 'attributes' => array(
+ 'class' => 'popups',
+ 'title' => t("Click to get the BibTEX output")));
+ }
+ else {
+ $link = array(
+ 'attributes' => array(
+ 'title' => t("Click to download the BibTEX formatted file")));
+ }
+ $link['attributes'] += array('rel' => 'nofollow');
+
+ $link['href'] = "$base/export/bibtex" ;
+ if (!empty($nid)) {
+ $link['href'] .= '/' . $nid;
+ }
+ $link['title'] = t('BibTex');
+
+ if (empty($nid) && !empty($filter)) { // add any filters which may be on the current page
+ $link['query'] = $filter;
+ }
+
+ return array('biblio_bibtex' => $link);
+}
+
+function biblio_bibtex_node_delete($node) {
+ if ($node->type != 'biblio') {
+ return;
+ }
+ db_delete('biblio_bibtex')
+ ->condition('nid', $node->nid)
+ ->execute();
+}
+
+function biblio_bibtex_node_insert($node) {
+ if ($node->type != 'biblio') {
+ return;
+ }
+ if (!isset($node->biblio_bibtex_md5)) {
+ return;
+ }
+ drupal_write_record('biblio_bibtex', $node);
+}
+
+function biblio_bibtex_biblio_import($file, $terms = array(), $batch = FALSE, $session_id = NULL, $save = TRUE, $string = FALSE) {
+ $nids = array();
+ $dups = array();
+
+ module_load_include('php', 'biblio_bibtex', 'PARSEENTRIES');
+ $bibtex = new PARSEENTRIES();
+
+ if ($string) {
+ $bibtex->loadBibtexString($file);
+ }
+ else {
+ $bibtex->openBib($file->uri);
+ }
+
+ $bibtex->extractEntries();
+
+ if ($bibtex->count) {
+ $entries =& $bibtex->getEntries();
+ list($nids, $dups) = _biblio_bibtex_import($entries, $terms, $batch, $session_id, $save);
+ }
+ return array($nids, $dups);
+}
+function biblio_bibtex_biblio_export($nids) {
+ if (module_exists('popups') && $nid) {
+ $popup = TRUE;
+ }
+ else {
+ $popup = FALSE;
+ drupal_add_http_header('Content-type', 'application/text; charset=utf-8');
+ drupal_add_http_header('Content-Disposition', 'attachment; filename="Biblio-Bibtex.bib"');
+ }
+
+ $nodes = node_load_multiple($nids, array(), TRUE);
+ foreach ($nodes as $node) {
+ if (!$popup) {
+ print _biblio_bibtex_export($node);
+ }
+ else{
+ $popup_data .= _biblio_bibtex_export($node);
+ }
+ }
+ if ($popup && !empty($popup_data)) return '
";
+
+?>
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/modules/marcParse/php-marc.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/modules/marcParse/php-marc.php Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,1016 @@
+
+//
+//-----------------------------------------------------------------------------
+//
+// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+//-----------------------------------------------------------------------------
+//
+// $Revision$
+//
+//-----------------------------------------------------------------------------
+
+/**
+ * Hexadecimal value for Subfield indicator
+ * @global hex SUBFIELD_INDICATOR
+ */
+define("SUBFIELD_INDICATOR", "\x1F");
+/**
+ * Hexadecimal value for End of Field
+ * @global hex END_OF_FIELD
+ */
+define("END_OF_FIELD", "\x1E");
+/**
+ * Hexadecimal value for End of Record
+ * @global hex END_OF_RECORD
+ */
+define("END_OF_RECORD", "\x1D");
+/**
+ * Length of the Directory
+ * @global integer DIRECTORY_ENTRY_LEN
+ */
+define("DIRECTORY_ENTRY_LEN", 12);
+/**
+ * Length of the Leader
+ * @global integer LEADER_LEN
+ */
+define("LEADER_LEN", 24);
+
+/**
+ * Class File
+ * Class to read MARC records from file(s)
+ */
+Class File {
+
+ /**
+ * ========== VARIABLE DECLARATIONS ==========
+ */
+
+ /**
+ * Array containing raw records
+ * @var array
+ */
+ var $raw;
+ /**
+ * Array of warnings
+ * @var array
+ */
+ var $warn;
+ /**
+ * Current position in the array of records
+ * @var integer
+ */
+ var $pointer;
+
+ /**
+ * ========== ERROR FUNCTIONS ==========
+ */
+
+ /**
+ * Croaking function
+ *
+ * Similar to Perl's croak function, which ends parsing and raises an
+ * user error with a descriptive message.
+ * @param string The message to display
+ */
+ function _croak($msg) {
+ trigger_error($msg, E_USER_ERROR);
+ }
+
+ /**
+ * Fuction to issue warnings
+ *
+ * Warnings will not be displayed unless explicitly accessed, but all
+ * warnings issued during parse will be stored
+ * @param string Warning
+ * @return string Last added warning
+ */
+ function _warn($msg) {
+ $this->warn[] = $msg;
+ return $msg;
+ }
+
+ /**
+ * Get warning(s)
+ *
+ * Get either all warnings or a specific warning ID
+ * @param integer ID of the warning
+ * @return array|string Return either Array of all warnings or specific warning
+ */
+ function warnings($id = "") {
+ if (!$id) {
+ return $this->warn;
+ } else {
+ if (array_key_exists($id, $this->warn)) {
+ return $this->warn[$id];
+ } else {
+ return "Invalid warning ID: $id";
+ }
+ }
+ }
+
+ /**
+ * ========== PROCESSING FUNCTIONS ==========
+ */
+
+ /**
+ * Return the next raw MARC record
+ *
+ * Returns th nexts raw MARC record from the read file, unless all
+ * records already have been read.
+ * @return string|FALSE Either a raw record or False
+ */
+ function _next() {
+ /**
+ * Exit if we are at the end of the file
+ */
+ if ($this->pointer >= count($this->raw)) {
+ return FALSE;
+ }
+
+ /**
+ * Read next line
+ */
+ $usmarc = $this->raw[$this->pointer++];
+
+ // remove illegal stuff that sometimes occurs between records
+ // preg_replace does not know what to do with \x00, thus omitted.
+ $usmarc = preg_replace("/^[\x0a\x0d]+/", "", $usmarc);
+
+ /**
+ * Record validation
+ */
+ if ( strlen($usmarc) < 5 ) {
+ $this->_warn( "Couldn't find record length" );
+ }
+ $reclen = substr($usmarc,0,5);
+ if ( preg_match("/^\d{5}$/", $reclen) || $reclen != strlen($usmarc) ) {
+ $this->_warn( "Invalid record length \"$reclen\"" );
+ }
+
+ return $usmarc;
+ }
+
+ /**
+ * Read in MARC record file
+ *
+ * This function will read in MARC record files that either
+ * contain a single MARC record, or numerous records.
+ * @param string Name of the file
+ * @return string Returns warning if issued during read
+ */
+ function file($in) {
+ if (file_exists($in)) {
+ $input = file($in);
+ $recs = explode(END_OF_RECORD, join("", $input));
+ // Append END_OF_RECORD as we lost it when splitting
+ // Last is not record, as it is empty because every record ends
+ // with END_OF_RECORD.
+ for ($i = 0; $i < (count($recs)-1); $i++) {
+ $this->raw[] = $recs[$i].END_OF_RECORD;
+ }
+ $this->pointer = 0;
+ } else {
+ return $this->_warn("Invalid input file: $i");
+ }
+ }
+
+ /**
+ * Return next Record-object
+ *
+ * Decode the next raw MARC record and return
+ * @return Record A Record object
+ */
+ function next() {
+ if ($raw = $this->_next()) {
+ return $this->decode($raw);
+ } else {
+ return FALSE;
+ }
+ }
+
+ /**
+ * Decode a given raw MARC record
+ *
+ * "Port" of Andy Lesters MARC::File::USMARC->decode() function into PHP. Ideas and
+ * "rules" have been used from USMARC::decode().
+ *
+ * @param string Raw MARC record
+ * @return Record Decoded MARC Record object
+ */
+ function decode($text) {
+ if (!preg_match("/^\d{5}/", $text, $matches)) {
+ $this->_croak('Record length "'.substr( $text, 0, 5 ).'" is not numeric');
+ }
+
+ $marc = new Record;
+
+ // Store record length
+ $reclen = $matches[0];
+
+ if ($reclen != strlen($text)) {
+ $this->_croak( "Invalid record length: Leader says $reclen bytes, but it's actually ".strlen($text));
+ }
+
+ if (substr($text, -1, 1) != END_OF_RECORD)
+ $this->_croak("Invalid record terminator");
+
+ // Store leader
+ $marc->leader(substr( $text, 0, LEADER_LEN ));
+
+ // bytes 12 - 16 of leader give offset to the body of the record
+ $data_start = 0 + substr( $text, 12, 5 );
+
+ // immediately after the leader comes the directory (no separator)
+ $dir = substr( $text, LEADER_LEN, $data_start - LEADER_LEN - 1 ); // -1 to allow for \x1e at end of directory
+
+ // character after the directory must be \x1e
+ if (substr($text, $data_start-1, 1) != END_OF_FIELD) {
+ $this->_croak("No directory found");
+ }
+
+ // All directory entries 12 bytes long, so length % 12 must be 0
+ if (strlen($dir) % DIRECTORY_ENTRY_LEN != 0) {
+ $this->_croak("Invalid directory length");
+ }
+
+ // go through all the fields
+ $nfields = strlen($dir) / DIRECTORY_ENTRY_LEN;
+ for ($n=0; $n<$nfields; $n++) {
+ // As pack returns to key 1, leave place 0 in list empty
+ list(, $tagno) = unpack("A3", substr($dir, $n*DIRECTORY_ENTRY_LEN, DIRECTORY_ENTRY_LEN));
+ list(, $len) = unpack("A3/A4", substr($dir, $n*DIRECTORY_ENTRY_LEN, DIRECTORY_ENTRY_LEN));
+ list(, $offset) = unpack("A3/A4/A5", substr($dir, $n*DIRECTORY_ENTRY_LEN, DIRECTORY_ENTRY_LEN));
+
+ // Check directory validity
+ if (!preg_match("/^[0-9A-Za-z]{3}$/", $tagno)) {
+ $this->_croak("Invalid tag in directory: \"$tagno\"");
+ }
+ if (!preg_match("/^\d{4}$/", $len)) {
+ $this->_croak("Invalid length in directory, tag $tagno: \"$len\"");
+ }
+ if (!preg_match("/^\d{5}$/", $offset)) {
+ $this->_croak("Invalid offset in directory, tag $tagno: \"$offset\"");
+ }
+ if ($offset + $len > $reclen) {
+ $this->_croak("Directory entry runs off the end of the record tag $tagno");
+ }
+
+ $tagdata = substr( $text, $data_start + $offset, $len );
+
+ if ( substr($tagdata, -1, 1) == END_OF_FIELD ) {
+ # get rid of the end-of-tag character
+ $tagdata = substr($tagdata, 0, -1);
+ --$len;
+ } else {
+ $this->_croak("field does not end in end of field character in tag $tagno");
+ }
+
+ if ( preg_match("/^\d+$/", $tagno) && ($tagno < 10) ) {
+ $marc->append_fields(new Field($tagno, $tagdata));
+ } else {
+ $subfields = explode(SUBFIELD_INDICATOR, $tagdata);
+ $indicators = array_shift($subfields);
+
+ if ( strlen($indicators) > 2 || strlen( $indicators ) == 0 ) {
+ $this->_warn("Invalid indicators \"$indicators\" forced to blanks for tag $tagno\n");
+ list($ind1,$ind2) = array(" ", " ");
+ } else {
+ $ind1 = substr( $indicators, 0, 1 );
+ $ind2 = substr( $indicators, 1, 1 );
+ }
+
+ // Split the subfield data into subfield name and data pairs
+ $subfield_data = array();
+ foreach ($subfields as $subfield) {
+ if ( strlen($subfield) > 0 ) {
+ $subfield_data[substr($subfield, 0, 1)][] = substr($subfield, 1);
+ } else {
+ $this->_warn( "Entirely empty subfield found in tag $tagno" );
+ }
+ }
+
+ if (!isset($subfield_data)) {
+ $this->_warn( "No subfield data found $location for tag $tagno" );
+ }
+
+ $marc->append_fields(new Field($tagno, $ind1, $ind2, $subfield_data ));
+ }
+ }
+ return $marc;
+ }
+
+ /**
+ * Get the number of records available in this Record
+ * @return int The number of records
+ */
+ function num_records() {
+ return count($this->raw);
+ }
+}
+
+/**
+ * USMARC Class
+ * Extension class to File class, which allows passing of raw MARC string
+ * instead of filename
+ */
+Class USMARC Extends File {
+ /**
+ * Read raw MARC string for decoding
+ * @param string Raw MARC
+ */
+ function usmarc($string) {
+ $this->raw[] = $string;
+ $this->pointer = 0;
+ }
+}
+
+/**
+ * Record Class
+ * Create a MARC Record class
+ */
+Class Record {
+
+ /**
+ * ========== VARIABLE DECLARATIONS ==========
+ */
+
+ /**
+ * Contain all @link Field objects of the Record
+ * @var array
+ */
+ var $fields;
+ /**
+ * Leader of the Record
+ * @var string
+ */
+ var $ldr;
+ /**
+ * Array of warnings
+ * @var array
+ */
+ var $warn;
+
+ /**
+ * ========== ERROR FUNCTIONS ==========
+ */
+
+ /**
+ * Croaking function
+ *
+ * Similar to Perl's croak function, which ends parsing and raises an
+ * user error with a descriptive message.
+ * @param string The message to display
+ */
+ function _croak($msg) {
+ trigger_error($msg, E_USER_ERROR);
+ }
+
+ /**
+ * Fuction to issue warnings
+ *
+ * Warnings will not be displayed unless explicitly accessed, but all
+ * warnings issued during parse will be stored
+ * @param string Warning
+ * @return string Last added warning
+ */
+ function _warn($msg) {
+ $this->warn[] = $msg;
+ return $msg;
+ }
+
+ /**
+ * Return an array of warnings
+ */
+ function warnings() {
+ return $this->warn;
+ }
+
+ /**
+ * ========== PROCESSING FUNCTIONS ==========
+ */
+
+ /**
+ * Start function
+ *
+ * Set all variables to defaults to create new Record object
+ */
+ function record() {
+ $this->fields = array();
+ $this->ldr = str_repeat(' ', 24);
+ }
+
+ /**
+ * Get/Set Leader
+ *
+ * If argument specified, sets leader, otherwise gets leader. No validation
+ * on the specified leader is performed
+ * @param string Leader
+ * @return string|null Return leader in case requested.
+ */
+ function leader($ldr = "") {
+ if ($ldr) {
+ $this->ldr = $ldr;
+ } else {
+ return $this->ldr;
+ }
+ }
+
+ /**
+ * Append field to existing
+ *
+ * Given Field object will be appended to the existing list of fields. Field will be
+ * appended last and not in its "correct" location.
+ * @param Field The field to append
+ */
+ function append_fields($field) {
+ if (strtolower(get_class($field)) == "field") {
+ $this->fields[$field->tagno][] = $field;
+ } else {
+ $this->_croak(sprintf("Given argument must be Field object, but was '%s'", get_class($field)));
+ }
+ }
+
+ /**
+ * Build Record Directory
+ *
+ * Generate the directory of the Record according to existing data.
+ * @return array Array ( $fields, $directory, $total, $baseaddress )
+ */
+ function _build_dir() {
+ // Vars
+ $fields = array();
+ $directory = array();
+
+ $dataend = 0;
+ foreach ($this->fields as $field_group ) {
+ foreach ($field_group as $field) {
+ // Get data in raw format
+ $str = $field->raw();
+ $fields[] = $str;
+
+ // Create directory entry
+ $len = strlen($str);
+ $direntry = sprintf( "%03s%04d%05d", $field->tagno(), $len, $dataend );
+ $directory[] = $direntry;
+ $dataend += $len;
+ }
+ }
+
+ /**
+ * Rules from MARC::Record::USMARC
+ */
+ $baseaddress =
+ LEADER_LEN + // better be 24
+ ( count($directory) * DIRECTORY_ENTRY_LEN ) +
+ // all the directory entries
+ 1; // end-of-field marker
+
+
+ $total =
+ $baseaddress + // stuff before first field
+ $dataend + // Length of the fields
+ 1; // End-of-record marker
+
+ return array($fields, $directory, $total, $baseaddress);
+ }
+
+ /**
+ * Set Leader lengths
+ *
+ * Set the Leader lengths of the record according to defaults specified in
+ * http://www.loc.gov/marc/bibliographic/ecbdldrd.html
+ */
+ function leader_lengths($reclen, $baseaddr) {
+ $this->ldr = substr_replace($this->ldr, sprintf("%05d", $reclen), 0, 5);
+ $this->ldr = substr_replace($this->ldr, sprintf("%05d", $baseaddr), 12, 5);
+ $this->ldr = substr_replace($this->ldr, '22', 10, 2);
+ $this->ldr = substr_replace($this->ldr, '4500', 20, 4);
+ }
+
+ /**
+ * Return all Field objects
+ * @return array Array of Field objects
+ */
+ function fields() {
+ return $this->fields;
+ }
+
+ /**
+ * Get specific field
+ *
+ * Search for field in Record fields based on field name, e.g. 020
+ * @param string Field name
+ * @return Field|FALSE Return Field if found, otherwise FALSE
+ */
+ function field($spec) {
+ if (array_key_exists($spec, $this->fields)) {
+ return $this->fields[$spec][0];
+ } else {
+ return FALSE;
+ }
+ }
+
+ /**
+ * Get subfield of Field object
+ *
+ * Returns the value of a specific subfield of a given Field object
+ * @param string Name of field
+ * @param string Name of subfield
+ * @return string|FALSE Return value of subfield if Field exists, otherwise FALSE
+ */
+ function subfield($field, $subfield) {
+ if (!$field = $this->field($field)) {
+ return FALSE;
+ } else {
+ return $field->subfield($subfield);
+ }
+ }
+
+ /**
+ * Delete Field
+ *
+ * Delete a given field from within a Record
+ * @param Field The field to be deleted
+ */
+ function delete_field($obj) {
+ unset($this->fields[$obj->field]);
+ }
+
+ /**
+ * Clone record
+ *
+ * Clone a record with all its Fields and subfields
+ * @return Record Clone record
+ */
+ function make_clone() {
+ $clone = new Record;
+ $clone->leader($this->ldr);
+
+ foreach ($this->fields() as $data) {
+ foreach ($data as $field) {
+ $clone->append_fields($field);
+ }
+ }
+
+ return $clone;
+ }
+
+ /**
+ * ========== OUTPUT FUNCTIONS ==========
+ */
+
+ /**
+ * Formatted representation of Field
+ *
+ * Format a Field with a sprintf()-like formatting syntax. The formatting
+ * codes are the names of the subfields of the Field.
+ * @param string Field name
+ * @param string Format string
+ * @return string|FALSE Return formatted string if Field exists, otherwise False
+ */
+ function ffield($tag, $format) {
+ $result = "";
+ if ($field = $this->field($tag)) {
+ for ($i=0; $isubfield($curr);
+ }
+ }
+ }
+ return implode("", $result);
+ } else {
+ return FALSE;
+ }
+ }
+
+ /**
+ * Return Raw
+ *
+ * Return the Record in raw MARC format.
+ * @return string Raw MARC data
+ */
+ function raw() {
+ list ($fields, $directory, $reclen, $baseaddress) = $this->_build_dir();
+ $this->leader_lengths($reclen, $baseaddress);
+
+ /**
+ * Glue together all parts
+ */
+ return $this->ldr.implode("", $directory).END_OF_FIELD.implode("", $fields).END_OF_RECORD;
+ }
+
+ /**
+ * Return formatted
+ *
+ * Return the Record in a formatted fashion. Similar to the output
+ * of the formatted() function in MARC::Record in Perl
+ * @return string Formatted representation of MARC record
+ */
+ function formatted() {
+ $formatted = "";
+ foreach ($this->fields as $field_group) {
+ foreach ($field_group as $field) {
+ $formatted .= $field->formatted(). "\n";
+ }
+ }
+ return $formatted;
+ }
+}
+
+/**
+ * Field Class
+ * Create a MARC Field object
+ */
+Class Field {
+
+ /**
+ * ========== VARIABLE DECLARATIONS ==========
+ */
+
+ /**
+ * The tag name of the Field
+ * @var string
+ */
+ var $tagno;
+ /**
+ * Value of the first indicator
+ * @var string
+ */
+ var $ind1;
+ /**
+ * Value of the second indicator
+ * @var string
+ */
+ var $ind2;
+ /**
+ * Array of subfields
+ * @var array
+ */
+ var $subfields = array();
+ /**
+ * Specify if the Field is a Control field
+ * @var bool
+ */
+ var $is_control;
+ /**
+ * Array of warnings
+ * @var array
+ */
+ var $warn;
+ /**
+ * Value of field, if field is a Control field
+ * @var string
+ */
+ var $data;
+
+ /**
+ * ========== ERROR FUNCTIONS ==========
+ */
+
+ /**
+ * Croaking function
+ *
+ * Similar to Perl's croak function, which ends parsing and raises an
+ * user error with a descriptive message.
+ * @param string The message to display
+ */
+ function _croak($msg) {
+ trigger_error($msg, E_USER_ERROR);
+ }
+
+ /**
+ * Fuction to issue warnings
+ *
+ * Warnings will not be displayed unless explicitly accessed, but all
+ * warnings issued during parse will be stored
+ * @param string Warning
+ * @return string Last added warning
+ */
+ function _warn($msg) {
+ $this->warn[] = $msg;
+ return $msg;
+ }
+
+ /**
+ * Return an array of warnings
+ */
+ function warnings() {
+ return $this->warn;
+ }
+
+ /**
+ * ========== PROCESSING FUNCTIONS ==========
+ */
+
+ /**
+ * Field init function
+ *
+ * Create a new Field object from passed arguments
+ * @param array Array ( tagno, ind1, ind2, subfield_data )
+ * @return string Returns warnings if any issued during parse
+ */
+ function field() {
+ $args = func_get_args();
+
+ $tagno = array_shift($args);
+ $this->tagno = $tagno;
+
+ // Check if valid tag
+ if (!preg_match("/^[0-9A-Za-z]{3}$/", $tagno)) {
+ return $this->_warn("Tag \"$tagno\" is not a valid tag.");
+ }
+
+ // Check if field is Control field
+ $this->is_control = (preg_match("/^\d+$/", $tagno) && $tagno < 10);
+ if ($this->is_control) {
+ $this->data = array_shift($args);
+ } else {
+ foreach (array("ind1", "ind2") as $indcode) {
+ $indicator = array_shift($args);
+ if (!preg_match("/^[0-9A-Za-z ]$/", $indicator)) {
+ if ($indicator != "") {
+ $this->_warn("Illegal indicator '$indicator' in field '$tagno' forced to blank");
+ }
+ $indicator = " ";
+ }
+ $this->$indcode = $indicator;
+ }
+
+ $subfields = array_shift($args);
+
+ if (count($subfields) < 1) {
+ return $this->_warn("Field $tagno must have at least one subfield");
+ } else {
+ $this->add_subfields($subfields);
+ }
+ }
+ }
+
+ /**
+ * Add subfield
+ *
+ * Appends subfields to existing fields last, not in "correct" plase
+ * @param array Subfield data
+ * @return string Returns warnings if issued during parse.
+ */
+ function add_subfields() {
+ // Process arguments
+ $args = func_get_args();
+ if (count($args) == 1 && is_array($args[0])) {
+ $args = $args[0];
+ }
+ // Add subfields, is appropriate
+ if ($this->is_control) {
+ return $this->_warn("Subfields allowed only for tags bigger or equal to 10");
+ } else {
+ $this->subfields = array_merge($this->subfields, $args);
+ }
+
+ return count($args)/2;
+ }
+
+ /**
+ * Return Tag number of Field
+ */
+ function tagno() {
+ return $this->tagno;
+ }
+
+ /**
+ * Set/Get Data of Control field
+ *
+ * Sets the Data if argument given, otherwise Data returned
+ * @param string Data to be set
+ * @return string Data of Control field if argument not given
+ */
+ function data($data = "") {
+ if (!$this->is_control) {
+ $this->_croak("data() is only allowed for tags bigger or equal to 10");
+ }
+ if ($data) {
+ $this->data = $data;
+ } else {
+ return $this->data;
+ }
+ }
+
+ /**
+ * Get values of indicators
+ *
+ * @param string Indicator number
+ */
+ function indicator($ind) {
+ if ($ind == 1) {
+ return $this->ind1;
+ } elseif ($ind == 2) {
+ return $this->ind2;
+ } else {
+ $this->_warn("Invalid indicator: $ind");
+ }
+ }
+
+ /**
+ * Check if Field is Control field
+ *
+ * @return bool True or False
+ */
+ function is_control() {
+ return $this->is_control;
+ }
+
+ /**
+ * Get the value of a subfield
+ *
+ * Return of the value of the given subfield, if exists
+ * @param string Name of subfield
+ * @return string|FALSE Value of the subfield if exists, otherwise FALSE
+ */
+ function subfield($code, $repeatable = FALSE) {
+ if (array_key_exists($code, $this->subfields)) {
+ return $repeatable ? $this->subfields[$code] : $this->subfields[$code][0];
+ } else {
+ return $repeatable ? array(): FALSE;
+ }
+ }
+
+ /**
+ * Return array of subfields
+ *
+ * @return array Array of subfields
+ */
+ function subfields() {
+ return $this->subfields;
+ }
+
+ /**
+ * Update Field
+ *
+ * Update Field with given array of arguments.
+ * @param array Array of key->value pairs of data
+ */
+ function update() {
+ // Process arguments
+ $args = func_get_args();
+ if (count($args) == 1 && is_array($args[0])) {
+ $args = $args[0];
+ }
+ if ($this->is_control) {
+ $this->data = array_shift($args);
+ } else {
+ foreach ($args as $subfield => $value) {
+ if ($subfield == "ind1") {
+ $this->ind1 = $value;
+ } elseif ($subfield == "ind2") {
+ $this->ind2 = $value;
+ } else {
+ $this->subfields[$subfield] = $value;
+ }
+ }
+ }
+ }
+
+ /**
+ * Replace Field with given Field
+ *
+ * @param Field Field to replace with
+ */
+ function replace_with($obj) {
+ if (strtolower(get_class($obj)) == "field") {
+ $this->tagno = $obj->tagno;
+ $this->ind1 = $obj->ind1;
+ $this->ind2 = $obj->ind2;
+ $this->subfields = $obj->subfields;
+ $this->is_control = $obj->is_control;
+ $this->warn = $obj->warn;
+ $this->data = $obj->data;
+ } else {
+ $this->_croak(sprintf("Argument must be Field-object, but was '%s'", get_class($obj)));
+ }
+ }
+
+ /**
+ * Clone Field
+ *
+ * @return Field Cloned Field object
+ */
+ function make_clone() {
+ if ($this->is_control) {
+ return new Field($this->tagno, $this->data);
+ } else {
+ return new Field($this->tagno, $this->ind1, $this->ind2, $this->subfields);
+ }
+ }
+
+ /**
+ * ========== OUTPUT FUNCTIONS ==========
+ */
+
+ /**
+ * Return Field formatted
+ *
+ * Return Field as string, formatted in a similar fashion to the
+ * MARC::Record formatted() functio in Perl
+ * @return string Formatted output of Field
+ */
+ function formatted() {
+ // Variables
+ $lines = array();
+ // Process
+ if ($this->is_control) {
+ return sprintf("%3s %s", $this->tagno, $this->data);
+ } else {
+ $pre = sprintf("%3s %1s%1s", $this->tagno, $this->ind1, $this->ind2);
+ }
+ // Process subfields
+ foreach ($this->subfields as $subfield => $value) {
+ $lines[] = sprintf("%6s _%1s%s", $pre, $subfield, $value);
+ $pre = "";
+ }
+
+ return join("\n", $lines);
+ }
+
+ /**
+ * Return Field in Raw MARC
+ *
+ * Return the Field formatted in Raw MARC for saving into MARC files
+ * @return string Raw MARC
+ */
+ function raw() {
+ if ($this->is_control) {
+ return $this->data.END_OF_FIELD;
+ } else {
+ $subfields = array();
+ foreach ($this->subfields as $subfield => $value) {
+ $subfields[] = SUBFIELD_INDICATOR.$subfield.$value;
+ }
+ return $this->ind1.$this->ind2.implode("", $subfields).END_OF_FIELD;
+ }
+ }
+
+ /**
+ * Return Field as String
+ *
+ * Return Field formatted as String, with either all subfields or special
+ * subfields as specified.
+ * @return string Formatted as String
+ */
+ function string($fields = "") {
+ $matches = array();
+ if ($fields) {
+ for($i=0; $isubfields)) {
+ $matches[] = $this->subfields[$fields[$i]];
+ }
+ }
+ } else {
+ $matches = $this->subfields;
+ }
+ return implode(" ", $matches);
+ }
+
+}
+
+?>
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/modules/pubmed/EntrezClient.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/modules/pubmed/EntrezClient.php Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,505 @@
+webEnvironment = $webEnvironment;
+ }
+
+ /**
+ * Returns the web environment from the previous ESearch results.
+ *
+ * This value may change with each utility call. If WebEnv is used, History
+ * search numbers can be included in an ESummary URL, e.g.,
+ * term=cancer+AND+%23X (where %23 replaces # and X is the History search
+ * number).
+ *
+ * @return string
+ */
+ public function getWebEnvironment()
+ {
+ return $this->webEnvironment;
+ }
+
+ /**
+ * Sets a history search number.
+ *
+ * @param int $key
+ */
+ public function setQueryKey($key)
+ {
+ $this->queryKey = $key;
+ }
+
+ /**
+ * Returns the history search number from the previous ESearch results.
+ *
+ * @return int
+ */
+ public function getQueryKey()
+ {
+ return $this->queryKey;
+ }
+
+ /**
+ * Sets the entrez database to be queried.
+ *
+ * Values available from EInfo, PubMed is the default db.
+ *
+ * @param string $database
+ * @see getAvailableDatabases
+ */
+ public function setDatabase($database)
+ {
+ $this->database = strtolower($database);
+ }
+
+ /**
+ * Returns the database to be queried in the next search.
+ *
+ * @return string
+ */
+ public function getDatabase()
+ {
+ return $this->database;
+ }
+
+ /**
+ * Returns the available entrez databases from EInfo.
+ *
+ * @return array
+ * @throws Exception
+ */
+ public function getAvailableDatabases()
+ {
+ $databases = array();
+
+ $url = self::BASE_URL . 'einfo.fcgi';
+ $result = @simplexml_load_file($url);
+
+ if (!$result) {
+ throw new Exception('Query ' . $url . ' failed.');
+ }
+
+ if (isset($result->DbList->DbName)) {
+ foreach ($result->DbList->DbName as $name) {
+ $databases[] = (string)$name;
+ }
+ }
+
+ return $databases;
+ }
+
+ /**
+ * Sets a string identifying the resource.
+ *
+ * A string with no internal spaces that identifies the resource which is
+ * using Entrez links (e.g., tool=flybase). This argument is used to help
+ * NCBI provide better service to third parties generating Entrez queries
+ * from programs. As with any query system, it is sometimes possible to ask
+ * the same question different ways, with different effects on performance.
+ * NCBI requests that developers sending batch requests include a constant
+ * 'tool' argument for all requests using the utilities.
+ *
+ * @param string $tool
+ */
+ public function setTool($tool)
+ {
+ $this->tool = str_replace(array(" ", "\n", "\r"), '', $tool);
+ }
+
+ /**
+ * Returns the resource identifier.
+ *
+ * @return string
+ */
+ public function getTool()
+ {
+ return $this->tool;
+ }
+
+ /**
+ * Sets a contact email address for NCBI.
+ *
+ * If you choose to provide an email address, we will use it to contact you
+ * if there are problems with your queries or if we are changing software
+ * interfaces that might specifically affect your requests. If you choose
+ * not to include an email address we cannot provide specific help to you,
+ * but you can still sign up for utilities-announce to receive general
+ * announcements.
+ *
+ * @param string $email
+ */
+ public function setEmail($email)
+ {
+ $this->email = $email;
+ }
+
+ /**
+ * Returns the NCBI contact email address.
+ *
+ * @return string
+ */
+ public function getEmail()
+ {
+ return $this->email;
+ }
+
+ /**
+ * Sets the search terms for the next query.
+ *
+ * The search command uses terms or phrases with or without Boolean
+ * operators. See the PubMed or Entrez help for information about search
+ * field descriptions and tags. Search fields and tags are database specific.
+ *
+ * @param string $term
+ */
+ public function setTerm($term)
+ {
+ $this->term = $term;
+ $this->webEnvironment = NULL;
+ $this->count = NULL;
+ }
+
+ /**
+ * Returns the current search terms.
+ *
+ * @return string
+ */
+ public function getTerm()
+ {
+ return $this->term;
+ }
+
+ /**
+ * Sets two specific dates bounding the results.
+ *
+ * @param $minDate
+ * @param $maxDate
+ * @throws Exception
+ */
+ public function setDateRange($minDate, $maxDate=null)
+ {
+ if (is_null($maxDate)) {
+ $maxDate = date('Y/m/d');
+ } else {
+ $maxDate = date('Y/m/d', strtotime($maxDate));
+ }
+
+ $minDate = date('Y/m/d', strtotime($minDate));
+
+ if ($maxDate < $minDate) {
+ throw new Exception('First argument must be an earlier date.');
+ }
+
+ $this->dateRange = array($minDate, $maxDate);
+ }
+
+ /**
+ * Returns the specified date range bounding the results.
+ *
+ * @return array
+ * a pair of dates
+ */
+ public function getDateRange()
+ {
+ return $this->dateRange;
+ }
+
+ /**
+ * Returns the minimum date of the specified date range bounding the results.
+ *
+ * @return string
+ */
+ public function getMinDate()
+ {
+ return $this->dateRange[0];
+ }
+
+ /**
+ * Returns the maximum date of the specified date range bounding the results.
+ *
+ * @return string
+ */
+ public function getMaxDate()
+ {
+ return $this->dateRange[1];
+ }
+
+ /**
+ * Sets the maximum number of items retrieved by a search query.
+ *
+ * @param int $number
+ * @see search
+ */
+ public function setReturnMax($number)
+ {
+ $this->returnMax = $number;
+ }
+
+ /**
+ * Returns the maximum number of items retrieved by a search query.
+ *
+ * @return int
+ */
+ public function getReturnMax()
+ {
+ return $this->returnMax;
+ }
+
+ /**
+ * Returns the URL of the last executed query.
+ *
+ * @return string
+ */
+ public function getLastQuery()
+ {
+ return $this->query;
+ }
+
+ /**
+ * Returns up to the maximum number of items from the result set starting
+ * at $retstart.
+ *
+ * If this is the first search for a given term a web environment and a query
+ * key is retrieved from the NCBI server in addition to the result set.
+ * See http://eutils.ncbi.nlm.nih.gov/corehtml/query/static/esearch_help.html
+ *
+ * @param int $retStart
+ * the sequential number of the first record retrieved - default=0
+ * which will retrieve the first record
+ * @return SimpleXMLElement
+ * an array of PubMed IDs
+ * @throws Exception
+ * @see setReturnMax
+ * @see setRelativeDate
+ */
+ public function search($retStart=0)
+ {
+ if (!is_null($this->webEnvironment)) {
+ $params['WebEnv'] = $this->webEnvironment;
+ $params['query_key'] = $this->queryKey;
+ } else {
+ $params['usehistory'] = $this->useHistory;
+ $params['tool'] = $this->getTool();
+ $params['email'] = $this->getEmail();
+ $params['term'] = $this->getTerm();
+ }
+
+ if (isset($this->dateRange)) {
+ $params['mindate'] = $this->getMinDate();
+ $params['maxdate'] = $this->getMaxDate();
+ }
+
+ $params['retstart'] = $retStart;
+ $params['retmax'] = $this->getReturnMax();
+ $params['db'] = $this->getDatabase();
+
+ $this->query = self::BASE_URL . 'esearch.fcgi?' . http_build_query($params);
+ $result = @simplexml_load_file($this->query);
+
+ if (!$result) {
+ throw new Exception('Query ' . $this->query . ' failed.');
+ }
+
+ if (isset($result->WebEnv)) {
+ $this->webEnvironment = (string)$result->WebEnv;
+ $this->queryKey = (int)$result->QueryKey;
+ $this->count = (int)$result->Count;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Returns the number of results for the previously set search terms.
+ *
+ * @return int
+ * @throws Exception
+ */
+ public function count()
+ {
+ if (is_null($this->count)) {
+ $params['tool'] = $this->getTool();
+ $params['email'] = $this->getEmail();
+ $params['db'] = $this->getDatabase();
+ $params['term'] = $this->getTerm();
+ $params['rettype'] = 'count';
+
+ if (isset($this->dateRange)) {
+ $params['mindate'] = $this->getMinDate();
+ $params['maxdate'] = $this->getMaxDate();
+ }
+
+ $this->query = self::BASE_URL . 'esearch.fcgi?' . http_build_query($params);
+ $result = @simplexml_load_file($this->query);
+
+ if (!$result) {
+ throw new Exception('Query ' . $this->query . ' failed.');
+ }
+
+ if (isset($result->Count)) {
+ $this->count = (int)$result->Count;
+ }
+ }
+
+ return $this->count;
+ }
+
+ /**
+ * Returns the document identified by the given PubMed ID as a SimpleXMl
+ * object. The root element is PubmedArticleSet.
+ *
+ * @param int $id
+ * @return SimpleXMLElement
+ */
+ public function fetch($id)
+ {
+ $params['db'] = $this->getDatabase();
+ $params['retmode'] = 'xml';
+ $params['id'] = $id;
+
+ $this->query = self::BASE_URL . 'efetch.fcgi?' . http_build_query($params);
+ $request_options = array(
+ 'method' => 'POST');
+ $result = drupal_http_request($this->query, $request_options);
+ if ($result->code != 200) {
+ throw new Exception('Query ' . $this->query . ' failed.');
+ }
+ $result = @simplexml_load_string($result->data);
+
+ if (!$result) {
+ throw new Exception('Query ' . $this->query . ' failed.');
+ }
+
+ return $result;
+ }
+ public function fetchSummaries($retStart=0) {
+ return $this->fetchRecords($retStart, TRUE);
+ }
+ public function fetchResult($retStart=0) {
+ return $this->fetchRecords($retStart);
+ }
+
+ /**
+ * Returns up to the maximum number of results starting at $retstart
+ * found by the previous search.
+ *
+ * In order to return results this method must be called after search. The
+ * search method retrieves a web environment and query key from the NCBI
+ * server which is used to fetch the results. After setting a new search term
+ * the old web environment is deleted and search must be executed again
+ * before utilizing this method.
+ *
+ * The root element of the returned SimpleXML object is PubmedArticleSet.
+ *
+ * @param $retStart
+ * the sequential number of the first record retrieved - default=0
+ * which will retrieve the first record
+ * @return SimpleXMLElement
+ * @throws Exception
+ * @see search
+ * @see setReturnMax
+ */
+ public function fetchRecords($retStart=0, $summaries = FALSE) {
+ if (is_null($this->webEnvironment)) {
+ throw new Exception(t('No web environment set.'));
+ }
+
+ $params['WebEnv'] = $this->webEnvironment;
+ $params['query_key'] = $this->queryKey;
+ $params['retstart'] = $retStart;
+ $params['retmax'] = $this->getReturnMax();
+ $params['db'] = $this->getDatabase();
+ $params['retmode'] = 'xml';
+
+ if (isset($this->dateRange)) {
+ $params['mindate'] = $this->getMinDate();
+ $params['maxdate'] = $this->getMaxDate();
+ }
+ if ($summaries) {
+ $this->query = self::BASE_URL . 'esummary.fcgi?' . http_build_query($params);
+ }
+ else {
+ $this->query = self::BASE_URL . 'efetch.fcgi?' . http_build_query($params);
+ }
+ $request_options = array('method' => 'POST');
+ $result = drupal_http_request($this->query, $request_options);
+
+ if ($result->code != 200) {
+ throw new Exception('Query ' . $this->query . ' failed.');
+ }
+
+ $result = @simplexml_load_string($result->data);
+
+
+ if (isset($result->body->pre->ERROR)) return FALSE;
+
+ return $result;
+ }
+
+ public function post($uids) {
+ $params['db'] = $this->getDatabase();
+ $params['id'] = implode(',', $uids);
+ $this->query = self::BASE_URL . 'epost.fcgi?' . http_build_query($params);
+ $request_options = array('method' => 'POST');
+ $result = drupal_http_request($this->query, $request_options);
+
+ if ($result->code != 200) {
+ throw new Exception('Query ' . $this->query . ' failed.');
+ }
+
+ $result = @simplexml_load_string($result->data);
+
+ if (!$result) {
+ throw new Exception('Query ' . $this->query . ' failed.');
+ }
+
+ if (isset($result->WebEnv)) {
+ $this->webEnvironment = (string)$result->WebEnv;
+ $this->queryKey = (int)$result->QueryKey;
+ $this->count = (int)$result->Count;
+ }
+
+ }
+
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 modules/biblio/modules/pubmed/EntrezPubmedArticle.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/modules/pubmed/EntrezPubmedArticle.php Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,241 @@
+setArticle($pubmedArticle);
+ }
+ }
+
+ /**
+ * Returns the PubMed ID of the article.
+ *
+ * @return int
+ */
+ public function setArticle(SimpleXMLElement $pubmedArticle)
+ {
+ $this->biblio = array();
+ $this->article = $pubmedArticle->MedlineCitation;
+ $this->pubmeddata = $pubmedArticle->PubmedData;
+ $this->id = (int)$pubmedArticle->MedlineCitation->PMID;
+ $this->md5 = md5($pubmedArticle->asXML());
+ return $this;
+ }
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ /**
+ * Returns the md5 hash of the serialized XML.
+ *
+ * @return string
+ */
+ public function getMd5()
+ {
+ return $this->md5;
+ }
+
+ public function getBiblioAsObject() {
+ return (object)$this->getBiblio();
+ }
+
+ /**
+ * Returns article elements as an associative array suitable for import into
+ * a biblio node.
+ *
+ * @return array
+ */
+ public function getBiblio()
+ {
+ if (empty($this->biblio)) {
+ if (variable_get('biblio_auto_citekey', 1) ) {
+ $citekey = '';
+ }
+ else {
+ $citekey = $this->id;
+ }
+
+ // Attempts to extract the name of the journal from MedlineTA if
+ // available.
+ if (!empty($this->article->MedlineJournalInfo->MedlineTA)) {
+ $journal = (string)$this->article->MedlineJournalInfo->MedlineTA;
+ }
+ elseif (!empty($this->article->Article->Journal->ISOAbbreviation)) {
+ $journal = (string)$this->article->Article->Journal->ISOAbbreviation;
+ }
+ else {
+ $journal = (string)$this->article->Article->Journal->Title;
+ }
+
+ $this->biblio = array(
+ 'title' => (string)$this->article->Article->ArticleTitle,
+ 'biblio_citekey' => $citekey,
+ 'biblio_pubmed_id' => $this->id,
+ 'biblio_pubmed_md5' => $this->md5,
+ 'biblio_contributors' => $this->contributors(),
+ // MedlineCitations are always articles from journals or books
+ 'biblio_type' => 102,
+ 'biblio_date' => $this->date(),
+ 'biblio_year' => substr($this->date(), 0, 4),
+ 'biblio_secondary_title' => $journal,
+ 'biblio_alternate_title' => (string)$this->article->Article->Journal->ISOAbbreviation,
+ 'biblio_volume' => (string)$this->article->Article->Journal->JournalIssue->Volume,
+ 'biblio_issue' => (string)$this->article->Article->Journal->JournalIssue->Issue,
+ 'biblio_issn' => (string)$this->article->Article->Journal->ISSN,
+ 'biblio_pages' => (string)$this->article->Article->Pagination->MedlinePgn,
+ 'biblio_abst_e' => $this->abst(),
+ 'biblio_custom1' => "http://www.ncbi.nlm.nih.gov/pubmed/{$this->id}?dopt=Abstract",
+ 'biblio_keywords' => $this->keywords(),
+ 'biblio_lang' => $this->lang(),
+ );
+
+ $doi = $this->article->xpath('.//ELocationID[@EIdType="doi"]/text()');
+ if (empty($doi)) {
+ $doi = $this->pubmeddata->xpath('.//ArticleId[@IdType="doi"]/text()');
+ }
+ if (!empty($doi)) {
+ $this->biblio['biblio_doi'] = (string)$doi[0];
+ }
+
+ $pmcid = $this->pubmeddata->xpath('.//ArticleId[@IdType="pmc"]/text()');
+ if (!empty($pmcid)) {
+ $this->biblio['biblio_pmcid'] = (string)$pmcid[0];
+ }
+
+ $grants = $this->grants();
+ if (!empty($grants)) {
+ $this->biblio['biblio_pubmed_grants'] = $grants;
+ }
+ }
+
+ return $this->biblio;
+ }
+
+ /**
+ * Returns the list of contributors for import obtained from the given
+ * MedlineCitation element.
+ *
+ * @return array
+ * the contributors of the article
+ */
+ private function contributors()
+ {
+ $contributors = array();
+
+ if (isset($this->article->Article->AuthorList->Author)) {
+ foreach ($this->article->Article->AuthorList->Author as $author) {
+ $name = '';
+ if (isset($author->CollectiveName)) {
+ $category = 5; // corporate author
+ $name = (string)$author->CollectiveName;
+ } else {
+ $category = 1; //primary (human) author
+ $lastname = (string)$author->LastName;
+ if (isset($author->ForeName)) {
+ $name = $lastname . ', ' . (string)$author->ForeName;
+ } elseif (isset($author->FirstName)) {
+ $name = $lastname . ', ' . (string)$author->FirstName;
+ } elseif (isset($author->Initials)) {
+ $name = $lastname . ', ' . (string)$author->Initials;
+ }
+ }
+ if (!empty($name)) {
+ $contributors[] = array('name' => $name, 'auth_category' => $category);
+ }
+ }
+ }
+
+ return $contributors;
+ }
+
+ private function grants() {
+ $grants = array();
+ if (isset($this->article->Article->GrantList->Grant)) {
+ foreach ($this->article->Article->GrantList->Grant as $grant) {
+ $grants[] = array('grantid' => (string)$grant->GrantID,
+ 'acronym' => (string)$grant->Acronym,
+ 'agency' => (string)$grant->Agency,
+ 'country' => (string)$grant->Country
+ );
+ }
+ }
+ return $grants;
+ }
+
+ /**
+ * Returns the publication date obtained from the given MedlineCitation's
+ * PubDate element. See the reference documentation for possible values:
+ * http://www.nlm.nih.gov/bsd/licensee/elements_descriptions.html#pubdate
+ * According to the above source it always begins with a four digit year.
+ *
+ * @return string
+ * the publication date of the article
+ */
+ private function date()
+ {
+ $pubDate = $this->article->Article->Journal->JournalIssue->PubDate;
+
+ if (isset($pubDate->MedlineDate)) {
+ $date = (string)$pubDate->MedlineDate;
+ } else {
+ $date = implode(' ', (array)$pubDate);
+ }
+
+ return $date;
+ }
+
+ private function keywords() {
+ $keywords = array();
+ if (isset($this->article->MeshHeadingList->MeshHeading)) {
+ foreach ($this->article->MeshHeadingList->MeshHeading as $heading) {
+ $keywords[] = (string)$heading->DescriptorName;
+ }
+ }
+ return $keywords;
+ }
+
+ private function lang() {
+ if (isset($this->article->Article->Language)) {
+ return (string)$this->article->Article->Language;
+ }
+
+ }
+
+ private function abst() {
+ if (isset($this->article->Article->Abstract)) {
+ $abst = '';
+ foreach ($this->article->Article->Abstract->AbstractText as $text) {
+ $abst .= "
';
- }
- }
- }
-
- return $element;
-}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/includes/omega.drush.inc
--- a/sites/all/themes/omega/includes/omega.drush.inc Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,979 +0,0 @@
- dt('Creates a Omega subtheme.'),
- 'arguments' => array(
- 'name' => dt('The name of your subtheme.'),
- ),
- 'options' => array(
- 'destination' => dt('The destination of your subtheme. Defaults to "site:all" (sites/all/themes). May be one of "site:foo", "profile:bar" or "theme:baz" ("foo", "bar" and "baz" being the name of your site, profile or parent theme). May also have a third part for sub-pathing. For example, if using site:all:custom/cat, then the theme will be created in sites/all/themes/custom/cat/.'),
- 'machine-name' => dt('The machine-readable name of your subtheme. This will be auto-generated from the human-readable name if omitted.'),
- 'starterkit' => dt('The starterkit that your subtheme should use. Defaults to "default".'),
- 'basetheme' => dt('Specifies a custom base theme. Defaults to "omega".'),
- 'enable' => dt('Automatically enable the subtheme after creation.'),
- 'set-default' => dt('Automatically enable the subtheme after creation and make it the default theme.'),
- 'no-readme' => dt('Skips readme files when generating the subtheme.'),
- 'no-libraries' => dt("Prevent execution of the theme's libraries.make file.")
- ),
- 'examples' => array(
- 'drush omega-subtheme "My Theme"' => dt('Creates an Omega subtheme called "My Theme".'),
- 'drush omega-subtheme "My Theme" --destination=site:example.com' => dt('Creates an Omega subtheme called "My Theme" in sites/example.com/themes.'),
- 'drush omega-subtheme "My Theme" --basetheme=my_custom_basetheme' => dt('Uses the default starterkit from a custom basetheme to create an Omega subtheme called "My Theme" in sites/all/themes.'),
- 'drush omega-subtheme "My Theme" --basetheme=my_custom_basetheme --starterkit=my_custom_starterkit' => dt('Uses the my_custom_starterkit from a custom basetheme to create an Omega subtheme called "My Theme" in sites/all/themes.'),
- ),
- 'aliases' => array('osub'),
- );
-
- $items['omega-wizard'] = array(
- 'description' => dt('Guides you through a wizard for generating a subtheme.'),
- 'aliases' => array('owiz'),
- );
-
- $items['omega-guard'] = array(
- 'description' => dt('Runs guard for the given theme including Compass and LiveReload by default.'),
- 'arguments' => array(
- 'name' => dt('The name of your subtheme.'),
- ),
- 'options' => array(
- 'screen' => dt('Run guard watch in a detached screen.'),
- 'force-polling' => dt('Polling is required for making guard watch work with remote file systems e.g. in case of virtual environments where guard runs on the guest but the files are modified on the host.'),
- 'latency' => dt("Sometimes it seems to be required to set a latency (e.g. 5) if working with --force-polling because otherwise file changes are detected twice. Hence, not setting a latency might affect your system performance."),
- ),
- 'aliases' => array('ogrd'),
- );
-
- $items['omega-export'] = array(
- 'description' => dt('Exports the theme settings of a given theme from the database to the .info file.'),
- 'arguments' => array(
- 'theme' => dt('The machine-readable name of the theme to export the theme settings for.'),
- ),
- 'options' => array(
- 'revert' => dt('Purges the theme settings from the database after exporting them to the .info file.'),
- ),
- 'examples' => array(
- 'drush omega-export foo' => dt('Exports the theme settings of the "foo" theme to the "foo.info" file in that theme.'),
- 'drush omega-export foo --revert' => dt('Purges the theme settings of the "foo" theme from the database after exporting them to the .info file.'),
- ),
- 'aliases' => array('oexp'),
- );
-
- $items['omega-revert'] = array(
- 'description' => dt('Reverts the theme settings of a given theme by deleting them from the database.'),
- 'arguments' => array(
- 'theme' => dt('The machine-readable name of the theme to revert the theme settings for.'),
- ),
- 'options' => array(
- 'all' => dt('Reverts the theme settings of all Omega sub-themes.'),
- ),
- 'examples' => array(
- 'drush omega-revert foo' => dt('Reverts the theme settings of the "foo" theme.'),
- ),
- 'aliases' => array('orev'),
- );
-
- return $items;
-}
-
-/**
- * Implements hook_drush_help().
- */
-function omega_drush_help($section) {
- switch ($section) {
- case 'drush:omega-subtheme':
- return dt('Generates a subtheme.');
- case 'drush:omega-wizard':
- return dt('Guides you through a wizard for generating a subtheme.');
- case 'drush:omega-guard':
- return dt('Runs guard for the given theme including Compass and LiveReload by default.');
- case 'drush:omega-export':
- return dt('Exports the theme settings of a given theme.');
- case 'drush:omega-revert':
- return dt('Reverts the theme settings of a given theme.');
- }
-}
-
-/**
- * Implements drush_hook_COMMAND_validate().
- */
-function drush_omega_subtheme_validate($name = NULL) {
- if (!isset($name)) {
- return drush_set_error('OMEGA_MISSING_ARGUMENT', dt("You didn't specify a name for the subtheme."));
- }
-
- // Rebuild the theme data so that we can safely check for the existence of
- // themes by using the information provided by list_themes().
- system_rebuild_theme_data();
-
- if ($machine_name = drush_get_option('machine-name')) {
- // Validate the machine-readable name of the theme.
- if (!is_string($machine_name)) {
- return drush_set_error('OMEGA_THEME_NAME_INVALID', dt('The --machine-name option expects a string value.'));
- }
-
- if (!preg_match('/^[a-z][a-z0-9_]*$/', $machine_name)) {
- return drush_set_error('OMEGA_THEME_NAME_INVALID', dt('The machine name (@name) is invalid. It may only contain lowercase numbers, letters and underscores and must start with a letter.', array(
- '@name' => $machine_name,
- )));
- }
-
- $themes = list_themes();
- // Validate that the machine-readable name of the theme is unique.
- if (isset($themes[$machine_name])) {
- return drush_set_error('OMEGA_THEME_ALREADY_EXISTS', dt('A theme with the name @name already exists. The machine-readable name must be unique.', array(
- '@name' => $machine_name,
- )));
- }
- }
-
- if ($destination = drush_get_option('destination')) {
- // Check if the syntax of the destination is valid.
- if (!is_string($destination) || !preg_match('/^(site|theme|profile)(:(.+?)){1,2}$/', $destination)) {
- return drush_set_error('OMEGA_DESTINATION_INVALID', dt('The destination syntax (@destination) is invalid. Please use one of the following destination patterns (site, profile or theme): --destination="site:foo", --destination="profile:bar" or --destination="theme:baz".', array(
- '@destination' => $destination,
- )));
- }
-
- // Check if the provided destination exists.
- if (!drush_omega_resolve_destination($destination)) {
- list($type, $destination) = explode(':', $destination);
-
- return drush_set_error('OMEGA_DESTINATION_DOES_NOT_EXIST', dt('The given destination @destination of type @type does not exist. Did you misspell it?', array(
- '@destination' => $destination,
- '@type' => $type,
- )));
- }
- }
-
- if ($basetheme = drush_get_option('basetheme')) {
- if (!is_string($basetheme)) {
- return drush_set_error('OMEGA_BASETHEME_INVALID', dt('The --basetheme option expects a string value.'));
- }
-
- // Check if the base theme exists.
- if (!array_key_exists($basetheme, list_themes())) {
- return drush_set_error('OMEGA_BASETHEME_DOES_NOT_EXIST', dt('The base theme @basetheme does not exist or is invalid.', array(
- '@basetheme' => $basetheme,
- )));
- }
-
- // Check if the base theme is an Omega theme.
- if (!array_key_exists('omega', omega_theme_trail($basetheme))) {
- return drush_set_error('OMEGA_BASETHEME_INVALID', dt('The base theme @basetheme does not exist or is invalid.', array(
- '@basetheme' => $basetheme,
- )));
- }
- }
-
- if ($starterkit = drush_get_option('starterkit')) {
- if (!is_string($starterkit)) {
- return drush_set_error('OMEGA_STARTERKIT_INVALID', dt('The --starterkit option expects a string value.'));
- }
-
- $basetheme = drush_get_option('basetheme', 'omega');
-
- // Check if the starterkit exists.
- if (!array_key_exists($starterkit, omega_discovery('starterkit', $basetheme))) {
- $themes = list_themes();
-
- return drush_set_error('OMEGA_STARTERKIT_DOES_NOT_EXIST', dt('There is no valid @basetheme theme starterkit with the name @starterkit. Did you forget to specify the correct basetheme?', array(
- '@basetheme' => $themes[$basetheme]->info['name'],
- '@starterkit' => $starterkit,
- )));
- }
- }
-}
-
-/**
- * Implements drush_hook_COMMAND().
- */
-function drush_omega_subtheme($name) {
- // Try to generate a machine-readable name. If that fails, prompt for one.
- if (!$machine_name = drush_get_option('machine-name', drush_omega_generate_theme_name($name))) {
- drush_print(dt("Sorry, I couldn't generate a machine-readable name for @name. Please use the '--machine-name' option to specify it manually.", array(
- '@name' => $name,
- )));
- }
-
- $basetheme = drush_get_option('basetheme', 'omega');
- $starterkits = omega_discovery('starterkit', $basetheme);
- $starterkit = drush_get_option('starterkit', 'default');
- $starterkit = $starterkits[$starterkit];
-
- // Check whether the destination path does not exist and bail out if it does
- // so we don't delete any important data by accident.
- $destination = drush_omega_resolve_destination(drush_get_option('destination', 'site:all')) . '/' . $machine_name;
- if (file_exists($destination)) {
- return drush_set_error('OMEGA_SUBTHEME_PATH', dt('The path @path already exists.', array('@path' => $destination)));
- }
-
- // Create a temporary directory so we don't leave any stale files if an
- // operation fails.
- $temporary = drush_tempdir() . '/' . $name;
-
- // Try to copy the starterkit to the destination path of the new subtheme.
- if (!drush_copy_dir($starterkit['path'], $temporary)) {
- return drush_set_error('OMEGA_GENERATE_SUBTHEME', dt('Failed to generate subtheme.'));
- }
-
- // Delete the .starterkit.inc file.
- drush_delete_dir($temporary . '/' . basename($starterkit['file']));
-
- // Put the name and description for the new subtheme in place.
- $info = array(
- 'name' => $name,
- 'description' => 'Please provide a description for your theme.',
- 'base theme' => $basetheme,
- ) + $starterkit['info'];
-
- // Write to the new .info file.
- $file = $temporary . '/' . $machine_name . '.info';
- if (!file_put_contents($file, drush_omega_compose_info_file($info))) {
- return drush_set_error('OMEGA_GENERATE_SUBTHEME', dt('Failed to generate subtheme.'));
- }
-
- // Optionally remove README.txt files.
- if (drush_get_option('no-readme')) {
- foreach (file_scan_directory($temporary, '/^README/') as $file) {
- drush_delete_dir($file->uri);
- }
- }
-
- // Recursively rewrite the file names and contents of all the files that are
- // now in the subtheme's directory to represent the human- and
- // machine-readable names of the subtheme.
- $search = array('/{{ THEME }}/', '/{{ THEMENAME }}/');
- $replace = array($machine_name, $name);
- if (!drush_omega_rewrite_recursive($temporary, $search, $replace)) {
- return drush_set_error('OMEGA_GENERATE_SUBTHEME', dt('Failed to generate subtheme.'));
- }
-
- // Move the new subtheme to its destination.
- if (!drush_op('drush_mkdir', dirname($destination)) || !drush_op('drush_move_dir', $temporary, $destination)) {
- return drush_set_error('OMEGA_GENERATE_SUBTHEME', dt('Failed to generate subtheme.'));
- }
-
- // Rebuild the theme caches so that we can do some final tasks.
- drupal_theme_rebuild();
- system_rebuild_theme_data();
-
- if (($default = drush_get_option('set-default')) || !drush_get_option('enable')) {
- // Enable the subtheme.
- drush_op('theme_enable', array($machine_name));
-
- if ($default) {
- // Make the newly created subtheme the default theme.
- drush_op('variable_set', 'theme_default', $machine_name);
- }
- }
-
- // Execute the theme's libraries.make file unless disabled.
- if (!drush_get_option('no-libraries') && is_file("$destination/libraries.make")) {
- drush_op('chdir', $destination);
- drush_invoke_process('@self', 'make', array('libraries.make'), array(
- 'no-core' => TRUE,
- 'contrib-destination' => '.',
- 'yes' => TRUE,
- ));
- }
-
- drush_log(dt('You have successfully created the theme @theme (@name) in @path.', array(
- '@theme' => $name,
- '@name' => $machine_name,
- '@path' => dirname($destination),
- )), 'success');
-}
-
-/**
- * Implements drush_hook_COMMAND().
- */
-function drush_omega_wizard() {
- // Rebuild the theme data so that we can safely check for the existence of
- // themes by using the information provided by list_themes().
- system_rebuild_theme_data();
-
- // Prompt for a theme name.
- $name = drush_prompt(dt('Please enter the name of the new sub-theme'), 'Omega Subtheme');
-
- // Try to generate a machine-readable name. If that fails, prompt for one.
- if (!$machine_name = drush_omega_generate_theme_name($name)) {
- drush_print(dt("Sorry, I couldn't generate a machine-readable name for @name", array(
- '@name' => $name,
- )));
- }
- // Prompt for a theme name using the automatically generated default if any.
- drush_set_option('machine-name', drush_omega_require_valid_theme_name(dt('Please enter a machine-readable name for your new theme'), $machine_name));
-
- // Prompt for a base theme.
- if (!$basetheme = drush_omega_theme_choice(dt('Please choose a base theme for your new theme'))) {
- return;
- }
- drush_set_option('basetheme', $basetheme);
-
- // Let the user choose a starterkit.
- if (!$starterkit = drush_omega_starterkit_choice($basetheme, dt('Please choose a starterkit for your new theme'))) {
- return;
- }
- drush_set_option('starterkit', $starterkit);
-
- // Let the user choose a destination.
- if (!$destination = drush_omega_destination_choice(dt('Please choose a destination. This is where your sub-theme will be placed'))) {
- return;
- }
- drush_set_option('destination', $destination);
-
- // Optionally skip readme files when generating the subtheme.
- drush_set_option('no-readme', !drush_confirm(dt("Do you want to keep the starterkit's readme files?")));
-
- // Finally, let the user choose to directly enable the subtheme.
- if ($enable = drush_confirm(dt('Do you want to enable your new theme?'))) {
- drush_set_option('set-default', drush_confirm(dt('Do you want to make your new theme the default theme?')));
- }
- drush_set_option('enable', $enable);
-
- drush_invoke('omega-subtheme', $name);
-}
-
-/**
- * Implements drush_hook_COMMAND_validate().
- */
-function drush_omega_export_validate($theme = NULL) {
- return drush_omega_validate_theme($theme);
-}
-
-/**
- * Implements drush_hook_COMMAND().
- *
- * Exports the theme settings for the given theme from the database and writes
- * them into the .info file of that theme.
- *
- * @param $theme
- * (optional) The machine-readable name of a theme.
- * @return bool
- * TRUE on success, FALSE on failure.
- */
-function drush_omega_export($theme = NULL) {
- if (!isset($theme) && !$theme = drush_omega_theme_choice(dt('Which theme do you want to export the theme settings for?'))) {
- return;
- }
-
- $themes = list_themes();
-
- // Insert the theme settings from the database.
- if (!$settings = variable_get('theme_' . $theme . '_settings')) {
- if (!drush_confirm(dt('There are no theme settings for @theme stored in the database. Do you want to purge the theme settings from the .info file too?', array('@theme' => $themes[$theme]->info['name'])))) {
- return;
- }
- }
-
- // Parse the current content of the .info file so we can append the settings
- // from the database.
- $path = drupal_get_path('theme', $theme) . '/' . $theme . '.info';
- $data = file_get_contents($path);
-
- // Remove the old theme settings from the .info file.
- $data = trim(preg_replace('/^settings\[.*\].*\n?/mi', '', $data));
-
- // Append the exported theme settings to the .info file if there are any.
- $data = $settings ? $data . "\n\n" . drush_omega_compose_info_file($settings, 'settings') : $data;
-
- // Write the data to the .info file of the theme.
- if (drush_op('file_put_contents', $path, $data)) {
- drush_log(dt('The theme settings for the @theme theme have been exported to the .info file of the theme.', array('@theme' => $themes[$theme]->info['name'])), 'success');
-
- if (drush_get_option('revert')) {
- // Revert the theme settings if the 'revert' option is set and they have
- // been exported successfully. In this case, we invoke the API function
- // through the drush command to display the messages.
- drush_invoke_process('@self', 'omega-revert', array($theme));
- }
-
- return TRUE;
- }
- else {
- // There was an error while exporting the theme settings.
- return drush_set_error('OMEGA_EXPORT_ERROR', dt('An error occurred while trying to export the theme settings for the @theme theme.', array('@theme' => $themes[$theme]->info['name'])));
- }
-}
-
-/**
- * Implements drush_hook_COMMAND_validate().
- */
-function drush_omega_revert_validate($theme = NULL) {
- return drush_omega_validate_theme($theme);
-}
-
-/**
- * Implements drush_hook_COMMAND().
- *
- * Delete the theme settings that have been stored in the database and thereby
- * reverts them to the default settings from the .info file.
- *
- * @param $theme
- * (optional) The machine-readable name of a theme.
- */
-function drush_omega_revert($theme = NULL) {
- if (drush_get_option('all')) {
- // Get a list of all Omega sub-themes.
- $themes = array();
- foreach (list_themes() as $key => $info) {
- $trail = omega_theme_trail($key);
- if (array_key_exists('omega', $trail)) {
- $themes[$key] = $info->info['name'];
- }
- }
-
- // Get confirmation from user.
- drush_print(dt('The settings for the following themes will be reverted: @themes', array('@themes' => implode(', ', $themes))));
- if (!drush_confirm(dt('Do you really want to continue?'))) {
- return;
- }
- }
- elseif (!isset($theme) && !$theme = drush_omega_theme_choice(dt('Which theme do you want to revert the theme settings for?'))) {
- return;
- }
-
- $info = list_themes();
- $themes = isset($themes) ? $themes : array($theme => $info[$theme]->info['name']);
- foreach ($themes as $theme => $name) {
- // Delete the theme settings variable for the given theme.
- drush_op('variable_del', 'theme_' . $theme . '_settings');
-
- // Clear the theme cache.
- cache_clear_all('omega:' . $theme . ':', 'cache', TRUE);
- }
-
- // Rebuild the theme data for good measure.
- drupal_theme_rebuild();
- system_rebuild_theme_data();
-
- drush_log(dt('You have successfully reverted the theme settings for these themes: @themes.', array('@themes' => implode(', ', $themes))), 'success');
-}
-
-/**
- * Implements drush_hook_COMMAND_validate().
- */
-function drush_omega_guard_validate($theme = NULL) {
- return drush_omega_validate_theme($theme);
-}
-
-/**
- * Implements drush_hook_COMMAND().
- *
- * Starts guard for the given theme for compass, theme registry rebuild and
- * livereload.
- *
- * @param $theme
- * (optional) The machine-readable name of a theme.
- */
-function drush_omega_guard($theme = NULL) {
- if (!isset($theme) && !$theme = drush_omega_theme_choice(dt('Which theme do you want to run Guard for?'))) {
- return;
- }
-
- // Check if Ruby is installed.
- drush_shell_exec('ruby --version');
- $output = reset(drush_shell_exec_output());
- $matches = array();
- if (!preg_match('/^ruby ([0-9][0-9\.]*)/', $output, $matches)) {
- // Ruby was not found on this machine.
- return drush_set_error(dt('You have to install Ruby version 1.9 or newer.'));
- }
- elseif (!version_compare($matches[1], '1.8', '>=')) {
- // Ruby is outdated.
- return drush_set_error(dt('The installed version of Ruby (@version) is outdated. Please upgrade to version 1.9 or newer.', array(
- '@version' => $matches[1],
- )));
- }
-
- // Check if Rubygems is installed.
- drush_shell_exec('gem --version');
- $output = reset(drush_shell_exec_output());
- $matches = array();
- if (!preg_match('/^[0-9][0-9\.]*$/', $output, $matches)) {
- // Rubygems was not found on this machine.
- return drush_set_error(dt('You have to install Rubygems version 1.8 or newer.'));
- }
- elseif (!version_compare($matches[0], '1.8', '>=')) {
- // Rubygems is outdated.
- return drush_set_error(dt('The installed version of Rubygems (@version) is outdated. Please upgrade to version 1.8 or newer.', array(
- '@version' => $matches[0],
- )));
- }
-
- // Check if Bundler is installed.
- drush_shell_exec('bundle --version');
- $output = reset(drush_shell_exec_output());
- $matches = array();
- if (!preg_match('/^Bundler version ([0-9][0-9\.]*)/', $output, $matches)) {
- // Bundler was not found on this machine.
- return drush_set_error(dt('You have to install Bundler version 1.2 or newer.'));
- }
- elseif (!version_compare($matches[1], '1.2', '>=')) {
- // Bundler is outdated.
- return drush_set_error(dt('The installed version of Bundler (@version) is outdated. Please upgrade to version 1.2 or newer.', array(
- '@version' => $matches[1],
- )));
- }
-
- // Retrieve the path to the theme.
- $path = drupal_get_path('theme', $theme);
-
- // Output an error message if the gemfiles dependencies are not satisfied.
- drush_shell_cd_and_exec(DRUPAL_ROOT . '/' . $path, 'bundle check --no-color');
- $output = drush_shell_exec_output();
- switch (reset($output)) {
- case "The Gemfile's dependencies are satisfied":
- // All is good, we can proceed.
- break;
-
- case 'Could not locate Gemfile':
- return drush_set_error(dt('There was no Gemfile at @path.', array(
- '@path' => $path,
- )));
-
- case "Your Gemfile's dependencies could not be satisfied":
- // @todo Add prompt for running 'bundle install'.
-
- default:
- return drush_set_error(dt("There was a problem with your setup:\n!error", array(
- '!error' => implode("\n", $output),
- )));
- }
-
- // This is the command for running guard through bundler.
- $command = 'bundle exec guard';
- if (drush_get_option('screen')) {
- drush_shell_exec('screen --version');
- if (!preg_match('/^Screen version/', reset(drush_shell_exec_output()))) {
- // Screen was not found on this machine.
- return drush_set_error(dt("You have to install 'screen' before you can run 'omega-guard' in a detached screen."));
- }
-
- // Check if there is already a screen. Running multiple screens at the same
- // time ultimately eats up too much performance. This way we ensure that
- // you don't accidently run the same screen session multiple times.
- drush_shell_exec('screen -list');
- foreach (drush_shell_exec_output() as $output) {
- $output = trim($output);
- $matches = array();
- if (preg_match('/^((\d+)\.omega:' . $theme . ':guard)/', $output, $matches)) {
- $themes = list_themes();
-
- // Make sure that we only got one screen for each theme at a time.
- if (drush_confirm(dt("There is already a screen running for @theme. Do you want to restart it?", array('@theme' => $themes[$theme]->name)))) {
- drush_shell_exec("screen -S $matches[2] -X quit");
- // We found an existing guard session and killed it.
- break;
- }
- else {
- // Fine, if the user does not want us to kill the session he has to do
- // it manually.
- return drush_set_error(dt("There is already a screen running for the @theme theme (@screen). You have to kill the runing screen with '@command' before you can start a new one.", array(
- '@theme' => $themes[$theme]->name,
- '@screen' => $matches[1],
- '@command' => "screen -S $matches[2] -X quit",
- )));
- }
- }
- };
-
- // We want to run the command in a detached (-dmS) screen.
- $command = "screen -dmS omega:$theme:guard $command";
- }
-
- // Polling is required for making guard watch work with remote file systems
- // e.g. in case of virtual environments where guard runs on the guest but
- // the files are modified on the host.
- if (drush_get_option('force-polling')) {
- $command .= ' --force-polling';
- }
-
- // Sometimes it seems to be required to set a latency (e.g. 5) if working with
- // polling because otherwise the file changes are detected twice. Hence,
- // not setting a latency might affect your system performance. If it doesn't
- // simply don't worry about it.
- if ($latency = drush_get_option('latency')) {
- $command .= ' --latency ' . $latency;
- }
-
- // Change the active directory to the theme folder and run the command there.
- drush_op('chdir', DRUPAL_ROOT . '/' . drupal_get_path('theme', $theme));
- drush_shell_exec_interactive($command);
-}
-
-/**
- * Resolves the destination path for a subtheme. This can either be a profile
- * theme folder, a sites theme folder or a theme.
- *
- * @param $destination
- * A destination string, this can either be a site path ('site:foo'), a
- * profile path ('profile:foo') or a theme path ('theme:foo').
- *
- * @return string|bool
- * The full path to the given destination, FALSE if the destination could not
- * be resolved.
- */
-function drush_omega_resolve_destination($destination) {
- list($type, $destination, $custom) = explode(':', $destination);
-
- // Add a '/' to the custom path suffix.
- $custom = $custom ? '/' . $custom : '';
-
- switch($type) {
- case 'site':
- if (array_key_exists($destination, drush_omega_sites())) {
- return 'sites/' . $destination . '/themes' . $custom;
- }
- break;
-
- case 'profile':
- require_once DRUPAL_ROOT . '/includes/install.core.inc';
- if (array_key_exists($destination, install_find_profiles())) {
- return 'profiles/' . $destination . '/themes' . $custom;
- }
- break;
-
- case 'theme':
- if (array_key_exists($destination, list_themes())) {
- return drupal_get_path('theme', $destination) . $custom;
- }
- break;
- }
-}
-
-/**
- * Helper function for printing a list of available Omega themes.
- *
- * @param $message
- * The message that should be displayed.
- *
- * @return bool|string
- * The machine-readable name of the chosen theme or FALSE if the operation was
- * cancelled.
- */
-function drush_omega_theme_choice($message) {
- $options = array();
- foreach (list_themes() as $key => $info) {
- $trail = omega_theme_trail($key);
- if (array_key_exists('omega', $trail)) {
- $parent = count($trail) > 1 ? array_slice($trail, -2, 1) : FALSE;
- $options[$key] = $info->info['name'] . ($parent ? ' (' . dt('Subtheme of @parent', array('@parent' => reset($parent))) . ')' : '') . ' - ' . strip_tags($info->info['description']);
- }
- }
- return drush_choice($options, $message);
-}
-
-/**
- * Helper function for printing a list of available starterkits.
- *
- * @param $basetheme
- * The machine-readable name of a basetheme.
- * @param $message
- * The message that should be displayed.
- *
- * @return bool|string
- * The machine-readable name of the chosen starterkit or FALSE if the
- * operation was cancelled.
- */
-function drush_omega_starterkit_choice($basetheme, $message) {
- $themes = list_themes();
- $options = array();
- foreach (omega_discovery('starterkit', $basetheme) as $key => $info) {
- $options[$key] = dt('@name: !description (Provided by @provider)', array(
- '@name' => $info['info']['name'],
- '!description' => isset($info['info']['description']) ? $info['info']['description'] : dt('No description'),
- '@provider' => $themes[$info['theme']]->info['name'],
- ));
- }
- return drush_choice($options, $message);
-}
-
-/**
- * Helper function that asks for the desired destination of a subtheme.
- *
- * @param $message
- * The message that should be displayed.
- *
- * @return bool|string
- * The given destination using the pattern "type:destination"
- * (e.g. "site:all") or FALSE if the operation was cancelled.
- */
-function drush_omega_destination_choice($message) {
- drush_print($message);
-
- // Let the user choose a destination.
- $options = array(
- 'site' => dt("Site (e.g. 'all' or 'example.com')"),
- 'profile' => dt('Installation profile'),
- 'theme' => dt('Parent theme'),
- );
-
- if (!$type = drush_choice($options, dt('Please choose a destination type.'))) {
- return FALSE;
- }
-
- switch ($type) {
- case 'site':
- if (!$destination = drush_choice(drush_omega_sites(), dt('Please choose a site.'))) {
- return FALSE;
- }
- return 'site:' . $destination;
-
- case 'profile':
- require_once DRUPAL_ROOT . '/includes/install.core.inc';
-
- $options = array();
- foreach (install_find_profiles() as $profile) {
- $info = drupal_parse_info_file(dirname($profile->uri) . '/' . $profile->name . '.info');
- $options[$profile->name] = $info['name'];
- }
-
- if (!$destination = drush_choice($options, dt('Please choose an installation profile.'))) {
- return FALSE;
- }
- return 'profile:' . $destination;
-
- case 'theme':
- if (!$destination = drush_omega_theme_choice(dt('Please choose a theme.'))) {
- return FALSE;
- }
- return 'theme:' . $destination;
-
- default:
- return 'site:all';
- }
-}
-
-/**
- * Helper function that continuously prompts for a valid machine-readable name.
- *
- * @param $message
- * The message that should be displayed.
- *
- * @return string
- * A valid, unique machine-readable name.
- */
-function drush_omega_require_valid_theme_name($message, $default = NULL) {
- while (TRUE) {
- // Keep prompting for a machine-name until we get an acceptable value.
- $prompt = drush_prompt($message, $default);
-
- if (!preg_match('/^[a-z][a-z0-9_]*$/', $prompt)) {
- drush_print('The machine-readable name is invalid. It may only contain lowercase numbers, letters and underscores and must start with a letter.');
- }
- else {
- $themes = list_themes();
- // Validate that the machine-readable name of the theme is unique.
- if (isset($themes[$prompt])) {
- drush_print(dt('A theme with the name @name already exists. The machine-readable name must be unique.', array(
- '@name' => $prompt,
- )));
- }
- else {
- // The given machine-readable name is valid. Let's proceed.
- return $prompt;
- }
- }
- }
-}
-
-/**
- * Recursively rewrites (and renames) all files in a given path.
- *
- * @param $path
- * The path to rewrite all files in.
- * @param $search
- * The string(s) to look for when replacing the file names and contents. Can
- * be an array or a string.
- * @param $replace
- * The string(s) to replace $search with. Can be an array or a string.
- *
- * @return bool
- * TRUE if the operation succeeded, FALSE otherwise.
- *
- * @see omega_drush_replace_contents()
- * @see str_replace()
- */
-function drush_omega_rewrite_recursive($path, $search, $replace) {
- if (!is_dir($path)) {
- return drush_set_error('INVALID_PATH', dt('The given path @path is not a directory.', array(
- '!path' => $path,
- )));
- }
-
- // If the file actually is a directory, proceed with the recursion.
- $directory = new DirectoryIterator($path);
- foreach ($directory as $item) {
- if ($item->isDot()) {
- // Do not process '..' and '.'.
- continue;
- }
-
- // Retrieve the path of the current item.
- $pathname = $item->getPathname();
- if ($item->isDir() && !drush_omega_rewrite_recursive($pathname, $search, $replace)) {
- return FALSE;
- }
- elseif ($item->isFile()) {
- // If it is a file, try to replace its contents.
- $contents = file_get_contents($pathname);
- if (($changed = preg_replace($search, $replace, $contents)) === NULL) {
- return drush_set_error('REWRITE_FAILURE', dt('There was an error while trying to rewrite !path (!search to !replace)', array(
- '!path' => $pathname,
- '!search' => $search,
- '!replace' => $replace,
- )));
- }
-
- if ($contents !== $changed) {
- file_put_contents($pathname, $changed);
- }
- }
-
- // Try to rename (move) the file if the name was changed.
- $original = basename($pathname);
- if (($renamed = preg_replace($search, $replace, $original)) === NULL) {
- return drush_set_error('REWRITE_FAILURE', dt('There was an error while trying to rewrite !path (!search to !replace)', array(
- '!path' => $path,
- '!search' => $search,
- '!replace' => $replace,
- )));
- }
-
- // Move (rename) if the file or directory name was changed.
- if ($original !== $renamed) {
- $new = dirname($pathname) . "/$renamed";
- if (!drush_move_dir($pathname, $new, TRUE)) {
- return FALSE;
- };
- }
- }
-
- return TRUE;
-}
-
-/**
- * Recursively builds an .info file structure from an array.
- *
- * @param $array
- * The array to build the .info file from.
- * @param $prefix
- * (Optional) Used internally to forward the current prefix (level of nesting)
- * for the keys.
- *
- * @return string
- * A .info file string.
- */
-function drush_omega_compose_info_file($array, $prefix = FALSE) {
- $info = '';
-
- foreach ($array as $key => $value) {
- if (is_array($value)) {
- // This is an array, let's proceed with the next level.
- $info .= drush_omega_compose_info_file($value, (!$prefix ? $key : "{$prefix}[{$key}]"));
- }
- else {
- // Escape all single quotes.
- $value = str_replace("'", "\'", $value);
- // Wrap the value in single quotes if it has any trailing or leading
- // whitespace or it is an empty string from the start.
- $value = $value === '' || trim($value) != $value ? "'" . $value . "'" : $value;
- // If the key is numeric remove it entirely (simple brackets are enough in
- // this case).
- $key = is_numeric($key) ? '' : $key;
-
- $info .= $prefix ? ("{$prefix}[" . $key .']') : $key;
- $info .= ' = ' . $value . "\n";
- }
- }
-
- return $info;
-}
-
-/**
- * Retrieve an array of available sites.
- *
- * @return array
- * An array that contains all the available sites in a multisite environment.
- */
-function drush_omega_sites() {
- $sites = array();
- // Look up the available sites by iterating over the contents of the sites
- // directory.
- $files = new DirectoryIterator(DRUPAL_ROOT . '/sites');
- foreach ($files as $file) {
- // The sites/default folder is not a valid destination.
- if ($file->isDir() && !$file->isDot() && $file->getFileName() != 'default') {
- $name = $file->getFileName();
- $sites[$name] = $name;
- }
- }
- return $sites;
-}
-
-/**
- * Helper function for generating a valid machine-readable name for a theme from
- * any string.
- *
- * @param $string
- * The string to generate the machine-readable name from.
- *
- * @return string
- * The generated machine-readable name.
- */
-function drush_omega_generate_theme_name($string) {
- // Machine-readable names have to start with a lowercase letter.
- $string = preg_replace('/^[^a-z]+/', '', strtolower($string));
- // Machine-readable names may only contain alphanumeric characters and
- // underscores.
- $string = preg_replace('/[^a-z0-9_]+/', '_', $string);
- // Trim all trailing and leading underscores.
- $string = trim($string, '_');
-
- $themes = list_themes();
- if (isset($themes[$string])) {
- $plain = $string;
- $counter = 0;
-
- while (isset($themes[$string])) {
- // Make sure that the machine-readable name of the theme is unique.
- $string = $plain . '_' . $counter++;
- }
- }
-
- return $string;
-}
-
-/**
- * Helper function for validating a given theme.
- */
-function drush_omega_validate_theme($theme = NULL) {
- if (!isset($theme)) {
- return;
- }
-
- // Rebuild the theme data so that we can safely check for the existence of
- // themes by using the information provided by list_themes().
- system_rebuild_theme_data();
-
- $themes = list_themes();
- // Check if the given theme exists.
- if (!isset($themes[$theme])) {
- return drush_set_error('OMEGA_THEME_DOES_NOT_EXIST', dt('There is no theme with the name @theme.', array(
- '@theme' => $theme,
- )));
- }
-}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/includes/omega.inc
--- a/sites/all/themes/omega/includes/omega.inc Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,697 +0,0 @@
-base_themes)) {
- $cache[$theme] = $GLOBALS['theme_info']->base_themes;
- }
-
- $themes = list_themes();
- if (empty($cache[$theme]) && isset($themes[$theme]->info['base theme'])) {
- $cache[$theme] = system_find_base_themes($themes, $theme);
- }
-
- // Add our current subtheme ($key) to that array.
- $cache[$theme][$theme] = $themes[$theme]->info['name'];
-
- return $cache[$theme];
-}
-
-/**
- * Helper function for generating a regex from a list of paths.
- *
- * Generates a single regex from a list of file paths that can be used to match
- * JS or CSS files using preg_grep() for example in hook_css_alter() or
- * hook_js_alter(). The '*' (asterisk) character can be used as a wild-card.
- *
- * @param $paths
- * An array of file paths.
- *
- * @return string
- * The generated regex.
- *
- * @see hook_js_alter()
- * @see hook_css_alter()
- */
-function omega_generate_path_regex($paths) {
- foreach ($paths as &$item) {
- // The first segment (everything before the first slash) is the namespace.
- // This rule only applies to local files... So if the namespace can not be
- // mapped to a module, profile or theme engine we assume that the we are
- // trying to target an external file.
- list($namespace) = explode('/', $item);
-
- // Check if the namespace refers to a file residing in the 'misc' folder or
- // if it is a global wildcard.
- if ($namespace !== '*' && $namespace !== 'misc') {
- // Otherwise, check if it refers to a theme, module, profile or theme
- // engine.
- foreach (array('theme', 'module', 'profile', 'theme_engine') as $type) {
- // We can't use drupal_get_path() directly because that uses dirname()
- // internally which returns '.' if no filename was found.
- if ($filename = drupal_get_filename($type, $namespace)) {
- $prefix = dirname($filename);
- $item = substr_replace($item, $prefix, 0, strlen($namespace));
- break;
- }
- }
- }
-
- // Escape any regex characters and turn asterisk wildcards into actual regex
- // wildcards.
- $item = preg_quote($item, '/');
- $item = str_replace('\*', '(.*)', $item);
- }
-
- return '/^' . implode('|', $paths) . '$/';
-}
-
-/**
- * Helper function for eliminating elements from an array using a simplified
- * regex pattern.
- *
- * @param $elements
- * The array of elements that should have some of its items removed.
- * @param $regex
- * A regex as generated by omega_generate_path_regex().
- */
-function omega_exclude_assets(&$elements, $regex) {
- $mapping = omega_generate_asset_mapping($elements);
-
- // Finally, implode the array of items to exclude into a proper regex and
- // invoke in on the array of files to be excluded.
- $elements = array_diff_key($elements, preg_grep($regex, $mapping));
-}
-
-/**
- * Helper function for generating a map of assets based on the data attribute.
- *
- * We can not rely on the array keys of the JS and CSS file arrays in Drupal
- * because in case of inline JS or CSS (which uses numerical array keys) and due
- * to potential overrides of the 'data' attribute which holds the actual,
- * reliable path of the file. This function returns a single-level array of
- * reliable JS/CSS file paths using the original array keys as keys. Elements of
- * type 'inline' or 'setting' are ignored.
- *
- * @param $elements
- * An array of JS or CSS files as given in hook_css_alter() or
- * hook_js_alter().
- *
- * @return array
- * A map of file paths generated from $elements.
- *
- * @see hook_js_alter()
- * @see hook_css_alter()
- */
-function omega_generate_asset_mapping($elements) {
- $mapping = array();
- foreach ($elements as $key => $item) {
- if ($item['type'] == 'inline' || $item['type'] == 'setting') {
- // Naturally, in-line CSS is not supported.
- continue;
- }
-
- // We need to build an array containing just the 'data' attribute because
- // that's the actual path of the file. The array key of the elements can
- // be something else if someone is sneaky enough to use drupal_add_js() or
- // drupal_add_css() with a bogus first argument (normally, that is the
- // path to the file) and then specify the actual path through the 'data'
- // attribute in the $options array.
- $mapping[$key] = $item['data'];
- }
-
- return $mapping;
-}
-
-/**
- * Retrieves the array of enabled extensions for a theme. Extensions can be
- * registered through the .info file. Each extension can define a theme settings
- * form altering function named
- * 'THEMENAME_extension_EXTENSION_theme_settings_form_alter()' through a file
- * named 'THEME_ROOT/includes/EXTENSION/EXTENSION.settings.inc' to have it
- * automatically included whenever the theme settings form is displayed. Each
- * extension can also define a
- * 'THEMENAME_extension_EXTENSION_theme_registry_alter()' function through a
- * file named 'THEME_ROOT/includes/EXTENSION/EXTENSION.inc' to register custom
- * hooks with the theme registry.
- *
- * @param $theme
- * (Optional) The key (machine-readable name) of a theme. Defaults to the key
- * of the current theme.
- *
- * @return array
- * The theme info array of the passed or current theme.
- *
- * @see _system_default_theme_features()
- * @see omega_extension_development_theme_settings_form_alter()
- * @see omega_extension_development_theme_registry_alter()
- */
-function omega_extensions($theme = NULL, $reset = FALSE) {
- $theme = isset($theme) ? $theme : $GLOBALS['theme_key'];
-
- if (!$reset) {
- if (($extensions = &drupal_static(__FUNCTION__)) && isset($extensions[$theme])) {
- return $extensions[$theme];
- }
-
- if (($cache = cache_get('omega:' . $theme . ':extensions')) !== FALSE) {
- return $extensions[$theme] = $cache->data;
- }
- }
-
- // Extensions can't be hidden.
- $extensions[$theme] = omega_discovery('extension', $theme);
-
- foreach ($extensions[$theme] as $extension => &$info) {
- // Make sure that the theme variable is never altered.
- $context = $theme;
- drupal_alter('omega_extension_info', $info, $context);
-
- // Determine if the extension is enabled.
- $info['enabled'] = omega_theme_get_setting('omega_toggle_extension_' . $extension, !empty($info['info']['enabled']));
-
- // Check if all dependencies are met.
- $info['errors'] = FALSE;
- if (!empty($info['info']['dependencies'])) {
- foreach ($info['info']['dependencies'] as $dependency) {
- $dependency = drupal_parse_dependency($dependency);
-
- if ((!$module = system_get_info('module', $dependency['name'])) || omega_check_incompatibility($dependency, $module['version'])) {
- $info['errors'] = TRUE;
- }
- }
- }
- }
-
- // Write to the cache.
- cache_set('omega:' . $theme . ':extensions', $extensions[$theme]);
-
- return $extensions[$theme];
-}
-
-/**
- * Determines if an extension is enabled.
- *
- * @param $extension
- * The machine-readable name of an extension.
- * @param $theme
- * (Optional) The key (machine-readable name) of a theme. Defaults to the key
- * of the current theme.
- *
- * @return bool
- * TRUE if the extension is enabled, FALSE otherwise.
- */
-function omega_extension_enabled($extension, $theme = NULL) {
- $theme = isset($theme) ? $theme : $GLOBALS['theme_key'];
- if (($extensions = omega_extensions($theme)) && isset($extensions[$extension])) {
- return empty($extensions[$extension]['errors']) && !empty($extensions[$extension]['enabled']) && variable_get('omega_toggle_extension_' . $extension, TRUE);
- }
-}
-
-/**
- * Looks up the info array of all themes in the theme trail and retrieves a
- * particular info array element.
- */
-function omega_theme_trail_info($element, $merge = TRUE, $theme = NULL) {
- $output = array();
-
- // Loop over all themes in the theme trail and look up $element in the .info
- // array.
- foreach (omega_theme_trail($theme) as $key => $name) {
- $info = omega_theme_info($key);
-
- // If $merge is TRUE we combine all the results of all themes in the theme
- // trail. Otherwise we just return the first occurrence.
- if (isset($info[$element]) && is_array($info[$element])) {
- $output = array_merge($info[$element], $output);
-
- if (!$merge) {
- return array('theme' => $key, 'info' => $output);
- }
- }
- }
-
- return $output;
-}
-
-/**
- * Retrieves the full info array of a theme.
- *
- * @param $theme
- * (Optional) The key (machine-readable name) of a theme. Defaults to the key
- * of the current theme.
- *
- * @return array
- * The theme info array of the passed or current theme.
- */
-function omega_theme_info($theme = NULL) {
- $theme = isset($theme) ? $theme : $GLOBALS['theme_key'];
-
- // If this is the current theme, just load the theme info from the globals.
- // Note: The global 'theme_key' property is not reliable in this case because
- // it gets overridden on theme settings pages.
- if ($theme == $GLOBALS['theme']) {
- return $GLOBALS['theme_info']->info;
- }
-
- $themes = list_themes();
- return $themes[$theme]->info;
-}
-
-/**
- * Invoke a hook in all themes in the theme trail that implement it.
- *
- * @param $hook
- * The name of the hook to invoke.
- * @param $theme
- * (Optional) The key (machine-readable name) of a theme. Defaults to the key
- * of the current theme.
- * @param ...
- * Arguments to pass to the hook.
- *
- * @return array
- * An array of return values of the hook implementations. If themes return
- * arrays from their implementations, those are merged into one array.
- *
- * @see module_invoke_all()
- */
-function omega_invoke_all($hook, $theme = NULL) {
- $theme = isset($theme) ? $theme : $GLOBALS['theme_key'];
-
- $args = func_get_args();
- // Remove $hook from the arguments.
- unset($args[0], $args[1]);
-
- $return = array();
- foreach (omega_theme_trail($theme) as $key => $name) {
- $function = $key . '_' . $hook;
-
- if (function_exists($function)) {
- $result = call_user_func_array($function, array_merge(array($theme), array_values($args)));
- if (isset($result) && is_array($result)) {
- // Append the 'theme' property to each array element.
- foreach ($result as &$item) {
- $item['theme'] = $key;
- }
- $return = array_merge_recursive($return, $result);
- }
- elseif (isset($result)) {
- $return[] = $result;
- }
- }
- }
- return $return;
-}
-
-/**
- * Custom implementation of drupal_array_get_nested_value() that also supports
- * objects instead of just arrays.
- *
- * @param $object
- * The array or object from which to get the value.
- * @param $parents
- * An array of parent keys of the value, starting with the outermost key.
- * @param $key_exists
- * (optional) If given, an already defined variable that is altered by
- * reference.
- *
- * @return mixed
- * The requested nested value. Possibly NULL if the value is NULL or not all
- * nested parent keys exist. $key_exists is altered by reference and is a
- * Boolean that indicates whether all nested parent keys exist (TRUE) or not
- * (FALSE). This allows to distinguish between the two possibilities when NULL
- * is returned.
- *
- * @see drupal_array_get_nested_value()
- */
-function omega_get_nested_value(&$object, array $parents, &$key_exists = NULL) {
- $ref = &$object;
- foreach ($parents as $parent) {
- if (is_array($ref) && array_key_exists($parent, $ref)) {
- $ref = &$ref[$parent];
- }
- elseif (is_object($ref) && property_exists($ref, $parent)) {
- $ref = &$ref->$parent;
- }
- else {
- $key_exists = FALSE;
- return NULL;
- }
- }
- $key_exists = TRUE;
- return $ref;
-}
-
-/**
- * Retrieves the info array for all available layouts.
- *
- * @return array
- * An array of available layouts for the given theme.
- */
-function omega_layouts_info() {
- if (($layouts = &drupal_static(__FUNCTION__)) !== NULL) {
- return $layouts;
- }
-
- // Try to retrieve the layouts definitions from cache.
- if (($cache = cache_get('omega:layouts')) !== FALSE) {
- return $layouts = $cache->data;
- }
-
- // Layouts do not have a specific theme scope.
- $layouts = omega_discovery('layout', FALSE);
- foreach ($layouts as $layout => &$info) {
- $info['attached'] = array();
- $info['template'] = isset($info['info']['template']) ? $info['info']['template'] : $layout;
- $root = drupal_get_path('theme', $info['theme']);
-
- if (isset($info['info']['stylesheets'])) {
- foreach ($info['info']['stylesheets'] as $media => $files) {
- foreach ($files as $key => $file) {
- if (is_file($info['path'] . '/' . $file)) {
- // First, check if the file exists in the layout's path.
- $path = $info['path'] . '/' . $file;
- }
- elseif (is_file($root . '/' . $file)) {
- // Otherwise, check if the file exists in the theme's path.
- $path = $root . '/' . $file;
- }
- else {
- // The specified file does not exist.
- continue;
- }
-
- $info['attached']['css']["$media:$key"] = array(
- 'data' => $path,
- 'media' => $media,
- 'group' => CSS_THEME,
- 'every_page' => TRUE,
- 'weight' => -10,
- );
- }
- }
- }
-
- // Look up possible CSS and JS file overrides.
- if (isset($info['info']['scripts'])) {
- foreach ($info['info']['scripts'] as $key => $file) {
- if (is_file($info['path'] . '/' . $file)) {
- // First, check if the file exists in the layout's path.
- $path = $info['path'] . '/' . $file;
- }
- elseif (is_file($root . '/' . $file)) {
- // Otherwise, check if the file exists in the theme's path.
- $path = $root . '/' . $file;
- }
- else {
- // The specified file does not exist.
- continue;
- }
-
- $info['attached']['js'][$key] = array(
- 'data' => $path,
- 'group' => JS_THEME,
- 'every_page' => TRUE,
- 'weight' => -10,
- );
- }
- }
- }
-
- // Give modules and themes a chance to alter the layout info array.
- drupal_alter('omega_layouts_info', $layouts);
-
- // Cache the layout definitions in the database.
- cache_set('omega:layouts', $layouts);
-
- return $layouts;
-}
-
-/**
- * Retrieves the active layout for the current page.
- *
- * @return array|bool
- * The info array for the active layout or FALSE if the current page does not
- * use an alternative page layout.
- */
-function omega_layout() {
- if (($cache = &drupal_static(__FUNCTION__)) !== NULL) {
- return $cache;
- }
-
- // Load the default layout from the theme settings.
- $layout = omega_theme_get_setting('omega_layout', 'simple');
- drupal_alter('omega_layout', $layout);
-
- $layouts = omega_layouts_info();
- $cache = isset($layouts[$layout]) ? $layouts[$layout] : FALSE;
-
- return $cache;
-}
-
-/**
- * Allow themes to easily define libraries.
- *
- * @param $theme
- * (Optional) The key (machine-readable name) of a theme. Defaults to the key
- * of the current theme.
- *
- * @return array
- * An array of libraries defined by themes in the theme trail of the given
- * theme.
- */
-function omega_theme_libraries_info($theme = NULL) {
- $theme = isset($theme) ? $theme : $GLOBALS['theme_key'];
-
- // Check if the libraries have already been statically cached.
- if (($libraries = &drupal_static(__FUNCTION__)) && isset($libraries[$theme])) {
- return $libraries[$theme];
- };
-
- // Try to retrieve the library definitions from cache.
- if (($cache = cache_get("omega:$theme:libraries")) !== FALSE) {
- return $libraries[$theme] = $cache->data;
- }
-
- // Retrieve the libraries by invoking the hook.
- $libraries[$theme] = omega_invoke_all('omega_theme_libraries_info');
-
- $context = $theme;
- // Give modules and themes a chance to alter the libraries info array.
- drupal_alter('omega_theme_libraries_info', $libraries[$theme], $context);
-
- // Cache the layout definitions in the database.
- cache_set("omega:$theme:libraries", $libraries[$theme]);
-
- return $libraries[$theme];
-}
-
-/**
- * Helper function for discovering layouts, extensions or other plugins of any
- * sort in the theme trail.
- *
- * @param $type
- * A theme extension type (e.g. layout or extension).
- * @param $theme
- * (Optional) The key (machine-readable name) of a theme. Defaults to the key
- * of the current theme.
- *
- * @return array
- * An array containing the discovered definitions.
- */
-function omega_discovery($type, $theme = NULL) {
- $theme = isset($theme) ? $theme : $GLOBALS['theme_key'];
-
- if (($discovery = &drupal_static(__FUNCTION__, array())) && isset($discovery[$theme][$type])) {
- return $discovery[$theme][$type];
- }
-
- $discovery[$theme][$type] = array();
-
- // Retrieve all themes from the theme trail of the given theme.
- $themes = $theme === FALSE ? list_themes() : omega_theme_trail($theme);
-
- // Collect paths to all sub-themes grouped by base themes. These will be
- // used for filtering. This allows base themes to have sub-themes in its
- // folder hierarchy without affecting the base themes template discovery.
- $paths = array();
- foreach ($themes as $key => $info) {
- if (!empty($info->base_theme)) {
- $paths[$info->base_theme][$key] = dirname($info->filename);
- }
- }
- foreach ($paths as $basetheme => $subthemes) {
- foreach ($subthemes as $subtheme => $path) {
- if (isset($paths[$subtheme])) {
- $paths[$basetheme] = array_merge($paths[$basetheme], $paths[$subtheme]);
- }
- }
- }
-
- $strlen = strlen($type) + 1;
- foreach ($themes as $key => $label) {
- // Retrieve the array of paths that should be ignored for this theme.
- $ignore = isset($paths[$key]) ? $paths[$key] : array();
- $path = drupal_get_path('theme', $key);
-
- // Support files without '.inc' extension for backwards compatibility.
- foreach (file_scan_directory($path, '/\.' . $type . '(\.inc)?$/', array('key' => 'name')) as $name => $file) {
- // Ignore sub-theme templates for the current theme.
- if (strpos($file->uri, str_replace($ignore, '', $file->uri)) !== 0) {
- continue;
- }
-
- if (substr($name, -$strlen) === '.' . $type) {
- $name = substr($name, 0, strlen($name) - $strlen);
- }
-
- if ($info = drupal_parse_info_file($file->uri)) {
- $discovery[$theme][$type][$name] = array(
- 'name' => $name,
- 'path' => dirname($file->uri),
- 'file' => $file->uri,
- 'info' => $info,
- 'theme' => $key,
- );
- }
- }
- }
-
- return $discovery[$theme][$type];
-}
-
-/**
- * Checks whether a version is compatible with a given dependency.
- *
- * This is a wrapper for drupal_check_incompatibility() which strips the core
- * version and any potential development version suffix from the given string.
- *
- * @param $dependency
- * The parsed dependency structure from drupal_parse_dependency().
- * @param $current
- * The version to check against (like 4.2).
- *
- * @return
- * NULL if compatible, otherwise the original dependency version string that
- * caused the incompatibility.
- *
- * @see drupal_check_incompatibility()
- * @see drupal_parse_dependency()
- */
-function omega_check_incompatibility($dependency, $current) {
- // Remove the core version from the version string.
- $current = preg_replace('/^' . DRUPAL_CORE_COMPATIBILITY . '-/', '', $current);
- // Remove any potential development version suffixes from the string.
- $current = preg_replace('/-dev$/', '', $current);
-
- return drupal_check_incompatibility($dependency, $current);
-}
-
-/**
- * Finds the first occurrence of a given file in the theme trail.
- *
- * @param $file
- * The relative path to a file.
- * @param $theme
- * (Optional) The key (machine-readable name) of a theme. Defaults to the key
- * of the current theme.
- *
- * @return string
- * The path to the file. If the file does not exist at all, it will simply
- * return the path of the file as it would be if it existed in the given theme
- * directly. This ensures that the code that uses this function does not break
- * if a file does not exist anywhere.
- */
-function omega_theme_trail_file($file, $theme = NULL) {
- $theme = isset($theme) ? $theme : $GLOBALS['theme_key'];
-
- // Iterate over all themes in the theme trail (starting with the active theme)
- // and return the first match.
- $current = NULL;
- foreach (array_reverse(omega_theme_trail($theme)) as $name => $info) {
- $current = drupal_get_path('theme', $name) . '/' . $file;
- if (file_exists($current)) {
- return $current;
- }
- }
-
- // The default (fallback) path is the path of the active theme, even if it
- // does not actually have that file.
- return drupal_get_path('theme', $theme) . '/' . $file;
-}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/includes/scripts.inc
--- a/sites/all/themes/omega/includes/scripts.inc Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,411 +0,0 @@
- $item) {
- if ($item['scope'] == $scope) {
- $items[$key] = $item;
- }
- }
-
- // Sort the JavaScript so that it appears in the correct order.
- uasort($items, 'drupal_sort_css_js');
-
- // In Drupal 8, there's a JS_SETTING group for making setting variables
- // appear last after libraries have loaded. In Drupal 7, this is forced
- // without that group. We do not use the $key => $item type of iteration,
- // because PHP uses an internal array pointer for that, and we're modifying
- // the array order inside the loop.
- foreach (array_keys($items) as $key) {
- if ($items[$key]['type'] == 'setting') {
- $item = $items[$key];
- unset($items[$key]);
- $items[$key] = $item;
- }
- }
-
- // There is no need for the ajax page state if there is no ajax js!
- if (array_key_exists('misc/ajax.js', $items)) {
- // Provide the page with information about the individual JavaScript files
- // used, information not otherwise available when aggregation is enabled.
- $setting['ajaxPageState']['js'] = array_fill_keys(array_keys($items), 1);
- unset($setting['ajaxPageState']['js']['settings']);
- drupal_add_js($setting, 'setting');
-
- // If we're outputting the header scope, then this might be the final time
- // that drupal_get_js() is running, so add the setting to this output as well
- // as to the drupal_add_js() cache. If $items['settings'] doesn't exist, it's
- // because drupal_get_js() was intentionally passed a $javascript argument
- // stripped of settings, potentially in order to override how settings get
- // output, so in this case, do not add the setting to this output.
- if ($scope == 'header' && isset($items['settings'])) {
- $items['settings']['data'][] = $setting;
- }
- }
-
- // Render the HTML needed to load the JavaScript.
- $elements = array(
- '#type' => 'scripts',
- '#items' => $items,
- );
-
- return drupal_render($elements);
-}
-
-/**
- * Callback to add the elements needed for JavaScript tags to be rendered.
- *
- * This function evaluates the aggregation enabled/disabled condition on a group
- * by group basis by testing whether an aggregate file has been made for the
- * group rather than by testing the site-wide aggregation setting. This allows
- * this function to work correctly even if modules have implemented custom
- * logic for grouping and aggregating files.
- *
- * @param $elements
- * A render array containing:
- * - #items: The JavaScript items as returned by drupal_add_js() and
- * altered by drupal_get_js().
- * - #group_callback: A function to call to group #items. Following
- * this function, #aggregate_callback is called to aggregate items within
- * the same group into a single file.
- * - #aggregate_callback: A function to call to aggregate the items within
- * the groups arranged by the #group_callback function.
- *
- * @return array
- * A render array that will render to a string of JavaScript tags.
- *
- * @see drupal_get_js()
- */
-function omega_pre_render_scripts($elements) {
- // Group and aggregate the items.
- if (isset($elements['#group_callback'])) {
- $elements['#groups'] = $elements['#group_callback']($elements['#items']);
- }
- if (isset($elements['#aggregate_callback'])) {
- $elements['#aggregate_callback']($elements['#groups']);
- }
-
- // A dummy query-string is added to filenames, to gain control over
- // browser-caching. The string changes on every update or full cache
- // flush, forcing browsers to load a new copy of the files, as the
- // URL changed. Files that should not be cached (see drupal_add_js())
- // get REQUEST_TIME as query-string instead, to enforce reload on every
- // page request.
- $default_query_string = variable_get('css_js_query_string', '0');
-
- // For inline JavaScript to validate as XHTML, all JavaScript containing
- // XHTML needs to be wrapped in CDATA. To make that backwards compatible
- // with HTML 4, we need to comment out the CDATA-tag.
- $embed_prefix = "\n\n";
-
- // Since JavaScript may look for arguments in the URL and act on them, some
- // third-party code might require the use of a different query string.
- $js_version_string = variable_get('drupal_js_version_query_string', 'v=');
-
- // Defaults for each SCRIPT element.
- $element_defaults = array(
- '#type' => 'html_tag',
- '#tag' => 'script',
- '#value' => '',
- '#attributes' => array(
- 'type' => 'text/javascript',
- ),
- );
-
- // Loop through each group.
- foreach ($elements['#groups'] as $group) {
- // If a group of files has been aggregated into a single file,
- // $group['data'] contains the URI of the aggregate file. Add a single
- // script element for this file.
- if ($group['type'] == 'file' && isset($group['data'])) {
- $element = $element_defaults;
- $element['#attributes']['src'] = file_create_url($group['data']);
- $element['#browsers'] = $group['browsers'];
- $elements[] = $element;
- }
- // For non-file types, and non-aggregated files, add a script element per
- // item.
- else {
- foreach ($group['items'] as $item) {
- // Element properties that do not depend on item type.
- $element = $element_defaults;
- if (!empty($item['defer'])) {
- $element['#attributes']['defer'] = 'defer';
- }
- $element['#browsers'] = $item['browsers'];
-
- // Element properties that depend on item type.
- switch ($item['type']) {
- case 'setting':
- $element['#value_prefix'] = $embed_prefix;
- $element['#value'] = 'jQuery.extend(Drupal.settings, ' . drupal_json_encode(drupal_array_merge_deep_array($item['data'])) . ");";
- $element['#value_suffix'] = $embed_suffix;
- break;
-
- case 'inline':
- $element['#value_prefix'] = $embed_prefix;
- $element['#value'] = $item['data'];
- $element['#value_suffix'] = $embed_suffix;
- break;
-
- case 'file':
- $query_string = empty($item['version']) ? $default_query_string : $js_version_string . $item['version'];
- $query_string_separator = (strpos($item['data'], '?') !== FALSE) ? '&' : '?';
- $element['#attributes']['src'] = file_create_url($item['data']) . $query_string_separator . ($item['cache'] ? $query_string : REQUEST_TIME);
- break;
-
- case 'external':
- $element['#attributes']['src'] = $item['data'];
- break;
- }
-
- $elements[] = $element;
- }
- }
- }
-
- return $elements;
-}
-
-/**
- * Default callback to aggregate JavaScript files.
- *
- * Having the browser load fewer JavaScript files results in much faster page
- * loads than when it loads many small files. This function aggregates files
- * within the same group into a single file unless the site-wide setting to do
- * so is disabled (commonly the case during site development). To optimize
- * download, it also compresses the aggregate files by removing comments,
- * whitespace, and other unnecessary content.
- *
- * @param $js_groups
- * An array of JavaScript groups as returned by drupal_group_js(). For each
- * group that is aggregated, this function sets the value of the group's
- * 'data' key to the URI of the aggregate file.
- *
- * @see drupal_group_js()
- * @see drupal_pre_render_scripts()
- */
-function omega_aggregate_js(&$js_groups) {
- // Only aggregate when the site is configured to do so, and not during an
- // update.
- if (variable_get('preprocess_js', FALSE) && (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update')) {
- foreach ($js_groups as $key => $group) {
- if ($group['type'] == 'file' && $group['preprocess']) {
- $js_groups[$key]['data'] = omega_build_js_cache($group['items']);
- }
- }
- }
-}
-
-/**
- * Aggregates JavaScript files into a cache file in the files directory.
- *
- * The file name for the JavaScript cache file is generated from the hash of
- * the aggregated contents of the files in $files. This forces proxies and
- * browsers to download new JavaScript when the JavaScript changes.
- *
- * The cache file name is retrieved on a page load via a lookup variable that
- * contains an associative array. The array key is the hash of the names in
- * $files while the value is the cache file name. The cache file is generated
- * in two cases. First, if there is no file name value for the key, which will
- * happen if a new file name has been added to $files or after the lookup
- * variable is emptied to force a rebuild of the cache. Second, the cache file
- * is generated if it is missing on disk. Old cache files are not deleted
- * immediately when the lookup variable is emptied, but are deleted after a set
- * period by drupal_delete_file_if_stale(). This ensures that files referenced
- * by a cached page will still be available.
- *
- * @param $files
- * An array of JavaScript files to aggregate and compress into one file.
- *
- * @return string|bool
- * The URI of the cache file, or FALSE if the file could not be saved.
- */
-function omega_build_js_cache($files) {
- $contents = '';
- $uri = '';
- $map = variable_get('drupal_js_cache_files', array());
- // Create a new array so that only the file names are used to create the hash.
- // This prevents new aggregates from being created unnecessarily.
- $js_data = array();
- foreach ($files as $file) {
- $js_data[] = $file['data'];
- }
- $key = hash('sha256', serialize($js_data));
- if (isset($map[$key])) {
- $uri = $map[$key];
- }
-
- if (empty($uri) || !file_exists($uri)) {
- // Build aggregate JS file.
- foreach ($files as $path => $info) {
- if ($info['preprocess']) {
- // Append a ';' and a newline after each JS file to prevent them from running together.
- $contents .= file_get_contents($info['data']) . ";\n";
- }
- }
- // Prefix filename to prevent blocking by firewalls which reject files
- // starting with "ad*".
- $filename = 'js_' . drupal_hash_base64($contents) . '.js';
- // Create the js/ within the files folder.
- $jspath = 'public://js';
- $uri = $jspath . '/' . $filename;
- // Create the JS file.
- file_prepare_directory($jspath, FILE_CREATE_DIRECTORY);
- if (!file_exists($uri) && !file_unmanaged_save_data($contents, $uri, FILE_EXISTS_REPLACE)) {
- return FALSE;
- }
- // If JS gzip compression is enabled, clean URLs are enabled (which means
- // that rewrite rules are working) and the zlib extension is available then
- // create a gzipped version of this file. This file is served conditionally
- // to browsers that accept gzip using .htaccess rules.
- if (variable_get('js_gzip_compression', TRUE) && variable_get('clean_url', 0) && extension_loaded('zlib')) {
- if (!file_exists($uri . '.gz') && !file_unmanaged_save_data(gzencode($contents, 9, FORCE_GZIP), $uri . '.gz', FILE_EXISTS_REPLACE)) {
- return FALSE;
- }
- }
- $map[$key] = $uri;
- variable_set('drupal_js_cache_files', $map);
- }
- return $uri;
-}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/js/jquery.matchmedia.js
--- a/sites/all/themes/omega/js/jquery.matchmedia.js Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-(function ($, window) {
-
- 'use strict';
-
- /**
- * Check if the given media query currently applies.
- *
- * @param query
- * The media query to check for.
- *
- * @deprecated
- * Use window.matchMedia() instead.
- */
- $.matchmedia = function (query) {
- return window.matchMedia(query);
- };
-
- /**
- * Special event for listening to media query changes.
- *
- * @deprecated
- * Use window.matchMedia(query).addListener(callback) instead.
- */
- var event = $.event.special.mediaquery = {
- objects: {},
-
- handler: function (handler) {
- return function (mql) {
- mql.applies = mql.matches;
- handler.call(mql, mql);
- };
- },
-
- add: function (handleObj) {
- event.objects[handleObj.guid] = window.matchMedia(handleObj.data);
- event.objects[handleObj.guid].addListener(event.handler(handleObj.handler));
- },
-
- remove: function (handleObj) {
- event.objects[handleObj.guid].removeListener(event.handler(handleObj.handler));
- }
- };
-
- /**
- * Event shortcut.
- *
- * @deprecated
- * Use window.matchMedia(query).addListener(callback) instead.
- */
- $.fn.mediaquery = function (query, callback) {
- return $(this).bind('mediaquery', query, callback);
- };
-
-})(jQuery, window);
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/js/jquery.matchmedia.min.js
--- a/sites/all/themes/omega/js/jquery.matchmedia.min.js Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-!function($,window){"use strict";$.matchmedia=function(query){return window.matchMedia(query)};var event=$.event.special.mediaquery={objects:{},handler:function(handler){return function(mql){mql.applies=mql.matches;handler.call(mql,mql)}},add:function(handleObj){event.objects[handleObj.guid]=window.matchMedia(handleObj.data);event.objects[handleObj.guid].addListener(event.handler(handleObj.handler))},remove:function(handleObj){event.objects[handleObj.guid].removeListener(event.handler(handleObj.handler))}};$.fn.mediaquery=function(query,callback){return $(this).bind("mediaquery",query,callback)}}(jQuery,window);
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/js/jquery.resizeend.js
--- a/sites/all/themes/omega/js/jquery.resizeend.js Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-(function ($) {
-
- 'use strict';
-
- /**
- * Container for the resizeend timeout.
- */
- var resizeTimeout;
-
- /**
- * Throttled resize event. Fires only once after the resize ended.
- */
- var event = $.event.special.resizeend = {
- setup: function () {
- $(this).bind('resize', event.handler);
- },
-
- teardown: function () {
- $(this).unbind('resize', event.handler);
- },
-
- handler: function (e) {
- var context = this;
- if (resizeTimeout) {
- clearTimeout(resizeTimeout);
- }
-
- resizeTimeout = setTimeout(function () {
- // Set correct event type
- e.type = 'resizeend';
- $.event.handle.apply(context);
- }, 150);
- }
- };
-
- /**
- * Wrapper for the resizeend event.
- */
- $.fn.resizeend = function (handler) {
- return $(this).bind('resizeend', handler);
- };
-
-})(jQuery);
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/js/jquery.resizeend.min.js
--- a/sites/all/themes/omega/js/jquery.resizeend.min.js Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-!function($){"use strict";var resizeTimeout;var event=$.event.special.resizeend={setup:function(){$(this).bind("resize",event.handler)},teardown:function(){$(this).unbind("resize",event.handler)},handler:function(e){var context=this;if(resizeTimeout){clearTimeout(resizeTimeout)}resizeTimeout=setTimeout(function(){e.type="resizeend";$.event.handle.apply(context)},150)}};$.fn.resizeend=function(handler){return $(this).bind("resizeend",handler)}}(jQuery);
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/js/jquery.scrollable.js
--- a/sites/all/themes/omega/js/jquery.scrollable.js Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-(function ($) {
-
- 'use strict';
-
- /**
- * Custom expression for filtering for scrollable elements.
- */
- $.expr[':'].scrollable = function (elem) {
- var scrollable = true;
- // Backup the original scroll position.
- var original = $(elem).scrollTop();
-
- if (original === 0) {
- $(elem).scrollTop(1);
- scrollable = $(elem).scrollTop() === 1;
- $(elem).scrollTop(0);
- }
-
- return scrollable;
- };
-
-})(jQuery);
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/js/jquery.scrollable.min.js
--- a/sites/all/themes/omega/js/jquery.scrollable.min.js Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-!function($,window){"use strict";$.matchmedia=function(query){return window.matchMedia(query)};var event=$.event.special.mediaquery={objects:{},handler:function(handler){return function(mql){mql.applies=mql.matches;handler.call(mql,mql)}},add:function(handleObj){event.objects[handleObj.guid]=window.matchMedia(handleObj.data);event.objects[handleObj.guid].addListener(event.handler(handleObj.handler))},remove:function(handleObj){event.objects[handleObj.guid].removeListener(event.handler(handleObj.handler))}};$.fn.mediaquery=function(query,callback){return $(this).bind("mediaquery",query,callback)}}(jQuery,window);
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/js/omega.admin.js
--- a/sites/all/themes/omega/js/omega.admin.js Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-(function ($) {
-
- 'use strict';
-
- /**
- * Allows administrators to click on the icon of a layout instead of having to
- * target the radio button in order to select it.
- */
- Drupal.behaviors.omegaThemeSettingsLayouts = {
- attach: function (context) {
- $('.form-item-omega-layout .omega-layout-icon', context).click(function () {
- $(this).siblings('.form-item').find('input').click().change();
- });
- }
- };
-
- /**
- * Provide a nice little summary for the vertical tab pane of each extension
- * which indicates whether or not it is currently enabled.
- */
- Drupal.behaviors.omegaExtensionSummary = {
- attach: function (context) {
- $('fieldset[id^=edit-].omega-extension', context).each(function () {
- var extension = $(this).attr('id').substring(5);
- var $fieldset = $(this);
- var $checkbox = $fieldset.find('input[name="omega_toggle_extension_' + extension + '"]');
-
- $fieldset.drupalSetSummary(function () {
- if (!$checkbox.is(':checked')) {
- return Drupal.t('This extension is currently disabled');
- }
- });
-
- $checkbox.change(function () {
- $fieldset.trigger('summaryUpdated');
- });
- });
- }
- };
-
-})(jQuery);
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/js/omega.admin.min.js
--- a/sites/all/themes/omega/js/omega.admin.min.js Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-!function($){"use strict";Drupal.behaviors.omegaThemeSettingsLayouts={attach:function(context){$(".form-item-omega-layout .omega-layout-icon",context).click(function(){$(this).siblings(".form-item").find("input").click().change()})}};Drupal.behaviors.omegaExtensionSummary={attach:function(context){$("fieldset[id^=edit-].omega-extension",context).each(function(){var extension=$(this).attr("id").substring(5);var $fieldset=$(this);var $checkbox=$fieldset.find('input[name="omega_toggle_extension_'+extension+'"]');$fieldset.drupalSetSummary(function(){if(!$checkbox.is(":checked")){return Drupal.t("This extension is currently disabled")}});$checkbox.change(function(){$fieldset.trigger("summaryUpdated")})})}}}(jQuery);
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/js/omega.indicator.js
--- a/sites/all/themes/omega/js/omega.indicator.js Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-(function ($) {
-
- 'use strict';
-
- /**
- * Renders a widget for displaying the current width of the browser.
- */
- Drupal.behaviors.omegaBrowserWidth = {
- attach: function (context) {
- $('body', context).once('omega-browser-width', function () {
- var $indicator = $('').appendTo(this);
-
- // Bind to the window.resize event to continuously update the width.
- $(window).bind('resize.omega-browser-width', function () {
- $indicator.text($(this).width() + 'px');
- }).trigger('resize.omega-browser-width');
- });
- }
- };
-
-})(jQuery);
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/js/omega.indicator.min.js
--- a/sites/all/themes/omega/js/omega.indicator.min.js Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-!function($){"use strict";Drupal.behaviors.omegaBrowserWidth={attach:function(context){$("body",context).once("omega-browser-width",function(){var $indicator=$('').appendTo(this);$(window).bind("resize.omega-browser-width",function(){$indicator.text($(this).width()+"px")}).trigger("resize.omega-browser-width")})}}}(jQuery);
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/js/omega.mediaqueries.js
--- a/sites/all/themes/omega/js/omega.mediaqueries.js Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-(function ($, window, Drupal) {
-
- 'use strict';
-
- /**
- * Toggles media-query specific body classes.
- *
- * You can define new media queries to listen to by writing them into the
- * Drupal.settings.omegaSettings.mediaQueries array.
- */
- Drupal.behaviors.omegaMediaQueryClasses = {
- handler: function (name, mql) {
- if (mql.matches) {
- $('body').removeClass(name + '-inactive').addClass(name + '-active');
- }
- else {
- $('body').removeClass(name + '-active').addClass(name + '-inactive');
- }
- },
-
- attach: function (context, settings) {
- var behavior = this;
- var omegaSettings = settings.omega || {};
- var mediaQueries = omegaSettings.mediaQueries || {};
-
- $('body', context).once('omega-mediaqueries', function () {
- $.each(mediaQueries, function (index, value) {
- var mql = window.matchMedia(value);
-
- // Initially, check if the media query applies or not and add the
- // corresponding class to the body.
- behavior.handler(index, mql);
-
- // React to media query changes and toggle the class names.
- mql.addListener(function (mql) {
- behavior.handler(index, mql);
- });
- });
- });
- }
- };
-
-})(jQuery, window, Drupal);
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/js/omega.mediaqueries.min.js
--- a/sites/all/themes/omega/js/omega.mediaqueries.min.js Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-!function($,window,Drupal){"use strict";Drupal.behaviors.omegaMediaQueryClasses={handler:function(name,mql){if(mql.matches){$("body").removeClass(name+"-inactive").addClass(name+"-active")}else{$("body").removeClass(name+"-active").addClass(name+"-inactive")}},attach:function(context,settings){var behavior=this;var omegaSettings=settings.omega||{};var mediaQueries=omegaSettings.mediaQueries||{};$("body",context).once("omega-mediaqueries",function(){$.each(mediaQueries,function(index,value){var mql=window.matchMedia(value);behavior.handler(index,mql);mql.addListener(function(mql){behavior.handler(index,mql)})})})}}}(jQuery,window,Drupal);
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/js/omega.messages.js
--- a/sites/all/themes/omega/js/omega.messages.js Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-(function ($, Drupal) {
-
- 'use strict';
-
- /**
- * Adds a 'close' link on messages that allows them to be discarded.
- */
- Drupal.behaviors.omegaCloseableMessages = {
- attach: function (context) {
- $('.messages', context).once('closeable-messages', function () {
- $('').click(function () {
- $(this).closest('.messages').fadeOut(function () {
- $(this).remove();
- });
-
- return false;
- }).appendTo(this);
- });
- }
- };
-
-})(jQuery, Drupal);
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/js/omega.messages.min.js
--- a/sites/all/themes/omega/js/omega.messages.min.js Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-!function($,Drupal){"use strict";Drupal.behaviors.omegaCloseableMessages={attach:function(context){$(".messages",context).once("closeable-messages",function(){$('').click(function(){$(this).closest(".messages").fadeOut(function(){$(this).remove()});return false}).appendTo(this)})}}}(jQuery,Drupal);
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/layouts/simple/preview.png
Binary file sites/all/themes/omega/layouts/simple/preview.png has changed
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/layouts/simple/simple-layout.tpl.php
--- a/sites/all/themes/omega/layouts/simple/simple-layout.tpl.php Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-
+
+
+
+
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/ohm/templates/comment/comment.tpl.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/ohm/templates/comment/comment.tpl.php Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,92 @@
+created variable.
+ * - $changed: Formatted date and time for when the comment was last changed.
+ * Preprocess functions can reformat it by calling format_date() with the
+ * desired parameters on the $comment->changed variable.
+ * - $new: New comment marker.
+ * - $permalink: Comment permalink.
+ * - $submitted: Submission information created from $author and $created during
+ * template_preprocess_comment().
+ * - $user_picture: The comment author's picture from user-picture.tpl.php.
+ * - $signature: Authors signature.
+ * - $status: Comment status. Possible values are:
+ * comment-unpublished, comment-published or comment-preview.
+ * - $title: Linked title.
+ * - $classes: String of classes that can be used to style contextually through
+ * CSS. It can be manipulated through the variable $classes_array from
+ * preprocess functions. The default values can be one or more of the
+ * following:
+ * - comment: The current template type, i.e., "theming hook".
+ * - comment-by-anonymous: Comment by an unregistered user.
+ * - comment-by-node-author: Comment by the author of the parent node.
+ * - comment-preview: When previewing a new or edited comment.
+ * The following applies only to viewers who are registered users:
+ * - comment-unpublished: An unpublished comment visible only to
+ * administrators.
+ * - comment-by-viewer: Comment by the user currently viewing the page.
+ * - comment-new: New comment since last the visit.
+ * - $title_prefix (array): An array containing additional output populated by
+ * modules, intended to be displayed in front of the main title tag that
+ * appears in the template.
+ * - $title_suffix (array): An array containing additional output populated by
+ * modules, intended to be displayed after the main title tag that appears in
+ * the template.
+ *
+ * These two variables are provided for context:
+ * - $comment: Full comment object.
+ * - $node: Node object the comments are attached to.
+ *
+ * Other variables:
+ * - $classes_array: Array of html class attribute values. It is flattened
+ * into a string within the variable $classes.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_comment()
+ * @see template_process()
+ * @see theme_comment()
+ */
+?>
+>
+
+
+
';
+ }
+ }
+ }
+
+ return $element;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/includes/omega.drush.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/includes/omega.drush.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,979 @@
+ dt('Creates a Omega subtheme.'),
+ 'arguments' => array(
+ 'name' => dt('The name of your subtheme.'),
+ ),
+ 'options' => array(
+ 'destination' => dt('The destination of your subtheme. Defaults to "site:all" (sites/all/themes). May be one of "site:foo", "profile:bar" or "theme:baz" ("foo", "bar" and "baz" being the name of your site, profile or parent theme). May also have a third part for sub-pathing. For example, if using site:all:custom/cat, then the theme will be created in sites/all/themes/custom/cat/.'),
+ 'machine-name' => dt('The machine-readable name of your subtheme. This will be auto-generated from the human-readable name if omitted.'),
+ 'starterkit' => dt('The starterkit that your subtheme should use. Defaults to "default".'),
+ 'basetheme' => dt('Specifies a custom base theme. Defaults to "omega".'),
+ 'enable' => dt('Automatically enable the subtheme after creation.'),
+ 'set-default' => dt('Automatically enable the subtheme after creation and make it the default theme.'),
+ 'no-readme' => dt('Skips readme files when generating the subtheme.'),
+ 'no-libraries' => dt("Prevent execution of the theme's libraries.make file.")
+ ),
+ 'examples' => array(
+ 'drush omega-subtheme "My Theme"' => dt('Creates an Omega subtheme called "My Theme".'),
+ 'drush omega-subtheme "My Theme" --destination=site:example.com' => dt('Creates an Omega subtheme called "My Theme" in sites/example.com/themes.'),
+ 'drush omega-subtheme "My Theme" --basetheme=my_custom_basetheme' => dt('Uses the default starterkit from a custom basetheme to create an Omega subtheme called "My Theme" in sites/all/themes.'),
+ 'drush omega-subtheme "My Theme" --basetheme=my_custom_basetheme --starterkit=my_custom_starterkit' => dt('Uses the my_custom_starterkit from a custom basetheme to create an Omega subtheme called "My Theme" in sites/all/themes.'),
+ ),
+ 'aliases' => array('osub'),
+ );
+
+ $items['omega-wizard'] = array(
+ 'description' => dt('Guides you through a wizard for generating a subtheme.'),
+ 'aliases' => array('owiz'),
+ );
+
+ $items['omega-guard'] = array(
+ 'description' => dt('Runs guard for the given theme including Compass and LiveReload by default.'),
+ 'arguments' => array(
+ 'name' => dt('The name of your subtheme.'),
+ ),
+ 'options' => array(
+ 'screen' => dt('Run guard watch in a detached screen.'),
+ 'force-polling' => dt('Polling is required for making guard watch work with remote file systems e.g. in case of virtual environments where guard runs on the guest but the files are modified on the host.'),
+ 'latency' => dt("Sometimes it seems to be required to set a latency (e.g. 5) if working with --force-polling because otherwise file changes are detected twice. Hence, not setting a latency might affect your system performance."),
+ ),
+ 'aliases' => array('ogrd'),
+ );
+
+ $items['omega-export'] = array(
+ 'description' => dt('Exports the theme settings of a given theme from the database to the .info file.'),
+ 'arguments' => array(
+ 'theme' => dt('The machine-readable name of the theme to export the theme settings for.'),
+ ),
+ 'options' => array(
+ 'revert' => dt('Purges the theme settings from the database after exporting them to the .info file.'),
+ ),
+ 'examples' => array(
+ 'drush omega-export foo' => dt('Exports the theme settings of the "foo" theme to the "foo.info" file in that theme.'),
+ 'drush omega-export foo --revert' => dt('Purges the theme settings of the "foo" theme from the database after exporting them to the .info file.'),
+ ),
+ 'aliases' => array('oexp'),
+ );
+
+ $items['omega-revert'] = array(
+ 'description' => dt('Reverts the theme settings of a given theme by deleting them from the database.'),
+ 'arguments' => array(
+ 'theme' => dt('The machine-readable name of the theme to revert the theme settings for.'),
+ ),
+ 'options' => array(
+ 'all' => dt('Reverts the theme settings of all Omega sub-themes.'),
+ ),
+ 'examples' => array(
+ 'drush omega-revert foo' => dt('Reverts the theme settings of the "foo" theme.'),
+ ),
+ 'aliases' => array('orev'),
+ );
+
+ return $items;
+}
+
+/**
+ * Implements hook_drush_help().
+ */
+function omega_drush_help($section) {
+ switch ($section) {
+ case 'drush:omega-subtheme':
+ return dt('Generates a subtheme.');
+ case 'drush:omega-wizard':
+ return dt('Guides you through a wizard for generating a subtheme.');
+ case 'drush:omega-guard':
+ return dt('Runs guard for the given theme including Compass and LiveReload by default.');
+ case 'drush:omega-export':
+ return dt('Exports the theme settings of a given theme.');
+ case 'drush:omega-revert':
+ return dt('Reverts the theme settings of a given theme.');
+ }
+}
+
+/**
+ * Implements drush_hook_COMMAND_validate().
+ */
+function drush_omega_subtheme_validate($name = NULL) {
+ if (!isset($name)) {
+ return drush_set_error('OMEGA_MISSING_ARGUMENT', dt("You didn't specify a name for the subtheme."));
+ }
+
+ // Rebuild the theme data so that we can safely check for the existence of
+ // themes by using the information provided by list_themes().
+ system_rebuild_theme_data();
+
+ if ($machine_name = drush_get_option('machine-name')) {
+ // Validate the machine-readable name of the theme.
+ if (!is_string($machine_name)) {
+ return drush_set_error('OMEGA_THEME_NAME_INVALID', dt('The --machine-name option expects a string value.'));
+ }
+
+ if (!preg_match('/^[a-z][a-z0-9_]*$/', $machine_name)) {
+ return drush_set_error('OMEGA_THEME_NAME_INVALID', dt('The machine name (@name) is invalid. It may only contain lowercase numbers, letters and underscores and must start with a letter.', array(
+ '@name' => $machine_name,
+ )));
+ }
+
+ $themes = list_themes();
+ // Validate that the machine-readable name of the theme is unique.
+ if (isset($themes[$machine_name])) {
+ return drush_set_error('OMEGA_THEME_ALREADY_EXISTS', dt('A theme with the name @name already exists. The machine-readable name must be unique.', array(
+ '@name' => $machine_name,
+ )));
+ }
+ }
+
+ if ($destination = drush_get_option('destination')) {
+ // Check if the syntax of the destination is valid.
+ if (!is_string($destination) || !preg_match('/^(site|theme|profile)(:(.+?)){1,2}$/', $destination)) {
+ return drush_set_error('OMEGA_DESTINATION_INVALID', dt('The destination syntax (@destination) is invalid. Please use one of the following destination patterns (site, profile or theme): --destination="site:foo", --destination="profile:bar" or --destination="theme:baz".', array(
+ '@destination' => $destination,
+ )));
+ }
+
+ // Check if the provided destination exists.
+ if (!drush_omega_resolve_destination($destination)) {
+ list($type, $destination) = explode(':', $destination);
+
+ return drush_set_error('OMEGA_DESTINATION_DOES_NOT_EXIST', dt('The given destination @destination of type @type does not exist. Did you misspell it?', array(
+ '@destination' => $destination,
+ '@type' => $type,
+ )));
+ }
+ }
+
+ if ($basetheme = drush_get_option('basetheme')) {
+ if (!is_string($basetheme)) {
+ return drush_set_error('OMEGA_BASETHEME_INVALID', dt('The --basetheme option expects a string value.'));
+ }
+
+ // Check if the base theme exists.
+ if (!array_key_exists($basetheme, list_themes())) {
+ return drush_set_error('OMEGA_BASETHEME_DOES_NOT_EXIST', dt('The base theme @basetheme does not exist or is invalid.', array(
+ '@basetheme' => $basetheme,
+ )));
+ }
+
+ // Check if the base theme is an Omega theme.
+ if (!array_key_exists('omega', omega_theme_trail($basetheme))) {
+ return drush_set_error('OMEGA_BASETHEME_INVALID', dt('The base theme @basetheme does not exist or is invalid.', array(
+ '@basetheme' => $basetheme,
+ )));
+ }
+ }
+
+ if ($starterkit = drush_get_option('starterkit')) {
+ if (!is_string($starterkit)) {
+ return drush_set_error('OMEGA_STARTERKIT_INVALID', dt('The --starterkit option expects a string value.'));
+ }
+
+ $basetheme = drush_get_option('basetheme', 'omega');
+
+ // Check if the starterkit exists.
+ if (!array_key_exists($starterkit, omega_discovery('starterkit', $basetheme))) {
+ $themes = list_themes();
+
+ return drush_set_error('OMEGA_STARTERKIT_DOES_NOT_EXIST', dt('There is no valid @basetheme theme starterkit with the name @starterkit. Did you forget to specify the correct basetheme?', array(
+ '@basetheme' => $themes[$basetheme]->info['name'],
+ '@starterkit' => $starterkit,
+ )));
+ }
+ }
+}
+
+/**
+ * Implements drush_hook_COMMAND().
+ */
+function drush_omega_subtheme($name) {
+ // Try to generate a machine-readable name. If that fails, prompt for one.
+ if (!$machine_name = drush_get_option('machine-name', drush_omega_generate_theme_name($name))) {
+ drush_print(dt("Sorry, I couldn't generate a machine-readable name for @name. Please use the '--machine-name' option to specify it manually.", array(
+ '@name' => $name,
+ )));
+ }
+
+ $basetheme = drush_get_option('basetheme', 'omega');
+ $starterkits = omega_discovery('starterkit', $basetheme);
+ $starterkit = drush_get_option('starterkit', 'basic');
+ $starterkit = $starterkits[$starterkit];
+
+ // Check whether the destination path does not exist and bail out if it does
+ // so we don't delete any important data by accident.
+ $destination = drush_omega_resolve_destination(drush_get_option('destination', 'site:all')) . '/' . $machine_name;
+ if (file_exists($destination)) {
+ return drush_set_error('OMEGA_SUBTHEME_PATH', dt('The path @path already exists.', array('@path' => $destination)));
+ }
+
+ // Create a temporary directory so we don't leave any stale files if an
+ // operation fails.
+ $temporary = drush_tempdir() . '/' . $name;
+
+ // Try to copy the starterkit to the destination path of the new subtheme.
+ if (!drush_copy_dir($starterkit['path'], $temporary)) {
+ return drush_set_error('OMEGA_GENERATE_SUBTHEME', dt('Failed to generate subtheme.'));
+ }
+
+ // Delete the .starterkit.inc file.
+ drush_delete_dir($temporary . '/' . basename($starterkit['file']));
+
+ // Put the name and description for the new subtheme in place.
+ $info = array(
+ 'name' => $name,
+ 'description' => 'Please provide a description for your theme.',
+ 'base theme' => $basetheme,
+ ) + $starterkit['info'];
+
+ // Write to the new .info file.
+ $file = $temporary . '/' . $machine_name . '.info';
+ if (!file_put_contents($file, drush_omega_compose_info_file($info))) {
+ return drush_set_error('OMEGA_GENERATE_SUBTHEME', dt('Failed to generate subtheme.'));
+ }
+
+ // Optionally remove README.txt files.
+ if (drush_get_option('no-readme')) {
+ foreach (file_scan_directory($temporary, '/^README/') as $file) {
+ drush_delete_dir($file->uri);
+ }
+ }
+
+ // Recursively rewrite the file names and contents of all the files that are
+ // now in the subtheme's directory to represent the human- and
+ // machine-readable names of the subtheme.
+ $search = array('/{{ THEME }}/', '/{{ THEMENAME }}/');
+ $replace = array($machine_name, $name);
+ if (!drush_omega_rewrite_recursive($temporary, $search, $replace)) {
+ return drush_set_error('OMEGA_GENERATE_SUBTHEME', dt('Failed to generate subtheme.'));
+ }
+
+ // Move the new subtheme to its destination.
+ if (!drush_op('drush_mkdir', dirname($destination)) || !drush_op('drush_move_dir', $temporary, $destination)) {
+ return drush_set_error('OMEGA_GENERATE_SUBTHEME', dt('Failed to generate subtheme.'));
+ }
+
+ // Rebuild the theme caches so that we can do some final tasks.
+ drupal_theme_rebuild();
+ system_rebuild_theme_data();
+
+ if (($default = drush_get_option('set-default')) || !drush_get_option('enable')) {
+ // Enable the subtheme.
+ drush_op('theme_enable', array($machine_name));
+
+ if ($default) {
+ // Make the newly created subtheme the default theme.
+ drush_op('variable_set', 'theme_default', $machine_name);
+ }
+ }
+
+ // Execute the theme's libraries.make file unless disabled.
+ if (!drush_get_option('no-libraries') && is_file("$destination/libraries.make")) {
+ drush_op('chdir', $destination);
+ drush_invoke_process('@self', 'make', array('libraries.make'), array(
+ 'no-core' => TRUE,
+ 'contrib-destination' => '.',
+ 'yes' => TRUE,
+ ));
+ }
+
+ drush_log(dt('You have successfully created the theme @theme (@name) in @path.', array(
+ '@theme' => $name,
+ '@name' => $machine_name,
+ '@path' => dirname($destination),
+ )), 'success');
+}
+
+/**
+ * Implements drush_hook_COMMAND().
+ */
+function drush_omega_wizard() {
+ // Rebuild the theme data so that we can safely check for the existence of
+ // themes by using the information provided by list_themes().
+ system_rebuild_theme_data();
+
+ // Prompt for a theme name.
+ $name = drush_prompt(dt('Please enter the name of the new sub-theme'), 'Omega Subtheme');
+
+ // Try to generate a machine-readable name. If that fails, prompt for one.
+ if (!$machine_name = drush_omega_generate_theme_name($name)) {
+ drush_print(dt("Sorry, I couldn't generate a machine-readable name for @name", array(
+ '@name' => $name,
+ )));
+ }
+ // Prompt for a theme name using the automatically generated default if any.
+ drush_set_option('machine-name', drush_omega_require_valid_theme_name(dt('Please enter a machine-readable name for your new theme'), $machine_name));
+
+ // Prompt for a base theme.
+ if (!$basetheme = drush_omega_theme_choice(dt('Please choose a base theme for your new theme'))) {
+ return;
+ }
+ drush_set_option('basetheme', $basetheme);
+
+ // Let the user choose a starterkit.
+ if (!$starterkit = drush_omega_starterkit_choice($basetheme, dt('Please choose a starterkit for your new theme'))) {
+ return;
+ }
+ drush_set_option('starterkit', $starterkit);
+
+ // Let the user choose a destination.
+ if (!$destination = drush_omega_destination_choice(dt('Please choose a destination. This is where your sub-theme will be placed'))) {
+ return;
+ }
+ drush_set_option('destination', $destination);
+
+ // Optionally skip readme files when generating the subtheme.
+ drush_set_option('no-readme', !drush_confirm(dt("Do you want to keep the starterkit's readme files?")));
+
+ // Finally, let the user choose to directly enable the subtheme.
+ if ($enable = drush_confirm(dt('Do you want to enable your new theme?'))) {
+ drush_set_option('set-default', drush_confirm(dt('Do you want to make your new theme the default theme?')));
+ }
+ drush_set_option('enable', $enable);
+
+ drush_invoke('omega-subtheme', $name);
+}
+
+/**
+ * Implements drush_hook_COMMAND_validate().
+ */
+function drush_omega_export_validate($theme = NULL) {
+ return drush_omega_validate_theme($theme);
+}
+
+/**
+ * Implements drush_hook_COMMAND().
+ *
+ * Exports the theme settings for the given theme from the database and writes
+ * them into the .info file of that theme.
+ *
+ * @param $theme
+ * (optional) The machine-readable name of a theme.
+ * @return bool
+ * TRUE on success, FALSE on failure.
+ */
+function drush_omega_export($theme = NULL) {
+ if (!isset($theme) && !$theme = drush_omega_theme_choice(dt('Which theme do you want to export the theme settings for?'))) {
+ return;
+ }
+
+ $themes = list_themes();
+
+ // Insert the theme settings from the database.
+ if (!$settings = variable_get('theme_' . $theme . '_settings')) {
+ if (!drush_confirm(dt('There are no theme settings for @theme stored in the database. Do you want to purge the theme settings from the .info file too?', array('@theme' => $themes[$theme]->info['name'])))) {
+ return;
+ }
+ }
+
+ // Parse the current content of the .info file so we can append the settings
+ // from the database.
+ $path = drupal_get_path('theme', $theme) . '/' . $theme . '.info';
+ $data = file_get_contents($path);
+
+ // Remove the old theme settings from the .info file.
+ $data = trim(preg_replace('/^settings\[.*\].*\n?/mi', '', $data));
+
+ // Append the exported theme settings to the .info file if there are any.
+ $data = $settings ? $data . "\n\n" . drush_omega_compose_info_file($settings, 'settings') : $data;
+
+ // Write the data to the .info file of the theme.
+ if (drush_op('file_put_contents', $path, $data)) {
+ drush_log(dt('The theme settings for the @theme theme have been exported to the .info file of the theme.', array('@theme' => $themes[$theme]->info['name'])), 'success');
+
+ if (drush_get_option('revert')) {
+ // Revert the theme settings if the 'revert' option is set and they have
+ // been exported successfully. In this case, we invoke the API function
+ // through the drush command to display the messages.
+ drush_invoke_process('@self', 'omega-revert', array($theme));
+ }
+
+ return TRUE;
+ }
+ else {
+ // There was an error while exporting the theme settings.
+ return drush_set_error('OMEGA_EXPORT_ERROR', dt('An error occurred while trying to export the theme settings for the @theme theme.', array('@theme' => $themes[$theme]->info['name'])));
+ }
+}
+
+/**
+ * Implements drush_hook_COMMAND_validate().
+ */
+function drush_omega_revert_validate($theme = NULL) {
+ return drush_omega_validate_theme($theme);
+}
+
+/**
+ * Implements drush_hook_COMMAND().
+ *
+ * Delete the theme settings that have been stored in the database and thereby
+ * reverts them to the default settings from the .info file.
+ *
+ * @param $theme
+ * (optional) The machine-readable name of a theme.
+ */
+function drush_omega_revert($theme = NULL) {
+ if (drush_get_option('all')) {
+ // Get a list of all Omega sub-themes.
+ $themes = array();
+ foreach (list_themes() as $key => $info) {
+ $trail = omega_theme_trail($key);
+ if (array_key_exists('omega', $trail)) {
+ $themes[$key] = $info->info['name'];
+ }
+ }
+
+ // Get confirmation from user.
+ drush_print(dt('The settings for the following themes will be reverted: @themes', array('@themes' => implode(', ', $themes))));
+ if (!drush_confirm(dt('Do you really want to continue?'))) {
+ return;
+ }
+ }
+ elseif (!isset($theme) && !$theme = drush_omega_theme_choice(dt('Which theme do you want to revert the theme settings for?'))) {
+ return;
+ }
+
+ $info = list_themes();
+ $themes = isset($themes) ? $themes : array($theme => $info[$theme]->info['name']);
+ foreach ($themes as $theme => $name) {
+ // Delete the theme settings variable for the given theme.
+ drush_op('variable_del', 'theme_' . $theme . '_settings');
+
+ // Clear the theme cache.
+ cache_clear_all('omega:' . $theme . ':', 'cache', TRUE);
+ }
+
+ // Rebuild the theme data for good measure.
+ drupal_theme_rebuild();
+ system_rebuild_theme_data();
+
+ drush_log(dt('You have successfully reverted the theme settings for these themes: @themes.', array('@themes' => implode(', ', $themes))), 'success');
+}
+
+/**
+ * Implements drush_hook_COMMAND_validate().
+ */
+function drush_omega_guard_validate($theme = NULL) {
+ return drush_omega_validate_theme($theme);
+}
+
+/**
+ * Implements drush_hook_COMMAND().
+ *
+ * Starts guard for the given theme for compass, theme registry rebuild and
+ * livereload.
+ *
+ * @param $theme
+ * (optional) The machine-readable name of a theme.
+ */
+function drush_omega_guard($theme = NULL) {
+ if (!isset($theme) && !$theme = drush_omega_theme_choice(dt('Which theme do you want to run Guard for?'))) {
+ return;
+ }
+
+ // Check if Ruby is installed.
+ drush_shell_exec('ruby --version');
+ $output = reset(drush_shell_exec_output());
+ $matches = array();
+ if (!preg_match('/^ruby ([0-9][0-9\.]*)/', $output, $matches)) {
+ // Ruby was not found on this machine.
+ return drush_set_error(dt('You have to install Ruby version 1.9 or newer.'));
+ }
+ elseif (!version_compare($matches[1], '1.8', '>=')) {
+ // Ruby is outdated.
+ return drush_set_error(dt('The installed version of Ruby (@version) is outdated. Please upgrade to version 1.9 or newer.', array(
+ '@version' => $matches[1],
+ )));
+ }
+
+ // Check if Rubygems is installed.
+ drush_shell_exec('gem --version');
+ $output = reset(drush_shell_exec_output());
+ $matches = array();
+ if (!preg_match('/^[0-9][0-9\.]*$/', $output, $matches)) {
+ // Rubygems was not found on this machine.
+ return drush_set_error(dt('You have to install Rubygems version 1.8 or newer.'));
+ }
+ elseif (!version_compare($matches[0], '1.8', '>=')) {
+ // Rubygems is outdated.
+ return drush_set_error(dt('The installed version of Rubygems (@version) is outdated. Please upgrade to version 1.8 or newer.', array(
+ '@version' => $matches[0],
+ )));
+ }
+
+ // Check if Bundler is installed.
+ drush_shell_exec('bundle --version');
+ $output = reset(drush_shell_exec_output());
+ $matches = array();
+ if (!preg_match('/^Bundler version ([0-9][0-9\.]*)/', $output, $matches)) {
+ // Bundler was not found on this machine.
+ return drush_set_error(dt('You have to install Bundler version 1.2 or newer.'));
+ }
+ elseif (!version_compare($matches[1], '1.2', '>=')) {
+ // Bundler is outdated.
+ return drush_set_error(dt('The installed version of Bundler (@version) is outdated. Please upgrade to version 1.2 or newer.', array(
+ '@version' => $matches[1],
+ )));
+ }
+
+ // Retrieve the path to the theme.
+ $path = drupal_get_path('theme', $theme);
+
+ // Output an error message if the gemfiles dependencies are not satisfied.
+ drush_shell_cd_and_exec(DRUPAL_ROOT . '/' . $path, 'bundle check --no-color');
+ $output = drush_shell_exec_output();
+ switch (reset($output)) {
+ case "The Gemfile's dependencies are satisfied":
+ // All is good, we can proceed.
+ break;
+
+ case 'Could not locate Gemfile':
+ return drush_set_error(dt('There was no Gemfile at @path.', array(
+ '@path' => $path,
+ )));
+
+ case "Your Gemfile's dependencies could not be satisfied":
+ // @todo Add prompt for running 'bundle install'.
+
+ default:
+ return drush_set_error(dt("There was a problem with your setup:\n!error", array(
+ '!error' => implode("\n", $output),
+ )));
+ }
+
+ // This is the command for running guard through bundler.
+ $command = 'bundle exec guard';
+ if (drush_get_option('screen')) {
+ drush_shell_exec('screen --version');
+ if (!preg_match('/^Screen version/', reset(drush_shell_exec_output()))) {
+ // Screen was not found on this machine.
+ return drush_set_error(dt("You have to install 'screen' before you can run 'omega-guard' in a detached screen."));
+ }
+
+ // Check if there is already a screen. Running multiple screens at the same
+ // time ultimately eats up too much performance. This way we ensure that
+ // you don't accidently run the same screen session multiple times.
+ drush_shell_exec('screen -list');
+ foreach (drush_shell_exec_output() as $output) {
+ $output = trim($output);
+ $matches = array();
+ if (preg_match('/^((\d+)\.omega:' . $theme . ':guard)/', $output, $matches)) {
+ $themes = list_themes();
+
+ // Make sure that we only got one screen for each theme at a time.
+ if (drush_confirm(dt("There is already a screen running for @theme. Do you want to restart it?", array('@theme' => $themes[$theme]->name)))) {
+ drush_shell_exec("screen -S $matches[2] -X quit");
+ // We found an existing guard session and killed it.
+ break;
+ }
+ else {
+ // Fine, if the user does not want us to kill the session he has to do
+ // it manually.
+ return drush_set_error(dt("There is already a screen running for the @theme theme (@screen). You have to kill the runing screen with '@command' before you can start a new one.", array(
+ '@theme' => $themes[$theme]->name,
+ '@screen' => $matches[1],
+ '@command' => "screen -S $matches[2] -X quit",
+ )));
+ }
+ }
+ };
+
+ // We want to run the command in a detached (-dmS) screen.
+ $command = "screen -dmS omega:$theme:guard $command";
+ }
+
+ // Polling is required for making guard watch work with remote file systems
+ // e.g. in case of virtual environments where guard runs on the guest but
+ // the files are modified on the host.
+ if (drush_get_option('force-polling')) {
+ $command .= ' --force-polling';
+ }
+
+ // Sometimes it seems to be required to set a latency (e.g. 5) if working with
+ // polling because otherwise the file changes are detected twice. Hence,
+ // not setting a latency might affect your system performance. If it doesn't
+ // simply don't worry about it.
+ if ($latency = drush_get_option('latency')) {
+ $command .= ' --latency ' . $latency;
+ }
+
+ // Change the active directory to the theme folder and run the command there.
+ drush_op('chdir', DRUPAL_ROOT . '/' . drupal_get_path('theme', $theme));
+ drush_shell_exec_interactive($command);
+}
+
+/**
+ * Resolves the destination path for a subtheme. This can either be a profile
+ * theme folder, a sites theme folder or a theme.
+ *
+ * @param $destination
+ * A destination string, this can either be a site path ('site:foo'), a
+ * profile path ('profile:foo') or a theme path ('theme:foo').
+ *
+ * @return string|bool
+ * The full path to the given destination, FALSE if the destination could not
+ * be resolved.
+ */
+function drush_omega_resolve_destination($destination) {
+ list($type, $destination, $custom) = explode(':', $destination);
+
+ // Add a '/' to the custom path suffix.
+ $custom = $custom ? '/' . $custom : '';
+
+ switch($type) {
+ case 'site':
+ if (array_key_exists($destination, drush_omega_sites())) {
+ return 'sites/' . $destination . '/themes' . $custom;
+ }
+ break;
+
+ case 'profile':
+ require_once DRUPAL_ROOT . '/includes/install.core.inc';
+ if (array_key_exists($destination, install_find_profiles())) {
+ return 'profiles/' . $destination . '/themes' . $custom;
+ }
+ break;
+
+ case 'theme':
+ if (array_key_exists($destination, list_themes())) {
+ return drupal_get_path('theme', $destination) . $custom;
+ }
+ break;
+ }
+}
+
+/**
+ * Helper function for printing a list of available Omega themes.
+ *
+ * @param $message
+ * The message that should be displayed.
+ *
+ * @return bool|string
+ * The machine-readable name of the chosen theme or FALSE if the operation was
+ * cancelled.
+ */
+function drush_omega_theme_choice($message) {
+ $options = array();
+ foreach (list_themes() as $key => $info) {
+ $trail = omega_theme_trail($key);
+ if (array_key_exists('omega', $trail)) {
+ $parent = count($trail) > 1 ? array_slice($trail, -2, 1) : FALSE;
+ $options[$key] = $info->info['name'] . ($parent ? ' (' . dt('Subtheme of @parent', array('@parent' => reset($parent))) . ')' : '') . ' - ' . strip_tags($info->info['description']);
+ }
+ }
+ return drush_choice($options, $message);
+}
+
+/**
+ * Helper function for printing a list of available starterkits.
+ *
+ * @param $basetheme
+ * The machine-readable name of a basetheme.
+ * @param $message
+ * The message that should be displayed.
+ *
+ * @return bool|string
+ * The machine-readable name of the chosen starterkit or FALSE if the
+ * operation was cancelled.
+ */
+function drush_omega_starterkit_choice($basetheme, $message) {
+ $themes = list_themes();
+ $options = array();
+ foreach (omega_discovery('starterkit', $basetheme) as $key => $info) {
+ $options[$key] = dt('@name: !description (Provided by @provider)', array(
+ '@name' => $info['info']['name'],
+ '!description' => isset($info['info']['description']) ? $info['info']['description'] : dt('No description'),
+ '@provider' => $themes[$info['theme']]->info['name'],
+ ));
+ }
+ return drush_choice($options, $message);
+}
+
+/**
+ * Helper function that asks for the desired destination of a subtheme.
+ *
+ * @param $message
+ * The message that should be displayed.
+ *
+ * @return bool|string
+ * The given destination using the pattern "type:destination"
+ * (e.g. "site:all") or FALSE if the operation was cancelled.
+ */
+function drush_omega_destination_choice($message) {
+ drush_print($message);
+
+ // Let the user choose a destination.
+ $options = array(
+ 'site' => dt("Site (e.g. 'all' or 'example.com')"),
+ 'profile' => dt('Installation profile'),
+ 'theme' => dt('Parent theme'),
+ );
+
+ if (!$type = drush_choice($options, dt('Please choose a destination type.'))) {
+ return FALSE;
+ }
+
+ switch ($type) {
+ case 'site':
+ if (!$destination = drush_choice(drush_omega_sites(), dt('Please choose a site.'))) {
+ return FALSE;
+ }
+ return 'site:' . $destination;
+
+ case 'profile':
+ require_once DRUPAL_ROOT . '/includes/install.core.inc';
+
+ $options = array();
+ foreach (install_find_profiles() as $profile) {
+ $info = drupal_parse_info_file(dirname($profile->uri) . '/' . $profile->name . '.info');
+ $options[$profile->name] = $info['name'];
+ }
+
+ if (!$destination = drush_choice($options, dt('Please choose an installation profile.'))) {
+ return FALSE;
+ }
+ return 'profile:' . $destination;
+
+ case 'theme':
+ if (!$destination = drush_omega_theme_choice(dt('Please choose a theme.'))) {
+ return FALSE;
+ }
+ return 'theme:' . $destination;
+
+ default:
+ return 'site:all';
+ }
+}
+
+/**
+ * Helper function that continuously prompts for a valid machine-readable name.
+ *
+ * @param $message
+ * The message that should be displayed.
+ *
+ * @return string
+ * A valid, unique machine-readable name.
+ */
+function drush_omega_require_valid_theme_name($message, $default = NULL) {
+ while (TRUE) {
+ // Keep prompting for a machine-name until we get an acceptable value.
+ $prompt = drush_prompt($message, $default);
+
+ if (!preg_match('/^[a-z][a-z0-9_]*$/', $prompt)) {
+ drush_print('The machine-readable name is invalid. It may only contain lowercase numbers, letters and underscores and must start with a letter.');
+ }
+ else {
+ $themes = list_themes();
+ // Validate that the machine-readable name of the theme is unique.
+ if (isset($themes[$prompt])) {
+ drush_print(dt('A theme with the name @name already exists. The machine-readable name must be unique.', array(
+ '@name' => $prompt,
+ )));
+ }
+ else {
+ // The given machine-readable name is valid. Let's proceed.
+ return $prompt;
+ }
+ }
+ }
+}
+
+/**
+ * Recursively rewrites (and renames) all files in a given path.
+ *
+ * @param $path
+ * The path to rewrite all files in.
+ * @param $search
+ * The string(s) to look for when replacing the file names and contents. Can
+ * be an array or a string.
+ * @param $replace
+ * The string(s) to replace $search with. Can be an array or a string.
+ *
+ * @return bool
+ * TRUE if the operation succeeded, FALSE otherwise.
+ *
+ * @see omega_drush_replace_contents()
+ * @see str_replace()
+ */
+function drush_omega_rewrite_recursive($path, $search, $replace) {
+ if (!is_dir($path)) {
+ return drush_set_error('INVALID_PATH', dt('The given path @path is not a directory.', array(
+ '!path' => $path,
+ )));
+ }
+
+ // If the file actually is a directory, proceed with the recursion.
+ $directory = new DirectoryIterator($path);
+ foreach ($directory as $item) {
+ if ($item->isDot()) {
+ // Do not process '..' and '.'.
+ continue;
+ }
+
+ // Retrieve the path of the current item.
+ $pathname = $item->getPathname();
+ if ($item->isDir() && !drush_omega_rewrite_recursive($pathname, $search, $replace)) {
+ return FALSE;
+ }
+ elseif ($item->isFile()) {
+ // If it is a file, try to replace its contents.
+ $contents = file_get_contents($pathname);
+ if (($changed = preg_replace($search, $replace, $contents)) === NULL) {
+ return drush_set_error('REWRITE_FAILURE', dt('There was an error while trying to rewrite !path (!search to !replace)', array(
+ '!path' => $pathname,
+ '!search' => $search,
+ '!replace' => $replace,
+ )));
+ }
+
+ if ($contents !== $changed) {
+ file_put_contents($pathname, $changed);
+ }
+ }
+
+ // Try to rename (move) the file if the name was changed.
+ $original = basename($pathname);
+ if (($renamed = preg_replace($search, $replace, $original)) === NULL) {
+ return drush_set_error('REWRITE_FAILURE', dt('There was an error while trying to rewrite !path (!search to !replace)', array(
+ '!path' => $path,
+ '!search' => $search,
+ '!replace' => $replace,
+ )));
+ }
+
+ // Move (rename) if the file or directory name was changed.
+ if ($original !== $renamed) {
+ $new = dirname($pathname) . "/$renamed";
+ if (!drush_move_dir($pathname, $new, TRUE)) {
+ return FALSE;
+ };
+ }
+ }
+
+ return TRUE;
+}
+
+/**
+ * Recursively builds an .info file structure from an array.
+ *
+ * @param $array
+ * The array to build the .info file from.
+ * @param $prefix
+ * (Optional) Used internally to forward the current prefix (level of nesting)
+ * for the keys.
+ *
+ * @return string
+ * A .info file string.
+ */
+function drush_omega_compose_info_file($array, $prefix = FALSE) {
+ $info = '';
+
+ foreach ($array as $key => $value) {
+ if (is_array($value)) {
+ // This is an array, let's proceed with the next level.
+ $info .= drush_omega_compose_info_file($value, (!$prefix ? $key : "{$prefix}[{$key}]"));
+ }
+ else {
+ // Escape all single quotes.
+ $value = str_replace("'", "\'", $value);
+ // Wrap the value in single quotes if it has any trailing or leading
+ // whitespace or it is an empty string from the start.
+ $value = $value === '' || trim($value) != $value ? "'" . $value . "'" : $value;
+ // If the key is numeric remove it entirely (simple brackets are enough in
+ // this case).
+ $key = is_numeric($key) ? '' : $key;
+
+ $info .= $prefix ? ("{$prefix}[" . $key .']') : $key;
+ $info .= ' = ' . $value . "\n";
+ }
+ }
+
+ return $info;
+}
+
+/**
+ * Retrieve an array of available sites.
+ *
+ * @return array
+ * An array that contains all the available sites in a multisite environment.
+ */
+function drush_omega_sites() {
+ $sites = array();
+ // Look up the available sites by iterating over the contents of the sites
+ // directory.
+ $files = new DirectoryIterator(DRUPAL_ROOT . '/sites');
+ foreach ($files as $file) {
+ // The sites/default folder is not a valid destination.
+ if ($file->isDir() && !$file->isDot() && $file->getFileName() != 'default') {
+ $name = $file->getFileName();
+ $sites[$name] = $name;
+ }
+ }
+ return $sites;
+}
+
+/**
+ * Helper function for generating a valid machine-readable name for a theme from
+ * any string.
+ *
+ * @param $string
+ * The string to generate the machine-readable name from.
+ *
+ * @return string
+ * The generated machine-readable name.
+ */
+function drush_omega_generate_theme_name($string) {
+ // Machine-readable names have to start with a lowercase letter.
+ $string = preg_replace('/^[^a-z]+/', '', strtolower($string));
+ // Machine-readable names may only contain alphanumeric characters and
+ // underscores.
+ $string = preg_replace('/[^a-z0-9_]+/', '_', $string);
+ // Trim all trailing and leading underscores.
+ $string = trim($string, '_');
+
+ $themes = list_themes();
+ if (isset($themes[$string])) {
+ $plain = $string;
+ $counter = 0;
+
+ while (isset($themes[$string])) {
+ // Make sure that the machine-readable name of the theme is unique.
+ $string = $plain . '_' . $counter++;
+ }
+ }
+
+ return $string;
+}
+
+/**
+ * Helper function for validating a given theme.
+ */
+function drush_omega_validate_theme($theme = NULL) {
+ if (!isset($theme)) {
+ return;
+ }
+
+ // Rebuild the theme data so that we can safely check for the existence of
+ // themes by using the information provided by list_themes().
+ system_rebuild_theme_data();
+
+ $themes = list_themes();
+ // Check if the given theme exists.
+ if (!isset($themes[$theme])) {
+ return drush_set_error('OMEGA_THEME_DOES_NOT_EXIST', dt('There is no theme with the name @theme.', array(
+ '@theme' => $theme,
+ )));
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/includes/omega.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/includes/omega.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,697 @@
+base_themes)) {
+ $cache[$theme] = $GLOBALS['theme_info']->base_themes;
+ }
+
+ $themes = list_themes();
+ if (empty($cache[$theme]) && isset($themes[$theme]->info['base theme'])) {
+ $cache[$theme] = system_find_base_themes($themes, $theme);
+ }
+
+ // Add our current subtheme ($key) to that array.
+ $cache[$theme][$theme] = $themes[$theme]->info['name'];
+
+ return $cache[$theme];
+}
+
+/**
+ * Helper function for generating a regex from a list of paths.
+ *
+ * Generates a single regex from a list of file paths that can be used to match
+ * JS or CSS files using preg_grep() for example in hook_css_alter() or
+ * hook_js_alter(). The '*' (asterisk) character can be used as a wild-card.
+ *
+ * @param $paths
+ * An array of file paths.
+ *
+ * @return string
+ * The generated regex.
+ *
+ * @see hook_js_alter()
+ * @see hook_css_alter()
+ */
+function omega_generate_path_regex($paths) {
+ foreach ($paths as &$item) {
+ // The first segment (everything before the first slash) is the namespace.
+ // This rule only applies to local files... So if the namespace can not be
+ // mapped to a module, profile or theme engine we assume that the we are
+ // trying to target an external file.
+ list($namespace) = explode('/', $item);
+
+ // Check if the namespace refers to a file residing in the 'misc' folder or
+ // if it is a global wildcard.
+ if ($namespace !== '*' && $namespace !== 'misc') {
+ // Otherwise, check if it refers to a theme, module, profile or theme
+ // engine.
+ foreach (array('theme', 'module', 'profile', 'theme_engine') as $type) {
+ // We can't use drupal_get_path() directly because that uses dirname()
+ // internally which returns '.' if no filename was found.
+ if ($filename = drupal_get_filename($type, $namespace)) {
+ $prefix = dirname($filename);
+ $item = substr_replace($item, $prefix, 0, strlen($namespace));
+ break;
+ }
+ }
+ }
+
+ // Escape any regex characters and turn asterisk wildcards into actual regex
+ // wildcards.
+ $item = preg_quote($item, '/');
+ $item = str_replace('\*', '(.*)', $item);
+ }
+
+ return '/^' . implode('|', $paths) . '$/';
+}
+
+/**
+ * Helper function for eliminating elements from an array using a simplified
+ * regex pattern.
+ *
+ * @param $elements
+ * The array of elements that should have some of its items removed.
+ * @param $regex
+ * A regex as generated by omega_generate_path_regex().
+ */
+function omega_exclude_assets(&$elements, $regex) {
+ $mapping = omega_generate_asset_mapping($elements);
+
+ // Finally, implode the array of items to exclude into a proper regex and
+ // invoke in on the array of files to be excluded.
+ $elements = array_diff_key($elements, preg_grep($regex, $mapping));
+}
+
+/**
+ * Helper function for generating a map of assets based on the data attribute.
+ *
+ * We can not rely on the array keys of the JS and CSS file arrays in Drupal
+ * because in case of inline JS or CSS (which uses numerical array keys) and due
+ * to potential overrides of the 'data' attribute which holds the actual,
+ * reliable path of the file. This function returns a single-level array of
+ * reliable JS/CSS file paths using the original array keys as keys. Elements of
+ * type 'inline' or 'setting' are ignored.
+ *
+ * @param $elements
+ * An array of JS or CSS files as given in hook_css_alter() or
+ * hook_js_alter().
+ *
+ * @return array
+ * A map of file paths generated from $elements.
+ *
+ * @see hook_js_alter()
+ * @see hook_css_alter()
+ */
+function omega_generate_asset_mapping($elements) {
+ $mapping = array();
+ foreach ($elements as $key => $item) {
+ if ($item['type'] == 'inline' || $item['type'] == 'setting') {
+ // Naturally, in-line CSS is not supported.
+ continue;
+ }
+
+ // We need to build an array containing just the 'data' attribute because
+ // that's the actual path of the file. The array key of the elements can
+ // be something else if someone is sneaky enough to use drupal_add_js() or
+ // drupal_add_css() with a bogus first argument (normally, that is the
+ // path to the file) and then specify the actual path through the 'data'
+ // attribute in the $options array.
+ $mapping[$key] = $item['data'];
+ }
+
+ return $mapping;
+}
+
+/**
+ * Retrieves the array of enabled extensions for a theme. Extensions can be
+ * registered through the .info file. Each extension can define a theme settings
+ * form altering function named
+ * 'THEMENAME_extension_EXTENSION_theme_settings_form_alter()' through a file
+ * named 'THEME_ROOT/includes/EXTENSION/EXTENSION.settings.inc' to have it
+ * automatically included whenever the theme settings form is displayed. Each
+ * extension can also define a
+ * 'THEMENAME_extension_EXTENSION_theme_registry_alter()' function through a
+ * file named 'THEME_ROOT/includes/EXTENSION/EXTENSION.inc' to register custom
+ * hooks with the theme registry.
+ *
+ * @param $theme
+ * (Optional) The key (machine-readable name) of a theme. Defaults to the key
+ * of the current theme.
+ *
+ * @return array
+ * The theme info array of the passed or current theme.
+ *
+ * @see _system_default_theme_features()
+ * @see omega_extension_development_theme_settings_form_alter()
+ * @see omega_extension_development_theme_registry_alter()
+ */
+function omega_extensions($theme = NULL, $reset = FALSE) {
+ $theme = isset($theme) ? $theme : $GLOBALS['theme_key'];
+
+ if (!$reset) {
+ if (($extensions = &drupal_static(__FUNCTION__)) && isset($extensions[$theme])) {
+ return $extensions[$theme];
+ }
+
+ if (($cache = cache_get('omega:' . $theme . ':extensions')) !== FALSE) {
+ return $extensions[$theme] = $cache->data;
+ }
+ }
+
+ // Extensions can't be hidden.
+ $extensions[$theme] = omega_discovery('extension', $theme);
+
+ foreach ($extensions[$theme] as $extension => &$info) {
+ // Make sure that the theme variable is never altered.
+ $context = $theme;
+ drupal_alter('omega_extension_info', $info, $context);
+
+ // Determine if the extension is enabled.
+ $info['enabled'] = omega_theme_get_setting('omega_toggle_extension_' . $extension, !empty($info['info']['enabled']));
+
+ // Check if all dependencies are met.
+ $info['errors'] = FALSE;
+ if (!empty($info['info']['dependencies'])) {
+ foreach ($info['info']['dependencies'] as $dependency) {
+ $dependency = drupal_parse_dependency($dependency);
+
+ if ((!$module = system_get_info('module', $dependency['name'])) || omega_check_incompatibility($dependency, $module['version'])) {
+ $info['errors'] = TRUE;
+ }
+ }
+ }
+ }
+
+ // Write to the cache.
+ cache_set('omega:' . $theme . ':extensions', $extensions[$theme]);
+
+ return $extensions[$theme];
+}
+
+/**
+ * Determines if an extension is enabled.
+ *
+ * @param $extension
+ * The machine-readable name of an extension.
+ * @param $theme
+ * (Optional) The key (machine-readable name) of a theme. Defaults to the key
+ * of the current theme.
+ *
+ * @return bool
+ * TRUE if the extension is enabled, FALSE otherwise.
+ */
+function omega_extension_enabled($extension, $theme = NULL) {
+ $theme = isset($theme) ? $theme : $GLOBALS['theme_key'];
+ if (($extensions = omega_extensions($theme)) && isset($extensions[$extension])) {
+ return empty($extensions[$extension]['errors']) && !empty($extensions[$extension]['enabled']) && variable_get('omega_toggle_extension_' . $extension, TRUE);
+ }
+}
+
+/**
+ * Looks up the info array of all themes in the theme trail and retrieves a
+ * particular info array element.
+ */
+function omega_theme_trail_info($element, $merge = TRUE, $theme = NULL) {
+ $output = array();
+
+ // Loop over all themes in the theme trail and look up $element in the .info
+ // array.
+ foreach (omega_theme_trail($theme) as $key => $name) {
+ $info = omega_theme_info($key);
+
+ // If $merge is TRUE we combine all the results of all themes in the theme
+ // trail. Otherwise we just return the first occurrence.
+ if (isset($info[$element]) && is_array($info[$element])) {
+ $output = array_merge($info[$element], $output);
+
+ if (!$merge) {
+ return array('theme' => $key, 'info' => $output);
+ }
+ }
+ }
+
+ return $output;
+}
+
+/**
+ * Retrieves the full info array of a theme.
+ *
+ * @param $theme
+ * (Optional) The key (machine-readable name) of a theme. Defaults to the key
+ * of the current theme.
+ *
+ * @return array
+ * The theme info array of the passed or current theme.
+ */
+function omega_theme_info($theme = NULL) {
+ $theme = isset($theme) ? $theme : $GLOBALS['theme_key'];
+
+ // If this is the current theme, just load the theme info from the globals.
+ // Note: The global 'theme_key' property is not reliable in this case because
+ // it gets overridden on theme settings pages.
+ if ($theme == $GLOBALS['theme']) {
+ return $GLOBALS['theme_info']->info;
+ }
+
+ $themes = list_themes();
+ return $themes[$theme]->info;
+}
+
+/**
+ * Invoke a hook in all themes in the theme trail that implement it.
+ *
+ * @param $hook
+ * The name of the hook to invoke.
+ * @param $theme
+ * (Optional) The key (machine-readable name) of a theme. Defaults to the key
+ * of the current theme.
+ * @param ...
+ * Arguments to pass to the hook.
+ *
+ * @return array
+ * An array of return values of the hook implementations. If themes return
+ * arrays from their implementations, those are merged into one array.
+ *
+ * @see module_invoke_all()
+ */
+function omega_invoke_all($hook, $theme = NULL) {
+ $theme = isset($theme) ? $theme : $GLOBALS['theme_key'];
+
+ $args = func_get_args();
+ // Remove $hook from the arguments.
+ unset($args[0], $args[1]);
+
+ $return = array();
+ foreach (omega_theme_trail($theme) as $key => $name) {
+ $function = $key . '_' . $hook;
+
+ if (function_exists($function)) {
+ $result = call_user_func_array($function, array_merge(array($theme), array_values($args)));
+ if (isset($result) && is_array($result)) {
+ // Append the 'theme' property to each array element.
+ foreach ($result as &$item) {
+ $item['theme'] = $key;
+ }
+ $return = array_merge_recursive($return, $result);
+ }
+ elseif (isset($result)) {
+ $return[] = $result;
+ }
+ }
+ }
+ return $return;
+}
+
+/**
+ * Custom implementation of drupal_array_get_nested_value() that also supports
+ * objects instead of just arrays.
+ *
+ * @param $object
+ * The array or object from which to get the value.
+ * @param $parents
+ * An array of parent keys of the value, starting with the outermost key.
+ * @param $key_exists
+ * (optional) If given, an already defined variable that is altered by
+ * reference.
+ *
+ * @return mixed
+ * The requested nested value. Possibly NULL if the value is NULL or not all
+ * nested parent keys exist. $key_exists is altered by reference and is a
+ * Boolean that indicates whether all nested parent keys exist (TRUE) or not
+ * (FALSE). This allows to distinguish between the two possibilities when NULL
+ * is returned.
+ *
+ * @see drupal_array_get_nested_value()
+ */
+function omega_get_nested_value(&$object, array $parents, &$key_exists = NULL) {
+ $ref = &$object;
+ foreach ($parents as $parent) {
+ if (is_array($ref) && array_key_exists($parent, $ref)) {
+ $ref = &$ref[$parent];
+ }
+ elseif (is_object($ref) && property_exists($ref, $parent)) {
+ $ref = &$ref->$parent;
+ }
+ else {
+ $key_exists = FALSE;
+ return NULL;
+ }
+ }
+ $key_exists = TRUE;
+ return $ref;
+}
+
+/**
+ * Retrieves the info array for all available layouts.
+ *
+ * @return array
+ * An array of available layouts for the given theme.
+ */
+function omega_layouts_info() {
+ if (($layouts = &drupal_static(__FUNCTION__)) !== NULL) {
+ return $layouts;
+ }
+
+ // Try to retrieve the layouts definitions from cache.
+ if (($cache = cache_get('omega:layouts')) !== FALSE) {
+ return $layouts = $cache->data;
+ }
+
+ // Layouts do not have a specific theme scope.
+ $layouts = omega_discovery('layout', FALSE);
+ foreach ($layouts as $layout => &$info) {
+ $info['attached'] = array();
+ $info['template'] = isset($info['info']['template']) ? $info['info']['template'] : $layout;
+ $root = drupal_get_path('theme', $info['theme']);
+
+ if (isset($info['info']['stylesheets'])) {
+ foreach ($info['info']['stylesheets'] as $media => $files) {
+ foreach ($files as $key => $file) {
+ if (is_file($info['path'] . '/' . $file)) {
+ // First, check if the file exists in the layout's path.
+ $path = $info['path'] . '/' . $file;
+ }
+ elseif (is_file($root . '/' . $file)) {
+ // Otherwise, check if the file exists in the theme's path.
+ $path = $root . '/' . $file;
+ }
+ else {
+ // The specified file does not exist.
+ continue;
+ }
+
+ $info['attached']['css']["$media:$key"] = array(
+ 'data' => $path,
+ 'media' => $media,
+ 'group' => CSS_THEME,
+ 'every_page' => TRUE,
+ 'weight' => -10,
+ );
+ }
+ }
+ }
+
+ // Look up possible CSS and JS file overrides.
+ if (isset($info['info']['scripts'])) {
+ foreach ($info['info']['scripts'] as $key => $file) {
+ if (is_file($info['path'] . '/' . $file)) {
+ // First, check if the file exists in the layout's path.
+ $path = $info['path'] . '/' . $file;
+ }
+ elseif (is_file($root . '/' . $file)) {
+ // Otherwise, check if the file exists in the theme's path.
+ $path = $root . '/' . $file;
+ }
+ else {
+ // The specified file does not exist.
+ continue;
+ }
+
+ $info['attached']['js'][$key] = array(
+ 'data' => $path,
+ 'group' => JS_THEME,
+ 'every_page' => TRUE,
+ 'weight' => -10,
+ );
+ }
+ }
+ }
+
+ // Give modules and themes a chance to alter the layout info array.
+ drupal_alter('omega_layouts_info', $layouts);
+
+ // Cache the layout definitions in the database.
+ cache_set('omega:layouts', $layouts);
+
+ return $layouts;
+}
+
+/**
+ * Retrieves the active layout for the current page.
+ *
+ * @return array|bool
+ * The info array for the active layout or FALSE if the current page does not
+ * use an alternative page layout.
+ */
+function omega_layout() {
+ if (($cache = &drupal_static(__FUNCTION__)) !== NULL) {
+ return $cache;
+ }
+
+ // Load the default layout from the theme settings.
+ $layout = omega_theme_get_setting('omega_layout', 'simple');
+ drupal_alter('omega_layout', $layout);
+
+ $layouts = omega_layouts_info();
+ $cache = isset($layouts[$layout]) ? $layouts[$layout] : FALSE;
+
+ return $cache;
+}
+
+/**
+ * Allow themes to easily define libraries.
+ *
+ * @param $theme
+ * (Optional) The key (machine-readable name) of a theme. Defaults to the key
+ * of the current theme.
+ *
+ * @return array
+ * An array of libraries defined by themes in the theme trail of the given
+ * theme.
+ */
+function omega_theme_libraries_info($theme = NULL) {
+ $theme = isset($theme) ? $theme : $GLOBALS['theme_key'];
+
+ // Check if the libraries have already been statically cached.
+ if (($libraries = &drupal_static(__FUNCTION__)) && isset($libraries[$theme])) {
+ return $libraries[$theme];
+ };
+
+ // Try to retrieve the library definitions from cache.
+ if (($cache = cache_get("omega:$theme:libraries")) !== FALSE) {
+ return $libraries[$theme] = $cache->data;
+ }
+
+ // Retrieve the libraries by invoking the hook.
+ $libraries[$theme] = omega_invoke_all('omega_theme_libraries_info');
+
+ $context = $theme;
+ // Give modules and themes a chance to alter the libraries info array.
+ drupal_alter('omega_theme_libraries_info', $libraries[$theme], $context);
+
+ // Cache the layout definitions in the database.
+ cache_set("omega:$theme:libraries", $libraries[$theme]);
+
+ return $libraries[$theme];
+}
+
+/**
+ * Helper function for discovering layouts, extensions or other plugins of any
+ * sort in the theme trail.
+ *
+ * @param $type
+ * A theme extension type (e.g. layout or extension).
+ * @param $theme
+ * (Optional) The key (machine-readable name) of a theme. Defaults to the key
+ * of the current theme.
+ *
+ * @return array
+ * An array containing the discovered definitions.
+ */
+function omega_discovery($type, $theme = NULL) {
+ $theme = isset($theme) ? $theme : $GLOBALS['theme_key'];
+
+ if (($discovery = &drupal_static(__FUNCTION__, array())) && isset($discovery[$theme][$type])) {
+ return $discovery[$theme][$type];
+ }
+
+ $discovery[$theme][$type] = array();
+
+ // Retrieve all themes from the theme trail of the given theme.
+ $themes = $theme === FALSE ? list_themes() : omega_theme_trail($theme);
+
+ // Collect paths to all sub-themes grouped by base themes. These will be
+ // used for filtering. This allows base themes to have sub-themes in its
+ // folder hierarchy without affecting the base themes template discovery.
+ $paths = array();
+ foreach ($themes as $key => $info) {
+ if (!empty($info->base_theme)) {
+ $paths[$info->base_theme][$key] = dirname($info->filename);
+ }
+ }
+ foreach ($paths as $basetheme => $subthemes) {
+ foreach ($subthemes as $subtheme => $path) {
+ if (isset($paths[$subtheme])) {
+ $paths[$basetheme] = array_merge($paths[$basetheme], $paths[$subtheme]);
+ }
+ }
+ }
+
+ $strlen = strlen($type) + 1;
+ foreach ($themes as $key => $label) {
+ // Retrieve the array of paths that should be ignored for this theme.
+ $ignore = isset($paths[$key]) ? $paths[$key] : array();
+ $path = drupal_get_path('theme', $key);
+
+ // Support files without '.inc' extension for backwards compatibility.
+ foreach (file_scan_directory($path, '/\.' . $type . '(\.inc)?$/', array('key' => 'name')) as $name => $file) {
+ // Ignore sub-theme templates for the current theme.
+ if (strpos($file->uri, str_replace($ignore, '', $file->uri)) !== 0) {
+ continue;
+ }
+
+ if (substr($name, -$strlen) === '.' . $type) {
+ $name = substr($name, 0, strlen($name) - $strlen);
+ }
+
+ if ($info = drupal_parse_info_file($file->uri)) {
+ $discovery[$theme][$type][$name] = array(
+ 'name' => $name,
+ 'path' => dirname($file->uri),
+ 'file' => $file->uri,
+ 'info' => $info,
+ 'theme' => $key,
+ );
+ }
+ }
+ }
+
+ return $discovery[$theme][$type];
+}
+
+/**
+ * Checks whether a version is compatible with a given dependency.
+ *
+ * This is a wrapper for drupal_check_incompatibility() which strips the core
+ * version and any potential development version suffix from the given string.
+ *
+ * @param $dependency
+ * The parsed dependency structure from drupal_parse_dependency().
+ * @param $current
+ * The version to check against (like 4.2).
+ *
+ * @return
+ * NULL if compatible, otherwise the original dependency version string that
+ * caused the incompatibility.
+ *
+ * @see drupal_check_incompatibility()
+ * @see drupal_parse_dependency()
+ */
+function omega_check_incompatibility($dependency, $current) {
+ // Remove the core version from the version string.
+ $current = preg_replace('/^' . DRUPAL_CORE_COMPATIBILITY . '-/', '', $current);
+ // Remove any potential development version suffixes from the string.
+ $current = preg_replace('/-dev$/', '', $current);
+
+ return drupal_check_incompatibility($dependency, $current);
+}
+
+/**
+ * Finds the first occurrence of a given file in the theme trail.
+ *
+ * @param $file
+ * The relative path to a file.
+ * @param $theme
+ * (Optional) The key (machine-readable name) of a theme. Defaults to the key
+ * of the current theme.
+ *
+ * @return string
+ * The path to the file. If the file does not exist at all, it will simply
+ * return the path of the file as it would be if it existed in the given theme
+ * directly. This ensures that the code that uses this function does not break
+ * if a file does not exist anywhere.
+ */
+function omega_theme_trail_file($file, $theme = NULL) {
+ $theme = isset($theme) ? $theme : $GLOBALS['theme_key'];
+
+ // Iterate over all themes in the theme trail (starting with the active theme)
+ // and return the first match.
+ $current = NULL;
+ foreach (array_reverse(omega_theme_trail($theme)) as $name => $info) {
+ $current = drupal_get_path('theme', $name) . '/' . $file;
+ if (file_exists($current)) {
+ return $current;
+ }
+ }
+
+ // The default (fallback) path is the path of the active theme, even if it
+ // does not actually have that file.
+ return drupal_get_path('theme', $theme) . '/' . $file;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/includes/registry.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/includes/registry.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,195 @@
+theme = $theme;
+ $this->trail = omega_theme_trail($theme);
+ $this->registry = &$registry;
+ }
+
+ /**
+ * Discovers and registers (pre-)process hooks on behalf of a given theme.
+ *
+ * @param string $theme
+ * The name of the theme for which to register (pre-)process hooks.
+ */
+ public function registerHooks($theme) {
+ foreach (array('process', 'preprocess') as $type) {
+ // Iterate over all preprocess/process files in the current theme.
+ foreach ($this->discoverFiles($theme, $type) as $item) {
+ $callback = "{$theme}_{$type}_{$item->hook}";
+
+ // If there is no hook with that name, continue.
+ if (!array_key_exists($item->hook, $this->registry)) {
+ continue;
+ }
+
+ // Append the included (pre-)process hook to the array of functions.
+ $this->registry[$item->hook]["$type functions"][] = $callback;
+
+ // By adding this file to the 'includes' array we make sure that it is
+ // available when the hook is executed.
+ $this->registry[$item->hook]['includes'][] = $item->uri;
+ }
+ }
+ }
+
+ /**
+ * Discovers and registers theme functions on behalf of a given theme.
+ *
+ * @param string $theme
+ * The name of the theme for which to register (pre-)process hooks.
+ * @param array $trail
+ * The theme trail of the given theme.
+ */
+ public function registerThemeFunctions($theme, $trail) {
+ // Recursively scan the folder for the current step for (pre-)process
+ // files and write them to the registry.
+ foreach ($this->discoverFiles($theme, 'theme') as $item) {
+ // Keep a copy of the hook name to accomodate for theme hook suggestions.
+ $base = $item->hook;
+ if (($separator = strpos($item->hook, '__')) !== FALSE) {
+ $base = substr($item->hook, 0, $separator);
+ }
+
+ // If there is no hook with that name, continue. This does not apply to
+ // theme hook suggestions.
+ if (!array_key_exists($base, $this->registry)) {
+ continue;
+ }
+
+ // Skip theme function overrides if they are already declared 'final'.
+ if (!empty($this->registry[$item->hook]['final'])) {
+ continue;
+ }
+
+ // Name of the function (theme hook or theme function).
+ $callback = "{$theme}_{$item->hook}";
+
+ // Furthermore, we don't want to re-override sub-theme template file or
+ // theme function overrides with theme functions from include files
+ // defined in a lower-level base theme. Without this check this would
+ // happen because our alter hook runs after the template file and theme
+ // function discovery logic from Drupal core (theme engine).
+ if (in_array($this->registry[$item->hook]['type'], array('base_theme_engine', 'theme_engine'))) {
+ foreach (array_reverse(array_keys($this->trail)) as $key) {
+ // Do not look any further once we reach the current theme.
+ if ($key === $theme) {
+ break;
+ }
+
+ // We need to check if the declaration of that function or template
+ // file lives further down the theme trail than the function we are
+ // currently looking at.
+ if ($this->registry[$item->hook]['theme path'] == drupal_get_path('theme', $key)) {
+ continue(2);
+ }
+ }
+ }
+
+ // Check if this is a previously unknown theme hook suggestion.
+ if (!array_key_exists($item->hook, $this->registry) && $base !== $item->hook) {
+ $arg = isset($this->registry[$base]['variables']) ? 'variables' : 'render element';
+
+ $this->registry[$item->hook] = array(
+ $arg => $this->registry[$base][$arg],
+ 'base hook' => $base,
+ 'preprocess functions' => array(),
+ 'process functions' => array(),
+ );
+ }
+
+ $this->registry[$item->hook]['function'] = $callback;
+ $this->registry[$item->hook]['theme path'] = drupal_get_path('theme', $theme);
+ $this->registry[$item->hook]['type'] = $theme == $this->theme ? 'theme_engine' : 'base_theme_engine';
+
+ // By adding this file to the 'includes' array we make sure that it is
+ // available when the hook is executed.
+ $this->registry[$item->hook]['includes'][] = $item->uri;
+ }
+ }
+
+ /**
+ * Overrides (pre-)process functions while maintaining execution order.
+ *
+ * Useful in cases where we want to take a completely different approach than
+ * what the original implementation does. In some cases this is much more
+ * practical than altering or undoing things that were added or changed in a
+ * previous hook.
+ *
+ * @param string $hook
+ * The name of the theme hook (e.g. 'html', 'page' or 'block').
+ * @param string $original
+ * The name of the original function.
+ * @param string $override
+ * The name of the new function.
+ * @param string $type
+ * (Optional) The type of the hook ('process' or 'preprocess'). Defaults to
+ * 'process'.
+ */
+ public function overrideHook($hook, $original, $override, $type = 'process') {
+ if (($index = array_search($original, $this->registry[$hook]["$type functions"], TRUE)) !== FALSE) {
+ array_splice($this->registry[$hook]["$type functions"], $index, 1, $override);
+ }
+ }
+
+ /**
+ * Scans for files of a certain type in the given theme's path.
+ *
+ * @param string $theme
+ * The name of the theme scan.
+ * @param string $type
+ * The file type (e.g. 'preprocess', 'process', or 'theme') to scan for.
+ *
+ * @return array
+ * An array of file objects that matched the given type.
+ */
+ protected function discoverFiles($theme, $type) {
+ $length = -(strlen($type) + 1);
+
+ $path = drupal_get_path('theme', $theme);
+ // Only look for files that match the 'something.preprocess.inc' pattern.
+ $mask = '/.' . $type . '.inc$/';
+
+ // Recursively scan the folder for the current step for (pre-)process
+ // files and write them to the registry.
+ $files = file_scan_directory($path . '/' . $type, $mask);
+ foreach ($files as &$file) {
+ $file->hook = strtr(substr($file->name, 0, $length), '-', '_');
+ };
+
+ return $files;
+ }
+
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/includes/scripts.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/includes/scripts.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,411 @@
+ $item) {
+ if ($item['scope'] == $scope) {
+ $items[$key] = $item;
+ }
+ }
+
+ // Sort the JavaScript so that it appears in the correct order.
+ uasort($items, 'drupal_sort_css_js');
+
+ // In Drupal 8, there's a JS_SETTING group for making setting variables
+ // appear last after libraries have loaded. In Drupal 7, this is forced
+ // without that group. We do not use the $key => $item type of iteration,
+ // because PHP uses an internal array pointer for that, and we're modifying
+ // the array order inside the loop.
+ foreach (array_keys($items) as $key) {
+ if ($items[$key]['type'] == 'setting') {
+ $item = $items[$key];
+ unset($items[$key]);
+ $items[$key] = $item;
+ }
+ }
+
+ // There is no need for the ajax page state if there is no ajax js!
+ if (array_key_exists('misc/ajax.js', $items)) {
+ // Provide the page with information about the individual JavaScript files
+ // used, information not otherwise available when aggregation is enabled.
+ $setting['ajaxPageState']['js'] = array_fill_keys(array_keys($items), 1);
+ unset($setting['ajaxPageState']['js']['settings']);
+ drupal_add_js($setting, 'setting');
+
+ // If we're outputting the header scope, then this might be the final time
+ // that drupal_get_js() is running, so add the setting to this output as well
+ // as to the drupal_add_js() cache. If $items['settings'] doesn't exist, it's
+ // because drupal_get_js() was intentionally passed a $javascript argument
+ // stripped of settings, potentially in order to override how settings get
+ // output, so in this case, do not add the setting to this output.
+ if ($scope == 'header' && isset($items['settings'])) {
+ $items['settings']['data'][] = $setting;
+ }
+ }
+
+ // Render the HTML needed to load the JavaScript.
+ $elements = array(
+ '#type' => 'scripts',
+ '#items' => $items,
+ );
+
+ return drupal_render($elements);
+}
+
+/**
+ * Callback to add the elements needed for JavaScript tags to be rendered.
+ *
+ * This function evaluates the aggregation enabled/disabled condition on a group
+ * by group basis by testing whether an aggregate file has been made for the
+ * group rather than by testing the site-wide aggregation setting. This allows
+ * this function to work correctly even if modules have implemented custom
+ * logic for grouping and aggregating files.
+ *
+ * @param $elements
+ * A render array containing:
+ * - #items: The JavaScript items as returned by drupal_add_js() and
+ * altered by drupal_get_js().
+ * - #group_callback: A function to call to group #items. Following
+ * this function, #aggregate_callback is called to aggregate items within
+ * the same group into a single file.
+ * - #aggregate_callback: A function to call to aggregate the items within
+ * the groups arranged by the #group_callback function.
+ *
+ * @return array
+ * A render array that will render to a string of JavaScript tags.
+ *
+ * @see drupal_get_js()
+ */
+function omega_pre_render_scripts($elements) {
+ // Group and aggregate the items.
+ if (isset($elements['#group_callback'])) {
+ $elements['#groups'] = $elements['#group_callback']($elements['#items']);
+ }
+ if (isset($elements['#aggregate_callback'])) {
+ $elements['#aggregate_callback']($elements['#groups']);
+ }
+
+ // A dummy query-string is added to filenames, to gain control over
+ // browser-caching. The string changes on every update or full cache
+ // flush, forcing browsers to load a new copy of the files, as the
+ // URL changed. Files that should not be cached (see drupal_add_js())
+ // get REQUEST_TIME as query-string instead, to enforce reload on every
+ // page request.
+ $default_query_string = variable_get('css_js_query_string', '0');
+
+ // For inline JavaScript to validate as XHTML, all JavaScript containing
+ // XHTML needs to be wrapped in CDATA. To make that backwards compatible
+ // with HTML 4, we need to comment out the CDATA-tag.
+ $embed_prefix = "\n\n";
+
+ // Since JavaScript may look for arguments in the URL and act on them, some
+ // third-party code might require the use of a different query string.
+ $js_version_string = variable_get('drupal_js_version_query_string', 'v=');
+
+ // Defaults for each SCRIPT element.
+ $element_defaults = array(
+ '#type' => 'html_tag',
+ '#tag' => 'script',
+ '#value' => '',
+ '#attributes' => array(
+ 'type' => 'text/javascript',
+ ),
+ );
+
+ // Loop through each group.
+ foreach ($elements['#groups'] as $group) {
+ // If a group of files has been aggregated into a single file,
+ // $group['data'] contains the URI of the aggregate file. Add a single
+ // script element for this file.
+ if ($group['type'] == 'file' && isset($group['data'])) {
+ $element = $element_defaults;
+ $element['#attributes']['src'] = file_create_url($group['data']);
+ $element['#browsers'] = $group['browsers'];
+ $elements[] = $element;
+ }
+ // For non-file types, and non-aggregated files, add a script element per
+ // item.
+ else {
+ foreach ($group['items'] as $item) {
+ // Element properties that do not depend on item type.
+ $element = $element_defaults;
+ if (!empty($item['defer'])) {
+ $element['#attributes']['defer'] = 'defer';
+ }
+ $element['#browsers'] = $item['browsers'];
+
+ // Element properties that depend on item type.
+ switch ($item['type']) {
+ case 'setting':
+ $element['#value_prefix'] = $embed_prefix;
+ $element['#value'] = 'jQuery.extend(Drupal.settings, ' . drupal_json_encode(drupal_array_merge_deep_array($item['data'])) . ");";
+ $element['#value_suffix'] = $embed_suffix;
+ break;
+
+ case 'inline':
+ $element['#value_prefix'] = $embed_prefix;
+ $element['#value'] = $item['data'];
+ $element['#value_suffix'] = $embed_suffix;
+ break;
+
+ case 'file':
+ $query_string = empty($item['version']) ? $default_query_string : $js_version_string . $item['version'];
+ $query_string_separator = (strpos($item['data'], '?') !== FALSE) ? '&' : '?';
+ $element['#attributes']['src'] = file_create_url($item['data']) . $query_string_separator . ($item['cache'] ? $query_string : REQUEST_TIME);
+ break;
+
+ case 'external':
+ $element['#attributes']['src'] = $item['data'];
+ break;
+ }
+
+ $elements[] = $element;
+ }
+ }
+ }
+
+ return $elements;
+}
+
+/**
+ * Default callback to aggregate JavaScript files.
+ *
+ * Having the browser load fewer JavaScript files results in much faster page
+ * loads than when it loads many small files. This function aggregates files
+ * within the same group into a single file unless the site-wide setting to do
+ * so is disabled (commonly the case during site development). To optimize
+ * download, it also compresses the aggregate files by removing comments,
+ * whitespace, and other unnecessary content.
+ *
+ * @param $js_groups
+ * An array of JavaScript groups as returned by drupal_group_js(). For each
+ * group that is aggregated, this function sets the value of the group's
+ * 'data' key to the URI of the aggregate file.
+ *
+ * @see drupal_group_js()
+ * @see drupal_pre_render_scripts()
+ */
+function omega_aggregate_js(&$js_groups) {
+ // Only aggregate when the site is configured to do so, and not during an
+ // update.
+ if (variable_get('preprocess_js', FALSE) && (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update')) {
+ foreach ($js_groups as $key => $group) {
+ if ($group['type'] == 'file' && $group['preprocess']) {
+ $js_groups[$key]['data'] = omega_build_js_cache($group['items']);
+ }
+ }
+ }
+}
+
+/**
+ * Aggregates JavaScript files into a cache file in the files directory.
+ *
+ * The file name for the JavaScript cache file is generated from the hash of
+ * the aggregated contents of the files in $files. This forces proxies and
+ * browsers to download new JavaScript when the JavaScript changes.
+ *
+ * The cache file name is retrieved on a page load via a lookup variable that
+ * contains an associative array. The array key is the hash of the names in
+ * $files while the value is the cache file name. The cache file is generated
+ * in two cases. First, if there is no file name value for the key, which will
+ * happen if a new file name has been added to $files or after the lookup
+ * variable is emptied to force a rebuild of the cache. Second, the cache file
+ * is generated if it is missing on disk. Old cache files are not deleted
+ * immediately when the lookup variable is emptied, but are deleted after a set
+ * period by drupal_delete_file_if_stale(). This ensures that files referenced
+ * by a cached page will still be available.
+ *
+ * @param $files
+ * An array of JavaScript files to aggregate and compress into one file.
+ *
+ * @return string|bool
+ * The URI of the cache file, or FALSE if the file could not be saved.
+ */
+function omega_build_js_cache($files) {
+ $contents = '';
+ $uri = '';
+ $map = variable_get('drupal_js_cache_files', array());
+ // Create a new array so that only the file names are used to create the hash.
+ // This prevents new aggregates from being created unnecessarily.
+ $js_data = array();
+ foreach ($files as $file) {
+ $js_data[] = $file['data'];
+ }
+ $key = hash('sha256', serialize($js_data));
+ if (isset($map[$key])) {
+ $uri = $map[$key];
+ }
+
+ if (empty($uri) || !file_exists($uri)) {
+ // Build aggregate JS file.
+ foreach ($files as $path => $info) {
+ if ($info['preprocess']) {
+ // Append a ';' and a newline after each JS file to prevent them from running together.
+ $contents .= file_get_contents($info['data']) . ";\n";
+ }
+ }
+ // Prefix filename to prevent blocking by firewalls which reject files
+ // starting with "ad*".
+ $filename = 'js_' . drupal_hash_base64($contents) . '.js';
+ // Create the js/ within the files folder.
+ $jspath = 'public://js';
+ $uri = $jspath . '/' . $filename;
+ // Create the JS file.
+ file_prepare_directory($jspath, FILE_CREATE_DIRECTORY);
+ if (!file_exists($uri) && !file_unmanaged_save_data($contents, $uri, FILE_EXISTS_REPLACE)) {
+ return FALSE;
+ }
+ // If JS gzip compression is enabled, clean URLs are enabled (which means
+ // that rewrite rules are working) and the zlib extension is available then
+ // create a gzipped version of this file. This file is served conditionally
+ // to browsers that accept gzip using .htaccess rules.
+ if (variable_get('js_gzip_compression', TRUE) && variable_get('clean_url', 0) && extension_loaded('zlib')) {
+ if (!file_exists($uri . '.gz') && !file_unmanaged_save_data(gzencode($contents, 9, FORCE_GZIP), $uri . '.gz', FILE_EXISTS_REPLACE)) {
+ return FALSE;
+ }
+ }
+ $map[$key] = $uri;
+ variable_set('drupal_js_cache_files', $map);
+ }
+ return $uri;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/js/jquery.matchmedia.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/js/jquery.matchmedia.js Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,54 @@
+(function ($, window) {
+
+ 'use strict';
+
+ /**
+ * Check if the given media query currently applies.
+ *
+ * @param query
+ * The media query to check for.
+ *
+ * @deprecated
+ * Use window.matchMedia() instead.
+ */
+ $.matchmedia = function (query) {
+ return window.matchMedia(query);
+ };
+
+ /**
+ * Special event for listening to media query changes.
+ *
+ * @deprecated
+ * Use window.matchMedia(query).addListener(callback) instead.
+ */
+ var event = $.event.special.mediaquery = {
+ objects: {},
+
+ handler: function (handler) {
+ return function (mql) {
+ mql.applies = mql.matches;
+ handler.call(mql, mql);
+ };
+ },
+
+ add: function (handleObj) {
+ event.objects[handleObj.guid] = window.matchMedia(handleObj.data);
+ event.objects[handleObj.guid].addListener(event.handler(handleObj.handler));
+ },
+
+ remove: function (handleObj) {
+ event.objects[handleObj.guid].removeListener(event.handler(handleObj.handler));
+ }
+ };
+
+ /**
+ * Event shortcut.
+ *
+ * @deprecated
+ * Use window.matchMedia(query).addListener(callback) instead.
+ */
+ $.fn.mediaquery = function (query, callback) {
+ return $(this).bind('mediaquery', query, callback);
+ };
+
+})(jQuery, window);
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/js/jquery.matchmedia.min.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/js/jquery.matchmedia.min.js Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,1 @@
+!function($,window){"use strict";$.matchmedia=function(query){return window.matchMedia(query)};var event=$.event.special.mediaquery={objects:{},handler:function(handler){return function(mql){mql.applies=mql.matches;handler.call(mql,mql)}},add:function(handleObj){event.objects[handleObj.guid]=window.matchMedia(handleObj.data);event.objects[handleObj.guid].addListener(event.handler(handleObj.handler))},remove:function(handleObj){event.objects[handleObj.guid].removeListener(event.handler(handleObj.handler))}};$.fn.mediaquery=function(query,callback){return $(this).bind("mediaquery",query,callback)}}(jQuery,window);
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/js/jquery.resizeend.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/js/jquery.resizeend.js Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,43 @@
+(function ($) {
+
+ 'use strict';
+
+ /**
+ * Container for the resizeend timeout.
+ */
+ var resizeTimeout;
+
+ /**
+ * Throttled resize event. Fires only once after the resize ended.
+ */
+ var event = $.event.special.resizeend = {
+ setup: function () {
+ $(this).bind('resize', event.handler);
+ },
+
+ teardown: function () {
+ $(this).unbind('resize', event.handler);
+ },
+
+ handler: function (e) {
+ var context = this;
+ if (resizeTimeout) {
+ clearTimeout(resizeTimeout);
+ }
+
+ resizeTimeout = setTimeout(function () {
+ // Set correct event type
+ e.type = 'resizeend';
+ $.event.handle.apply(context);
+ }, 150);
+ }
+ };
+
+ /**
+ * Wrapper for the resizeend event.
+ */
+ $.fn.resizeend = function (handler) {
+ return $(this).bind('resizeend', handler);
+ };
+
+})(jQuery);
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/js/jquery.resizeend.min.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/js/jquery.resizeend.min.js Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,1 @@
+!function($){"use strict";var resizeTimeout;var event=$.event.special.resizeend={setup:function(){$(this).bind("resize",event.handler)},teardown:function(){$(this).unbind("resize",event.handler)},handler:function(e){var context=this;if(resizeTimeout){clearTimeout(resizeTimeout)}resizeTimeout=setTimeout(function(){e.type="resizeend";$.event.handle.apply(context)},150)}};$.fn.resizeend=function(handler){return $(this).bind("resizeend",handler)}}(jQuery);
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/js/jquery.scrollable.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/js/jquery.scrollable.js Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,22 @@
+(function ($) {
+
+ 'use strict';
+
+ /**
+ * Custom expression for filtering for scrollable elements.
+ */
+ $.expr[':'].scrollable = function (elem) {
+ var scrollable = true;
+ // Backup the original scroll position.
+ var original = $(elem).scrollTop();
+
+ if (original === 0) {
+ $(elem).scrollTop(1);
+ scrollable = $(elem).scrollTop() === 1;
+ $(elem).scrollTop(0);
+ }
+
+ return scrollable;
+ };
+
+})(jQuery);
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/js/jquery.scrollable.min.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/js/jquery.scrollable.min.js Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,1 @@
+!function($,window){"use strict";$.matchmedia=function(query){return window.matchMedia(query)};var event=$.event.special.mediaquery={objects:{},handler:function(handler){return function(mql){mql.applies=mql.matches;handler.call(mql,mql)}},add:function(handleObj){event.objects[handleObj.guid]=window.matchMedia(handleObj.data);event.objects[handleObj.guid].addListener(event.handler(handleObj.handler))},remove:function(handleObj){event.objects[handleObj.guid].removeListener(event.handler(handleObj.handler))}};$.fn.mediaquery=function(query,callback){return $(this).bind("mediaquery",query,callback)}}(jQuery,window);
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/js/omega.admin.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/js/omega.admin.js Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,41 @@
+(function ($) {
+
+ 'use strict';
+
+ /**
+ * Allows administrators to click on the icon of a layout instead of having to
+ * target the radio button in order to select it.
+ */
+ Drupal.behaviors.omegaThemeSettingsLayouts = {
+ attach: function (context) {
+ $('.form-item-omega-layout .omega-layout-icon', context).click(function () {
+ $(this).siblings('.form-item').find('input').click().change();
+ });
+ }
+ };
+
+ /**
+ * Provide a nice little summary for the vertical tab pane of each extension
+ * which indicates whether or not it is currently enabled.
+ */
+ Drupal.behaviors.omegaExtensionSummary = {
+ attach: function (context) {
+ $('fieldset[id^=edit-].omega-extension', context).each(function () {
+ var extension = $(this).attr('id').substring(5);
+ var $fieldset = $(this);
+ var $checkbox = $fieldset.find('input[name="omega_toggle_extension_' + extension + '"]');
+
+ $fieldset.drupalSetSummary(function () {
+ if (!$checkbox.is(':checked')) {
+ return Drupal.t('This extension is currently disabled');
+ }
+ });
+
+ $checkbox.change(function () {
+ $fieldset.trigger('summaryUpdated');
+ });
+ });
+ }
+ };
+
+})(jQuery);
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/js/omega.admin.min.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/js/omega.admin.min.js Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,1 @@
+!function($){"use strict";Drupal.behaviors.omegaThemeSettingsLayouts={attach:function(context){$(".form-item-omega-layout .omega-layout-icon",context).click(function(){$(this).siblings(".form-item").find("input").click().change()})}};Drupal.behaviors.omegaExtensionSummary={attach:function(context){$("fieldset[id^=edit-].omega-extension",context).each(function(){var extension=$(this).attr("id").substring(5);var $fieldset=$(this);var $checkbox=$fieldset.find('input[name="omega_toggle_extension_'+extension+'"]');$fieldset.drupalSetSummary(function(){if(!$checkbox.is(":checked")){return Drupal.t("This extension is currently disabled")}});$checkbox.change(function(){$fieldset.trigger("summaryUpdated")})})}}}(jQuery);
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/js/omega.indicator.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/js/omega.indicator.js Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,21 @@
+(function ($) {
+
+ 'use strict';
+
+ /**
+ * Renders a widget for displaying the current width of the browser.
+ */
+ Drupal.behaviors.omegaBrowserWidth = {
+ attach: function (context) {
+ $('body', context).once('omega-browser-width', function () {
+ var $indicator = $('').appendTo(this);
+
+ // Bind to the window.resize event to continuously update the width.
+ $(window).bind('resize.omega-browser-width', function () {
+ $indicator.text($(this).width() + 'px');
+ }).trigger('resize.omega-browser-width');
+ });
+ }
+ };
+
+})(jQuery);
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/js/omega.indicator.min.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/js/omega.indicator.min.js Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,1 @@
+!function($){"use strict";Drupal.behaviors.omegaBrowserWidth={attach:function(context){$("body",context).once("omega-browser-width",function(){var $indicator=$('').appendTo(this);$(window).bind("resize.omega-browser-width",function(){$indicator.text($(this).width()+"px")}).trigger("resize.omega-browser-width")})}}}(jQuery);
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/js/omega.mediaqueries.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/js/omega.mediaqueries.js Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,43 @@
+(function ($, window, Drupal) {
+
+ 'use strict';
+
+ /**
+ * Toggles media-query specific body classes.
+ *
+ * You can define new media queries to listen to by writing them into the
+ * Drupal.settings.omegaSettings.mediaQueries array.
+ */
+ Drupal.behaviors.omegaMediaQueryClasses = {
+ handler: function (name, mql) {
+ if (mql.matches) {
+ $('body').removeClass(name + '-inactive').addClass(name + '-active');
+ }
+ else {
+ $('body').removeClass(name + '-active').addClass(name + '-inactive');
+ }
+ },
+
+ attach: function (context, settings) {
+ var behavior = this;
+ var omegaSettings = settings.omega || {};
+ var mediaQueries = omegaSettings.mediaQueries || {};
+
+ $('body', context).once('omega-mediaqueries', function () {
+ $.each(mediaQueries, function (index, value) {
+ var mql = window.matchMedia(value);
+
+ // Initially, check if the media query applies or not and add the
+ // corresponding class to the body.
+ behavior.handler(index, mql);
+
+ // React to media query changes and toggle the class names.
+ mql.addListener(function (mql) {
+ behavior.handler(index, mql);
+ });
+ });
+ });
+ }
+ };
+
+})(jQuery, window, Drupal);
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/js/omega.mediaqueries.min.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/js/omega.mediaqueries.min.js Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,1 @@
+!function($,window,Drupal){"use strict";Drupal.behaviors.omegaMediaQueryClasses={handler:function(name,mql){if(mql.matches){$("body").removeClass(name+"-inactive").addClass(name+"-active")}else{$("body").removeClass(name+"-active").addClass(name+"-inactive")}},attach:function(context,settings){var behavior=this;var omegaSettings=settings.omega||{};var mediaQueries=omegaSettings.mediaQueries||{};$("body",context).once("omega-mediaqueries",function(){$.each(mediaQueries,function(index,value){var mql=window.matchMedia(value);behavior.handler(index,mql);mql.addListener(function(mql){behavior.handler(index,mql)})})})}}}(jQuery,window,Drupal);
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/js/omega.messages.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/js/omega.messages.js Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,22 @@
+(function ($, Drupal) {
+
+ 'use strict';
+
+ /**
+ * Adds a 'close' link on messages that allows them to be discarded.
+ */
+ Drupal.behaviors.omegaCloseableMessages = {
+ attach: function (context) {
+ $('.messages', context).once('closeable-messages', function () {
+ $('').click(function () {
+ $(this).closest('.messages').fadeOut(function () {
+ $(this).remove();
+ });
+
+ return false;
+ }).appendTo(this);
+ });
+ }
+ };
+
+})(jQuery, Drupal);
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/js/omega.messages.min.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/js/omega.messages.min.js Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,1 @@
+!function($,Drupal){"use strict";Drupal.behaviors.omegaCloseableMessages={attach:function(context){$(".messages",context).once("closeable-messages",function(){$('').click(function(){$(this).closest(".messages").fadeOut(function(){$(this).remove()});return false}).appendTo(this)})}}}(jQuery,Drupal);
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/layouts/simple/preview.png
Binary file sites/all/themes/omega/omega/layouts/simple/preview.png has changed
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/layouts/simple/simple-layout.tpl.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/layouts/simple/simple-layout.tpl.php Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/layouts/simple/simple.layout.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/layouts/simple/simple.layout.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,18 @@
+name = Simple
+description = A simple 3 column layout demonstrating mobile first and Susy.
+preview = preview.png
+template = simple-layout
+
+; Regions
+regions[branding] = Branding
+regions[header] = Header
+regions[navigation] = Navigation bar
+regions[highlighted] = Highlighted
+regions[help] = Help
+regions[content] = Content
+regions[sidebar_first] = First sidebar
+regions[sidebar_second] = Second sidebar
+regions[footer] = Footer
+
+; Stylesheets
+stylesheets[all][] = css/layouts/simple/simple.layout.css
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/libraries.make
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/libraries.make Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,34 @@
+; ##############################################################################
+;
+; This is a Drush make file that will automatically download the front-end
+; libraries used by Omega. Alternatively, you can use Bower (http://bower.io) to
+; accomplish this.
+;
+; To run this file with 'drush make' you first have to navigate into the Omega
+; theme directory.
+;
+; $ cd sites/all/themes/omega/omega
+;
+; Now you can invoke 'drush make' using the following command:
+;
+; $ drush make libraries.make --no-core --contrib-destination=.
+;
+; ##############################################################################
+
+core = 7.x
+api = 2
+
+libraries[selectivizr][download][type] = "file"
+libraries[selectivizr][download][url] = "https://github.com/fubhy/selectivizr/archive/master.zip"
+
+libraries[html5shiv][download][type] = "file"
+libraries[html5shiv][download][url] = "https://github.com/fubhy/html5shiv/archive/master.zip"
+
+libraries[respond][download][type] = "file"
+libraries[respond][download][url] = "https://github.com/fubhy/respond/archive/master.zip"
+
+libraries[matchmedia][download][type] = "file"
+libraries[matchmedia][download][url] = "https://github.com/fubhy/matchmedia/archive/master.zip"
+
+libraries[pie][download][type] = "file"
+libraries[pie][download][url] = "https://github.com/fubhy/pie/archive/master.zip"
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/logo.png
Binary file sites/all/themes/omega/omega/logo.png has changed
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/omega.info
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/omega.info Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,28 @@
+name = Omega
+description = A powerful HTML5 base theme framework utilizing tools like Sass, Compass, Grunt, Bower, Ruby Version Manager, Bundler and more.
+screenshot = screenshot.png
+engine = phptemplate
+hidden = TRUE
+core = 7.x
+
+; Regions
+regions[branding] = Branding
+regions[header] = Header
+regions[navigation] = Navigation
+regions[highlighted] = Highlighted
+regions[help] = Help
+regions[content] = Content
+regions[sidebar_first] = First Sidebar
+regions[sidebar_second] = Second Sidebar
+regions[footer] = Footer
+
+; Plugins
+plugins[panels][layouts] = panels/layouts
+plugins[panels][styles] = panels/styles
+
+; Information added by drupal.org packaging script on 2013-09-12
+version = "7.x-4.0-rc1"
+core = "7.x"
+project = "omega"
+datestamp = "1378993635"
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/package.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/package.json Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,15 @@
+{
+ "name": "omega",
+ "version": "1.0.0",
+ "dependencies": {},
+ "devDependencies": {
+ "grunt": "~0.4.0",
+ "grunt-contrib-watch": "~0.4.3",
+ "grunt-contrib-compass": "~0.2.0",
+ "grunt-contrib-jshint": "~0.1.1",
+ "grunt-contrib-uglify": "~0.2.0"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/panels/layouts/omega/omega.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/panels/layouts/omega/omega.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,194 @@
+ t('Omega'),
+ 'category' => t('Omega page layouts'),
+ 'description' => t('Omega page layouts to be used as Panels Everywhere site templates.'),
+ 'get child' => 'omega_panels_get_sublayout',
+ 'get children' => 'omega_panels_get_sublayouts',
+ 'theme' => 'omega_panels',
+ 'admin theme' => 'omega_panels_admin',
+ 'regions' => array(),
+ );
+}
+
+/**
+ * Callback to retrieve a single Omega layout.
+ */
+function omega_panels_get_sublayout($plugin, $layout, $sublayout) {
+ $layouts = omega_panels_get_sublayouts($plugin, $layout);
+ if (isset($layouts["$layout:$sublayout"])) {
+ return $layouts["$layout:$sublayout"];
+ }
+}
+
+/**
+ * Callback to retrieve all Omega layouts.
+ */
+function omega_panels_get_sublayouts($plugin, $layout) {
+ require_once drupal_get_path('theme', 'omega') . '/includes/omega.inc';
+ $path = drupal_get_path('theme', 'omega');
+
+ $layouts = array();
+ if ($items = omega_layouts_info('omega')) {
+ foreach ($items as $name => $info) {
+ // Compute the relative path to the actual layout.
+ $relative = _omega_relative_path("$path/panels/layouts/omega", $info['path']);
+
+ $layouts["$layout:$name"] = array(
+ 'name' => "$layout:$name",
+ 'title' => $info['info']['name'],
+ 'layout' => $info,
+ ) + $plugin;
+
+ // Panels calls the preview image 'icon'.
+ if (isset($info['info']['preview'])) {
+ $layouts["$layout:$name"]['icon'] = "$relative{$info['info']['preview']}";
+ }
+
+ // Layouts may provide 'admin css' files.
+ if (isset($info['info']['admin css'])) {
+ $layouts["$layout:$name"]['admin css'] = "$relative{$info['info']['admin css']}";
+ }
+
+ // Various optional elements from the .info file of the layout.
+ foreach (array('regions', 'category', 'description') as $key) {
+ if (isset($info['info'][$key])) {
+ $layouts["$layout:$name"][$key] = $info['info'][$key];
+ }
+ }
+ }
+ }
+ return $layouts;
+}
+
+/**
+ * Implements hook_preprocess_omega_panels_admin().
+ */
+function template_preprocess_omega_panels_admin(&$variables) {
+ _omega_panels_layout_preprocess($variables);
+}
+
+/**
+ * Theme function for rendering an Omega layout on the Panels admin UI.
+ */
+function theme_omega_panels_admin(&$variables) {
+ return _omega_panels_layout_theme($variables);
+}
+
+/**
+ * Theme function for rendering an Omega layout.
+ */
+function theme_omega_panels(&$variables) {
+ return _omega_panels_layout_theme($variables);
+}
+
+/**
+ * Implements hook_preprocess_omega_panels().
+ */
+function template_preprocess_omega_panels(&$variables) {
+ _omega_panels_layout_preprocess($variables);
+ drupal_process_attached(array('#attached' => $variables['layout']['layout']['attached']));
+}
+
+/**
+ * Helper function for preprocessing an Omega layout in Panels.
+ */
+function _omega_panels_layout_preprocess(&$variables) {
+ // Place a reference to the 'content' array so that the variables are
+ // accessible through both, the default page.tpl.php accessor and the panels
+ // layout accessor.
+ $variables['page'] = &$variables['content'];
+
+ // Provide some harmless default variables that would otherwise be added by
+ // template_preprocess_page().
+ $variables['base_path'] = base_path();
+ $variables['front_page'] = url();
+ $variables['language'] = $GLOBALS['language'];
+ $variables['language']->dir = $GLOBALS['language']->direction ? 'rtl' : 'ltr';
+
+ // In order to not render any of these items we simply set them as an empty
+ // string.
+ $variables['feed_icons'] = '';
+ $variables['logo'] = '';
+ $variables['main_menu'] = '';
+ $variables['secondary_menu'] = '';
+ $variables['action_links'] = '';
+ $variables['site_name'] = '';
+ $variables['site_slogan'] = '';
+ $variables['tabs'] = '';
+ $variables['breadcrumb'] = '';
+ $variables['title'] = '';
+ $variables['messages'] = '';
+}
+
+/**
+ * Helper function for rendering an Omega layout in Panels.
+ */
+function _omega_panels_layout_theme(&$variables) {
+ // Clean up the theme hook suggestion so we don't end up in an infinite loop.
+ unset($variables['theme_hook_suggestion'], $variables['theme_hook_suggestions']);
+
+ $hook = str_replace('-', '_', $variables['layout']['layout']['template']);
+ return theme($hook, $variables);
+}
+
+/**
+ * Computes the relative path between two absolute paths.
+ *
+ * @param string $from
+ * An absolute path.
+ * @param string $to
+ * An absolute path.
+ *
+ * @return string
+ * The relative path between $from and $to.
+ */
+function _omega_relative_path($from, $to) {
+ // some compatibility fixes for Windows paths
+ $from = is_dir($from) ? rtrim($from, '\/') . '/' : $from;
+ $to = is_dir($to) ? rtrim($to, '\/') . '/' : $to;
+ $from = str_replace('\\', '/', $from);
+ $to = str_replace('\\', '/', $to);
+ $from = explode('/', $from);
+ $to = explode('/', $to);
+ $relative = $to;
+
+ foreach ($from as $depth => $dir) {
+ // Find first non-matching directory.
+ if ($dir === $to[$depth]) {
+ // Ignore this directory.
+ array_shift($relative);
+ }
+ else {
+ // Get number of remaining dirs to $from.
+ $remaining = count($from) - $depth;
+ if ($remaining > 1) {
+ // Add traversals up to first matching directory.
+ $padding = (count($relative) + $remaining - 1) * -1;
+ $relative = array_pad($relative, $padding, '..');
+ break;
+ }
+ else {
+ $padding[0] = './' . $relative[0];
+ }
+ }
+ }
+
+ return implode('/', $relative);
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/panels/styles/omega/omega.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/panels/styles/omega/omega.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,32 @@
+ TRUE,
+ 'hook theme' => 'omega_panels_theme_registry_hack',
+ );
+}
+
+/**
+ * Slight hack to ensure that the Omega layouts are always properly registered.
+ *
+ * This is required so that they can be used in backend UIs that are not served
+ * with Omega based themes.
+ */
+function omega_panels_theme_registry_hack(&$theme, $data) {
+ // The theme files might not be loaded yet.
+ if (!function_exists('_omega_theme_layouts')) {
+ require_once drupal_get_path('theme', 'omega') . '/template.php';
+ }
+
+ // Register each layout.
+ $theme = array_merge($theme, _omega_theme_layouts());
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/preprocess/block-admin-display-form.preprocess.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/preprocess/block-admin-display-form.preprocess.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,14 @@
+ $title) {
+ drupal_add_tabledrag('blocks', 'match', 'sibling', 'block-region-select', 'block-region-' . $region, NULL, FALSE);
+ drupal_add_tabledrag('blocks', 'order', 'sibling', 'block-weight', 'block-weight-' . $region);
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/preprocess/block.preprocess.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/preprocess/block.preprocess.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,116 @@
+module);
+ $variables['attributes_array']['class'] = preg_replace('/^block-' . $css_module . '$/', 'block--' . $css_module, $variables['attributes_array']['class']);
+ $variables['attributes_array']['class'] = preg_replace('/^block-menu$/', 'block--menu', $variables['attributes_array']['class']);
+
+ $variables['title_attributes_array']['class'][] = 'block__title';
+
+ $variables['content_attributes_array']['class'][] = 'block__content';
+
+ // Add template suggestions to appropriate blocks.
+ switch ($variables['block']->module) {
+ case 'system':
+ switch ($variables['block']->delta) {
+ case 'help':
+ case 'powered-by':
+ break;
+
+ case 'main':
+ // Use a template with no wrapper for the page's main content.
+ $variables['theme_hook_suggestions'][] = 'block__minimal';
+ break;
+
+ default:
+ // Any other "system" block is a menu block and should use block--nav.tpl.php
+ $variables['theme_hook_suggestions'][] = 'block__nav';
+ break;
+ }
+ break;
+
+ case 'menu':
+ case 'menu_block':
+ // Use block--nav.tpl.php template.
+ $variables['theme_hook_suggestions'][] = 'block__nav';
+ break;
+ }
+
+ // Add Aria Roles via attributes.
+ switch ($variables['block']->module) {
+ case 'system':
+ switch ($variables['block']->delta) {
+ case 'main':
+ // Note: the "main" role goes in the page.tpl, not here.
+ break;
+
+ case 'help':
+ case 'powered-by':
+ $variables['attributes_array']['role'] = 'complementary';
+ break;
+
+ default:
+ // Any other "system" block is a menu block.
+ $variables['attributes_array']['role'] = 'navigation';
+ break;
+ }
+ break;
+
+ case 'menu':
+ case 'menu_block':
+ case 'blog':
+ case 'book':
+ case 'comment':
+ case 'forum':
+ case 'shortcut':
+ case 'statistics':
+ $variables['attributes_array']['role'] = 'navigation';
+ break;
+
+ case 'search':
+ $variables['attributes_array']['role'] = 'search';
+ break;
+
+ case 'help':
+ case 'aggregator':
+ case 'locale':
+ case 'poll':
+ case 'profile':
+ $variables['attributes_array']['role'] = 'complementary';
+ break;
+
+ case 'node':
+ switch ($variables['block']->delta) {
+ case 'syndicate':
+ $variables['attributes_array']['role'] = 'complementary';
+ break;
+
+ case 'recent':
+ $variables['attributes_array']['role'] = 'navigation';
+ break;
+ }
+ break;
+
+ case 'user':
+ switch ($variables['block']->delta) {
+ case 'login':
+ $variables['attributes_array']['role'] = 'form';
+ break;
+
+ case 'new':
+ case 'online':
+ $variables['attributes_array']['role'] = 'complementary';
+ break;
+ }
+ break;
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/preprocess/comment-wrapper.preprocess.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/preprocess/comment-wrapper.preprocess.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,14 @@
+ $comment)) : '';
+ // Add a sub component class for the comment content.
+ $variables['content_attributes_array']['class'][] = 'comment__content';
+ // Add a sub component class to the comment links.
+ $variables['content']['links']['#attributes']['class'][] = 'comment__links';
+ // Change modifier classes to use BEM syntax.
+ $variables['classes_array'] = preg_replace('/^comment-new$/', 'comment--new', $variables['classes_array']);
+ $variables['classes_array'] = preg_replace('/^comment-by-viewer$/', 'comment--by-viewer', $variables['classes_array']);
+ $variables['classes_array'] = preg_replace('/^comment-by-node-author$/', 'comment--by-node-author', $variables['classes_array']);
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/preprocess/field.preprocess.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/preprocess/field.preprocess.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,10 @@
+ 'profile',
+ 'href' => $variables['grddl_profile'],
+ ));
+
+ // Serialize RDF Namespaces into an RDFa 1.1 prefix attribute.
+ if ($variables['rdf_namespaces']) {
+ $prefixes = array();
+ foreach (explode("\n ", ltrim($variables['rdf_namespaces'])) as $namespace) {
+ // Remove xlmns: and ending quote and fix prefix formatting.
+ $prefixes[] = str_replace('="', ': ', substr($namespace, 6, -1));
+ }
+ $variables['rdf_namespaces'] = ' prefix="' . implode(' ', $prefixes) . '"';
+ }
+
+ // Classes for body element. Allows advanced theming based on context
+ // (home page, node of certain type, etc.).
+ if (!$variables['is_front']) {
+ // Add unique class for each page.
+ $path = drupal_get_path_alias($_GET['q']);
+ // Add unique class for each section of the website.
+ list($section, ) = explode('/', $path, 2);
+ $arg = explode('/', $_GET['q']);
+
+ if ($arg[0] == 'node' && isset($arg[1])) {
+ if ($arg[1] == 'add') {
+ $section = 'node-add';
+ }
+ elseif (isset($arg[2]) && is_numeric($arg[1]) && ($arg[2] == 'edit' || $arg[2] == 'delete')) {
+ $section = 'node-' . $arg[2];
+ }
+ }
+
+ $variables['attributes_array']['class'][] = drupal_html_class('section-' . $section);
+ }
+
+ // Add some styles in case the Omega theme is the active theme.
+ if ($GLOBALS['theme'] == 'omega') {
+ _omega_preprocess_html($variables);
+ }
+}
+
+/**
+ * Helper function for loading theme assets in case 'Omega' is the active theme.
+ *
+ * @see omega_preprocess_html()
+ */
+function _omega_preprocess_html(&$variables) {
+ // @todo
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/preprocess/links.preprocess.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/preprocess/links.preprocess.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,13 @@
+ $name) {
+ if (!isset($variables['page'][$region])) {
+ $variables['page'][$region] = array();
+ }
+ }
+
+ $original = system_region_list($GLOBALS['theme_key'], REGIONS_VISIBLE);
+ foreach (array_diff_key($original, $layout['info']['regions']) as $region => $name) {
+ unset($variables['page'][$region]);
+ }
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/preprocess/poll-results.preprocess.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/preprocess/poll-results.preprocess.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,14 @@
+ 'links',
+ '#links' => $variables['raw_links'],
+ '#attributes' => array('class' => array('links', 'poll-results__links')),
+ );
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/preprocess/region.preprocess.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/preprocess/region.preprocess.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,25 @@
+style_plugin->options;
+ $columns = $options['columns'];
+ foreach ($variables['rows'] as $delta => $row) {
+ $variables['row_attributes_array'][$delta] = isset($variables['row_attributes_array'][$delta]) ? $variables['row_attributes_array'][$delta] : array();
+
+ if (!empty($variables['row_classes'][$delta])) {
+ $variables['row_attributes_array'][$delta]['class'] = explode(' ', $variables['row_classes'][$delta]);
+ }
+
+ // Views tables have additional classes for each column.
+ for ($column = 0; $column < $columns; $column++) {
+ $variables['column_attributes_array'][$delta][$column] = isset($variables['column_attributes_array'][$delta][$column]) ? $variables['column_attributes_array'][$delta][$column] : array();
+
+ if (!empty($variables['column_classes'][$delta][$column])) {
+ $variables['column_attributes_array'][$delta][$column]['class'] = explode(' ', $variables['column_classes'][$delta][$column]);
+ }
+ }
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/preprocess/views/views-view-list.preprocess.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/preprocess/views/views-view-list.preprocess.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,18 @@
+ $row) {
+ $variables['row_attributes_array'][$delta] = isset($variables['row_attributes_array'][$delta]) ? $variables['row_attributes_array'][$delta] : array();
+
+ if (!empty($variables['classes_array'][$delta])) {
+ $variables['row_attributes_array'][$delta]['class'] = explode(' ', $variables['classes_array'][$delta]);
+ }
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/preprocess/views/views-view-table.preprocess.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/preprocess/views/views-view-table.preprocess.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,36 @@
+ $row) {
+ $variables['row_attributes_array'][$delta] = isset($variables['row_attributes_array'][$delta]) ? $variables['row_attributes_array'][$delta] : array();
+
+ if (!empty($variables['row_classes'][$delta])) {
+ $variables['row_attributes_array'][$delta]['class'] = $variables['row_classes'][$delta];
+ }
+
+ // Views tables have additional classes for each table column.
+ foreach ($row as $field => $content) {
+ $variables['field_attributes_array'][$field][$delta] = isset($variables['field_attributes_array'][$field][$delta]) ? $variables['field_attributes_array'][$field][$delta] : array();
+
+ if (!empty($variables['field_classes'][$field][$delta])) {
+ $variables['field_attributes_array'][$field][$delta]['class'] = explode(' ', $variables['field_classes'][$field][$delta]);
+ }
+ }
+ }
+
+ // Views tables have additional classes for each header column.
+ foreach ($variables['header'] as $field => $label) {
+ $variables['header_attributes_array'][$field] = isset($variables['header_attributes_array'][$field]) ? $variables['header_attributes_array'][$field] : array();
+
+ if (!empty($variables['header_classes'][$field])) {
+ $variables['header_attributes_array'][$field]['class'] = explode(' ', $variables['header_classes'][$field]);
+ }
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/preprocess/views/views-view-unformatted.preprocess.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/preprocess/views/views-view-unformatted.preprocess.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,18 @@
+ $row) {
+ $variables['row_attributes_array'][$delta] = isset($variables['row_attributes_array'][$delta]) ? $variables['row_attributes_array'][$delta] : array();
+
+ if (!empty($variables['classes_array'][$delta])) {
+ $variables['row_attributes_array'][$delta]['class'] = explode(' ', $variables['classes_array'][$delta]);
+ }
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/process/block.process.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/process/block.process.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,9 @@
+subject.
+ $variables['title'] = $variables['block']->subject;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/process/comment-wrapper.process.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/process/comment-wrapper.process.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,9 @@
+style_plugin->options;
+ $columns = $options['columns'];
+ foreach ($variables['rows'] as $delta => $row) {
+ // Convert the previously set row attributes arrays into strings.
+ $variables['row_attributes'][$delta] = !empty($variables['row_attributes_array'][$delta]) ? drupal_attributes($variables['row_attributes_array'][$delta]) : '';
+
+ for ($column = 0; $column < $columns; $column++) {
+ // Convert the previously set column attributes arrays into strings.
+ $variables['column_attributes'][$delta][$column] = !empty($variables['column_attributes_array'][$delta][$column]) ? drupal_attributes($variables['column_attributes_array'][$delta][$column]) : '';
+ }
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/process/views/views-view-list.process.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/process/views/views-view-list.process.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,13 @@
+ $item) {
+ // Convert the previously set row attributes arrays into strings.
+ $variables['row_attributes'][$delta] = !empty($variables['row_attributes_array'][$delta]) ? drupal_attributes($variables['row_attributes_array'][$delta]) : '';
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/process/views/views-view-table.process.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/process/views/views-view-table.process.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,23 @@
+ $row) {
+ // Convert the previously set row attributes arrays into strings.
+ $variables['row_attributes'][$delta] = !empty($variables['row_attributes_array'][$delta]) ? drupal_attributes($variables['row_attributes_array'][$delta]) : '';
+
+ foreach ($row as $field => $content) {
+ // Convert the previously set field attributes arrays into strings.
+ $variables['field_attributes'][$field][$delta] = !empty($variables['field_attributes_array'][$field][$delta]) ? drupal_attributes($variables['field_attributes_array'][$field][$delta]) : '';
+ }
+ }
+
+ foreach ($variables['header'] as $field => $label) {
+ // Convert the previously set header attributes arrays into strings.
+ $variables['header_attributes'][$field] = !empty($variables['header_attributes_array'][$field]) ? drupal_attributes($variables['header_attributes_array'][$field]) : '';
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/process/views/views-view-unformatted.process.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/process/views/views-view-unformatted.process.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,13 @@
+ $item) {
+ // Convert the previously set row attributes arrays into strings.
+ $variables['row_attributes'][$delta] = !empty($variables['row_attributes_array'][$delta]) ? drupal_attributes($variables['row_attributes_array'][$delta]) : '';
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/layouts/simple/simple.layout.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/layouts/simple/simple.layout.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * _layout.scss
+ *
+ * Styling of the "simple" layout demonstrating the Compass grid extension Susy
+ * and building mobile first layouts.
+ ******************************************************************************/
+@import "susy";
+
+// Susy Variables
+
+// Set consistent vertical and horizontal spacing units.
+$vert-spacing-unit: 20px;
+$horz-spacing-unit: 1em;
+
+// Define Susy grid variables mobile first.
+$total-columns: 4;
+$column-width: 4em;
+$gutter-width: $horz-spacing-unit;
+$grid-padding: 5px;
+
+$container-style: magic;
+$container-width: 1200px;
+
+// Susy Media Layouts @see http://susy.oddbird.net/guides/reference/#ref-media-layouts
+$tab: 44em 12; // At 44em use 12 columns.
+$desk: 70em 16; // At 70em use 16 columns.
+
+.l-header,
+.l-main,
+.l-footer {
+ @include container; // Define these elements as the grid containers.
+ // @include susy-grid-background; // Show the columns for debugging.
+ margin-bottom: $vert-spacing-unit;
+}
+
+.l-region--highlighted,
+.l-region--help,
+.l-region--sidebar-first,
+.l-region--sidebar-second {
+ margin-bottom: $vert-spacing-unit;
+}
+
+@include at-breakpoint($tab) { // At a given Susy Media Layout, use a given amount of columns.
+ .l-header,
+ .l-main,
+ .l-footer {
+ @include set-container-width; // Reset only the container width (elements have already been declared as containers).
+ // @include susy-grid-background; // Show the columns for debugging.
+ }
+
+ .l-branding {
+ @include span-columns(4, 12); // Span 4 out of 12 columns.
+ }
+ .l-region--header{
+ @include span-columns(8 omega, 12); // Span the last (omega) 8 columns of 12.
+ }
+ .l-region--navigation {
+ clear: both;
+ }
+
+ .sidebar-first,
+ .sidebar-second,
+ .two-sidebars {
+ .l-content {
+ @include span-columns(8, 12); // Span 8 out of 12 columns.
+ }
+ .l-region--sidebar-first,
+ .l-region--sidebar-second {
+ @include span-columns(4 omega, 12); // Span the last (omega) 4 columns of 12.
+ }
+ .l-region--sidebar-second {
+ clear: right;
+ }
+ }
+}
+
+@include at-breakpoint($desk) {
+ .l-header,
+ .l-main,
+ .l-footer {
+ @include set-container-width; // Reset only the container width (elements have already been declared as containers).
+ // @include susy-grid-background; // Show the columns for debugging.
+ }
+
+ .l-branding {
+ @include span-columns(6, 16); // Span 6 out of 16 columns.
+ }
+ .l-region--header{
+ @include span-columns(10 omega, 16); // Span the last (omega) 10 columns of 16.
+ }
+
+ .sidebar-first {
+ .l-content {
+ @include span-columns(12 omega, 16); // Span the last (omega) 12 columns of 16.
+ }
+ .l-region--sidebar-first {
+ @include span-columns(4, 16); // Span 4 out of 16 columns.
+ }
+ }
+ .sidebar-second {
+ .l-content {
+ @include span-columns(12, 16); // Span 12 out of 16 columns.
+ }
+ .l-region--sidebar-second {
+ @include span-columns(4 omega, 16); // Span the last (omega) 4 columns of 16.
+ clear: none;
+ }
+ }
+
+ .two-sidebars {
+ .l-content {
+ @include span-columns(8, 16); // Span 8 out of 16 columns.
+ @include push(4, 16); // Push element by adding 4 out of 16 columns of left margin.
+ }
+ .l-region--sidebar-first,
+ .l-region--sidebar-second {
+ @include span-columns(4, 16); // Span 4 out of 16 columns.
+ }
+ .l-region--sidebar-first {
+ @include pull(12, 16); // Pull element by adding 12 out of 16 columns of negative left margin.
+ }
+ .l-region--sidebar-second {
+ @include omega; // This element spans the last (omega) column.
+ clear: none;
+ }
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/aggregator/aggregator.theme-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/aggregator/aggregator.theme-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,8 @@
+/**
+ * @file
+ * Aggregator theme CSS for right to left languages.
+ */
+
+.feed-source .feed-icon {
+ float: left;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/aggregator/aggregator.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/aggregator/aggregator.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,9 @@
+/**
+ * @file
+ * Aggregator theme CSS.
+ */
+
+.feed-source .feed-icon {
+ float: right; /* LTR */
+ display: block;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/block/block.admin.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/block/block.admin.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,16 @@
+/**
+ * @file
+ * Styles for the block admin page.
+ */
+.blocks-admin {
+ .region-title {
+ font-weight: bold;
+ }
+ .region-message {
+ font-weight: normal;
+ color: #999;
+ }
+ .region-populated {
+ display: none;
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/block/block.demo.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/block/block.demo.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,34 @@
+/**
+ * @file
+ * Styles for the block demo page.
+ */
+
+@import "compass";
+
+.block-region {
+ margin-top: 4px;
+ margin-bottom: 4px;
+ padding: 3px;
+ background-color: #ff6;
+}
+.block-demo-backlink,
+.block-demo-backlink:link,
+.block-demo-backlink:visited {
+ /* Position */
+ position: fixed;
+ z-index: 499;
+ left: 20px; /* LTR */
+ /* Box Model */
+ padding: 5px 10px;
+ /* Font */
+ color: #000;
+ font-family: "Lucida Grande", Verdana, sans-serif;
+ font-size: small;
+ line-height: 20px;
+ /* Other Declarations */
+ background-color: #B4D7F0;
+ @include border-radius(0 0 10px 10px);
+}
+.block-demo-backlink:hover {
+ text-decoration: underline;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/book/book.admin.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/book/book.admin.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,25 @@
+/**
+ * @file
+ * Administration styles for the Book module.
+ */
+/**
+ * Book outline on book edit form.
+ */
+.js .book-outline-form .form-submit {
+ display: none;
+}
+/**
+ * Book form for administering a single book's hierarchy.
+ */
+.book-admin-edit select {
+ margin-right: 24px;
+}
+.book-admin-edit .progress-disabled {
+ margin-right: 0;
+}
+.book-admin-edit .ajax-new-content {
+ background-color: #ffd;
+}
+.book-admin-edit .form-item {
+ float: left;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/book/book.theme-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/book/book.theme-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,15 @@
+/**
+ * @file
+ * Basic default book structural CSS for right to left languages.
+ */
+.book-navigation__previous {
+ float: right;
+ text-align: right;
+}
+.book-navigation__up {
+ float: right;
+}
+.book-navigation__next {
+ float: left;
+ text-align: left;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/book/book.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/book/book.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,22 @@
+/**
+ * @file
+ * Basic theming for the book navigation component.
+ */
+.book-navigation__previous {
+ float: left; /* LTR */
+ display: block;
+ width: 45%;
+ text-align: left; /* LTR */
+}
+.book-navigation__up {
+ float: left; /* LTR */
+ display: block;
+ width: 10%;
+ text-align: center;
+}
+.book-navigation__next {
+ float: right; /* LTR */
+ display: block;
+ width: 45%;
+ text-align: right; /* LTR */
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/color/color.admin-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/color/color.admin-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,48 @@
+/**
+ * @file
+ * Right-to-left specific stylesheet for the Color module.
+ */
+
+#placeholder {
+ left: 0;
+ right: auto;
+}
+
+/* Palette */
+.color-form .form-item {
+ padding-left: 0;
+ padding-right: 1em;
+}
+.color-form label {
+ float: right;
+ clear: right;
+}
+.color-form .form-text,
+.color-form .form-select {
+ float: right;
+}
+.color-form .form-text {
+ margin-right: 0;
+ margin-left: 5px;
+}
+#palette .hook {
+ float: right;
+}
+#palette .down,
+#palette .up,
+#palette .both {
+ background: image-url('modules/color/hook-rtl.png') no-repeat 0 0;
+}
+#palette .up {
+ background-position: 0 -27px;
+}
+#palette .both {
+ background-position: 0 -54px;
+}
+#palette .lock {
+ float: right;
+ right: -10px;
+}
+html.js #preview {
+ float: right;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/color/color.admin.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/color/color.admin.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,85 @@
+/**
+ * @file
+ * Stylesheet for the administration pages of the Color module.
+ */
+
+/* Farbtastic placement */
+.color-form {
+ max-width: 50em;
+ position: relative;
+}
+#placeholder {
+ position: absolute;
+ top: 0;
+ right: 0; /* LTR */
+}
+
+/* Palette */
+.color-form .form-item {
+ height: 2em;
+ line-height: 2em;
+ padding-left: 1em; /* LTR */
+ margin: 0.5em 0;
+}
+.color-form label {
+ float: left; /* LTR */
+ clear: left; /* LTR */
+ width: 10em;
+}
+.color-form .form-text,
+.color-form .form-select {
+ float: left; /* LTR */
+}
+.color-form .form-text {
+ text-align: center;
+ margin-right: 5px; /* LTR */
+ cursor: pointer;
+}
+
+#palette .hook {
+ float: left; /* LTR */
+ margin-top: 3px;
+ width: 16px;
+ height: 16px;
+}
+#palette .down,
+#palette .up,
+#palette .both {
+ background: image-url('modules/color/hook.png') no-repeat 100% 0; /* LTR */
+}
+#palette .up {
+ background-position: 100% -27px; /* LTR */
+}
+#palette .both {
+ background-position: 100% -54px; /* LTR */
+}
+
+#palette .lock {
+ float: left; /* LTR */
+ position: relative;
+ top: -1.4em;
+ left: -10px; /* LTR */
+ width: 20px;
+ height: 25px;
+ background: image-url('modules/color/lock.png') no-repeat 50% 2px;
+ cursor: pointer;
+}
+#palette .unlocked {
+ background-position: 50% -22px;
+}
+#palette .form-item {
+ width: 20em;
+}
+#palette .item-selected {
+ background: #eee;
+}
+
+/* Preview */
+#preview {
+ display: none;
+}
+html.js #preview {
+ display: block;
+ position: relative;
+ float: left; /* LTR */
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/comment/comment.theme-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/comment/comment.theme-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,9 @@
+/**
+ * @file
+ * Right-to-left comment module look and feel styling.
+ */
+
+.indented {
+ margin-left: 0;
+ margin-right: 25px;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/comment/comment.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/comment/comment.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,8 @@
+/**
+ * @file
+ * Comment module look and feel styling.
+ */
+
+.indented {
+ margin-left: 25px; /* LTR */
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/contextual/contextual.base-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/contextual/contextual.base-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,15 @@
+/**
+ * @file
+ * Styling for contextual links behaviour and structure.
+ */
+
+/**
+ * Contextual links structure.
+ */
+.contextual-links-wrapper {
+ left: 5px;
+ right: auto;
+}
+.contextual-links-trigger {
+ text-align: left;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/contextual/contextual.base.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/contextual/contextual.base.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,37 @@
+/**
+ * @file
+ * Styling for contextual links behaviour and structure.
+ */
+
+/**
+ * Contextual links behaviour.
+ */
+.contextual-links-wrapper,
+.contextual-links-trigger,
+.contextual-links {
+ display: none !important;
+}
+html.js .contextual-links-wrapper,
+.contextual-links-region:hover .contextual-links-trigger,
+.contextual-links-active .contextual-links-trigger,
+.contextual-links-active .contextual-links {
+ display: block !important;
+}
+
+/**
+ * Contextual links structure.
+ */
+.contextual-links-region {
+ outline: none;
+ position: relative;
+}
+.contextual-links-wrapper {
+ position: absolute;
+ z-index: 999;
+ right: 5px; /* LTR */
+ top: 2px;
+}
+.contextual-links-trigger {
+ overflow: hidden;
+ text-align: right; /* LTR */
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/contextual/contextual.theme-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/contextual/contextual.theme-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,15 @@
+/**
+ * @file
+ * Styling for contextual links look and feel.
+ */
+
+@import "compass";
+
+/**
+ * Contextual links.
+ */
+.contextual-links {
+ left: 0;
+ right: auto;
+ @include border-radius(0 4px 4px 4px);
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/contextual/contextual.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/contextual/contextual.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,96 @@
+/**
+ * @file
+ * Styling for contextual links look and feel.
+ *
+ * We are proactivly making use of !important to ensure the contextual links
+ * styling isn't broken by unspecific selectors such as ".block a". In order to
+ * change the styling of the contextual links you should overwrite this file in
+ * your subtheme.
+ */
+
+@import "compass";
+
+/**
+ * Contextual link wrappers
+ */
+.contextual-links-region-active {
+ outline: #999 dashed 1px;
+}
+.contextual-links-wrapper {
+ font-size: 12px !important;
+
+ a {
+ text-decoration: none;
+ }
+}
+
+/**
+ * Contextual trigger.
+*/
+.contextual-links-trigger {
+ /* Positioning */
+ height: 18px;
+ /* Box Model */
+ margin: 0 !important;
+ padding: 0 2px !important;
+ width: 28px;
+ /* Other Declarations */
+ background: transparent image-url('modules/contextual/gear-select.png') no-repeat 2px 0 !important;
+ border: 1px solid transparent !important;
+ @include border-radius(4px);
+ outline: none;
+ text-indent: 9999px; /* LTR */
+}
+.contextual-links-trigger:hover,
+.contextual-links-active .contextual-links-trigger {
+ background-position: 2px -18px !important;
+}
+.contextual-links-active .contextual-links-trigger {
+ /* Positioning */
+ position: relative;
+ z-index: 1;
+ /* Other Declarations */
+ background-color: #fff !important;
+ border-color: #ccc !important;
+ border-bottom: none !important;
+ @include border-bottom-radius(0);
+}
+
+/**
+ * Contextual links.
+ */
+.contextual-links {
+ /* Position */
+ position: absolute;
+ right: 0; /* LTR */
+ top: 18px;
+ /* Box Model */
+ margin: 0 !important;
+ padding: 0 !important;
+ /* Other Declarations */
+ background-color: #fff !important;
+ border: 1px solid #ccc !important;
+ @include border-radius(4px 0 4px 4px); /* LTR */
+ text-align: left;
+ white-space: nowrap;
+
+ li {
+ margin: 0 !important;
+ padding: 0 !important;
+ line-height: 100%;
+ list-style: none;
+ list-style-image: none;
+ }
+
+ a {
+ display: block;
+ margin: 0 !important;
+ padding: 5px 10px !important;
+ color: #333 !important;
+ font-size: 12px !important;
+
+ &:hover {
+ background-color: #bfdcee !important;
+ }
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/field/field.theme-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/field/field.theme-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,14 @@
+/**
+ * @file
+ * Styling for contextual links behaviour and structure.
+ */
+
+/**
+ * Field display.
+ */
+.field--label-inline {
+ .field__label,
+ .field__items {
+ float: right;
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/field/field.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/field/field.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,17 @@
+/**
+ * @file
+ * Styling for contextual links behaviour and structure.
+ */
+
+/**
+ * Field display.
+ */
+.field__label {
+ font-weight: bold;
+}
+.field--label-inline {
+ .field__label,
+ .field__items {
+ float: left; /* LTR */
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/field_ui/field_ui.admin-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/field_ui/field_ui.admin-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,14 @@
+/**
+ * @file
+ * Right-to-left specific stylesheet for the Field UI module.
+ */
+
+/**
+ *'Manage fields' and 'Manage display' overviews.
+ */
+.field-ui-overview {
+ /* Add New Row */
+ .add-new .label-input {
+ float: right; /* LTR */
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/field_ui/field_ui.admin.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/field_ui/field_ui.admin.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,48 @@
+/**
+ * @file
+ * Stylesheet for the Field UI module.
+ */
+
+/**
+ *'Manage fields' and 'Manage display' overviews.
+ */
+.field-ui-overview {
+ /* Add New Row */
+ .add-new {
+ td {
+ vertical-align: top;
+ }
+ .label-input {
+ float: left; /* LTR */
+ }
+ .tabledrag-changed {
+ display: none;
+ }
+ .form-type-machine-name .description {
+ white-space: normal;
+ }
+ }
+
+ /* Hidden Messages */
+ .region-add-new-title {
+ display: none;
+ }
+ .region-populated {
+ display: none;
+ }
+}
+
+/**
+ * 'Manage display' overview
+ */
+.field-display-overview {
+ .field-formatter-settings-editing td {
+ vertical-align: top;
+ }
+ .field-formatter-settings-editing .field-formatter-type {
+ display: none;
+ }
+}
+.field-ui-display-overview-form #edit-refresh {
+ display:none;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/file/file.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/file/file.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,30 @@
+/**
+ * @file
+ * Admin stylesheet for file module.
+ */
+
+/**
+ * Managed file element.
+ */
+.form-managed-file {
+ .progress-disabled {
+ float: none;
+ display: inline;
+ }
+
+ .ajax-progress,
+ .throbber {
+ float: none;
+ }
+
+ .ajax-progress-bar {
+ display: none;
+ width: 28em;
+ margin-top: 4px;
+ padding: 0;
+
+ .bar {
+ margin: 0;
+ }
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/filter/filter.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/filter/filter.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,55 @@
+/**
+ * @file
+ * Styling for the filter module.
+ */
+
+/**
+ * Top Level Wrapper
+ * Contains the form item being filtered, the filter format form item and
+ * formatting guidelines.
+ */
+.text-format-wrapper {
+ .form-item {
+ margin-bottom: 0;
+ }
+ .description {
+ margin-top: 0.5em;
+ }
+}
+
+/* Filter Format Wrapper. */
+.filter-wrapper {
+ border-top: 0;
+ margin: 0;
+
+ .form-item {
+ float: left;
+ padding: 0 0 0.5em 1.5em;
+
+ label {
+ display: inline;
+ }
+ }
+}
+
+/* More Information Link. */
+.filter-help {
+ float: right;
+ padding: 0 1.5em 0.5em;
+
+ a {
+ background: transparent image-url('misc/help.png') right center no-repeat;
+ padding: 0 20px;
+ }
+}
+
+/* Filter Guidelines */
+.filter-guidelines {
+ clear: left;
+ padding: 0 1.5em;
+}
+
+/* Filter formatting tips. */
+.tips {
+ font-size: 0.9em;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/forum/forum.theme-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/forum/forum.theme-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,10 @@
+/**
+ * @file
+ * Right-to-left styling for the Forum module.
+ */
+
+.forum-icon {
+ float: right;
+ margin-left: 0;
+ margin-right: 0.4em;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/forum/forum.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/forum/forum.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,30 @@
+/**
+ * @file
+ * Styling for the Forum module.
+ */
+
+/* Forum Status Icons */
+.forum-icon {
+ float: left;
+ width: 24px;
+ height: 24px;
+ margin-right: 0.4em;
+ background-image: image-url('modules/forum/forum-icons.png');
+ background-repeat: no-repeat;
+ text-indent: -9999px;
+}
+.forum-icon--status-new {
+ background-position: -24px 0;
+}
+.forum-icon--status-hot {
+ background-position: -48px 0;
+}
+.forum-icon--status-hot-new {
+ background-position: -72px 0;
+}
+.forum-icon--status-sticky {
+ background-position: -96px 0;
+}
+.forum-icon--status-closed {
+ background-position: -120px 0;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/image/image.admin.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/image/image.admin.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,74 @@
+/**
+ * @file
+ * Admin styles for the image module.
+ */
+
+/**
+ * Image style configuration pages.
+ */
+
+/* Add new effect form. */
+.image-style-new,
+.image-style-new div {
+ display: inline;
+}
+
+/* Image style columns. */
+.image-style-preview__col {
+ float: left;
+ top: 50%;
+ width: 48%;
+ padding-bottom: 2em;
+ text-align: center;
+}
+
+/* Image style preview images. */
+.image-style-preview__preview-image {
+ margin: auto;
+ position: relative;
+}
+.preview-image__width {
+ position: absolute;
+ height: 2px;
+ left: -1px;
+ bottom: -6px;
+ border: 1px solid #666;
+ border-top: none;
+
+ .dimension {
+ position: relative;
+ top: 4px;
+ }
+}
+.preview-image__height {
+ position: absolute;
+ right: -6px;
+ top: -1px;
+ width: 2px;
+ border: 1px solid #666;
+ border-left: none;
+
+ .dimension {
+ position: absolute;
+ height: 2em;
+ top: 50%;
+ left: 10px;
+ margin-top: -1em;
+ }
+}
+
+/**
+ * Image anchor form element.
+ */
+.image-anchor {
+ width: auto;
+
+ .even,
+ .odd {
+ background: none;
+ }
+
+ td {
+ border: 1px solid #CCC;
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/image/image.theme-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/image/image.theme-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,15 @@
+/**
+ * @file
+ * Right-to-left styling for the Forum module.
+ */
+
+/**
+ * Image upload widget.
+ */
+.image-preview {
+ float: right;
+ padding: 0 0 10px 10px;
+}
+.image-widget-data {
+ float: right;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/image/image.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/image/image.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,19 @@
+/**
+ * @file
+ * Styles for the image module.
+ */
+
+/**
+ * Image upload widget.
+ */
+.image-preview {
+ float: left; /* LTR */
+ padding: 0 10px 10px 0; /* LTR */
+}
+.image-widget-data {
+ float: left; /* LTR */
+
+ .text-field {
+ width: auto;
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/locale/locale.admin-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/locale/locale.admin-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,18 @@
+/**
+ * @file
+ * Right to left admin styles for the locale module.
+ */
+
+.locale-translation-filter-form {
+ .form-item-language,
+ .form-item-translation,
+ .form-item-group {
+ float: right;
+ padding-left: .8em;
+ padding-right: 0;
+ }
+ .form-actions {
+ float: right;
+ padding: 3ex 1em 0 0;
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/locale/locale.admin.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/locale/locale.admin.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,29 @@
+/**
+ * @file
+ * Admin styles for the locale module.
+ */
+
+/* Untranslated locales. */
+.locale-untranslated {
+ font-style: normal;
+ text-decoration: line-through;
+}
+
+/* Translations 'exposed' filter form. */
+.locale-translation-filter-form {
+ .form-item-language,
+ .form-item-translation,
+ .form-item-group {
+ float: left; /* LTR */
+ padding-right: .8em; /* LTR */
+ margin: 0.1em;
+ width: 15em; /* Opera 9 Fix. */
+ }
+ .form-type-select select {
+ width: 100%;
+ }
+ .form-actions {
+ float: left; /* LTR */
+ padding: 3ex 0 0 1em; /* LTR */
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/openid/openid.base-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/openid/openid.base-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,9 @@
+/**
+ * @file
+ * Right to left base styles for the Open ID module.
+ */
+
+html.js .user-login-form .openid-link,
+html.js .user-login .openid-link {
+ margin-right: 0;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/openid/openid.base.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/openid/openid.base.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,14 @@
+/**
+ * @file
+ * Base styles for the Open ID module.
+ */
+
+html.js .user-login-form .openid-link,
+html.js .user-login .openid-link {
+ display: block;
+ margin-left: 0; /* LTR */
+}
+html.js .user-login-form .form-item-openid-identifier,
+html.js .user-login .form-item-openid-identifier {
+ display: none;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/openid/openid.theme-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/openid/openid.theme-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,15 @@
+/**
+ * @file
+ * Right to left theme styles for the openid module.
+ */
+
+.form-item-openid-identifier input {
+ padding-left: 0;
+ padding-right: 20px;
+ background-position: right 50%;
+}
+
+.openid-links a {
+ padding: 0 1.5em 0 0;
+ background-position: right top;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/openid/openid.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/openid/openid.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,30 @@
+/**
+ * @file
+ * Theme styles for the openid module.
+ */
+
+.form-item-openid-identifier {
+ display: block;
+
+ input {
+ padding-left: 20px; /* LTR */
+ background-image: image-url('modules/openid/login-bg.png');
+ background-position: left 50%; /* LTR */
+ background-repeat: no-repeat;
+ }
+}
+
+.openid-links {
+ li {
+ display: none;
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ }
+ a {
+ padding: 0 0 0 1.5em; /* LTR */
+ background-image: image-url('modules/openid/login-bg.png');
+ background-position: left top; /* LTR */
+ background-repeat: no-repeat;
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/poll/poll.admin.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/poll/poll.admin.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,16 @@
+/**
+ * @file
+ * Admin styles for the poll module.
+ */
+
+/* Poll choice form on node form. */
+.poll-choice-table {
+ .form-text {
+ display: inline;
+ width: auto;
+ }
+ .choice-flag {
+ white-space: nowrap;
+ width: 4em;
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/poll/poll.theme-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/poll/poll.theme-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,15 @@
+/**
+ * @file
+ * Right to left theme for the poll voting form and results display.
+ */
+
+/* Poll Bars */
+.poll-bars__bar .foreground {
+ float: right;
+}
+.poll-bars__text {
+ text-align: right;
+}
+.poll-bars__percent {
+ text-align: left;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/poll/poll.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/poll/poll.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,41 @@
+/**
+ * @file
+ * Theme for the poll voting form and results display.
+ */
+
+/**
+ * Poll Results
+ */
+
+/* Poll Bars */
+.poll-bars__bar {
+ height: 1em;
+ margin: 1px 0;
+ background-color: #ddd;
+
+ .foreground {
+ height: 1em;
+ float: left; /* LTR */
+ background-color: #000;
+ }
+}
+.poll-bars__percent {
+ text-align: right; /* LTR */
+}
+
+/* Poll Total */
+.poll-results__total {
+ text-align: center;
+}
+
+/**
+ * Poll Voting Form
+ */
+.poll-vote-form {
+ text-align: center;
+}
+.poll-vote-form__choices {
+ display: table;
+ margin: 0 auto;
+ text-align: left; /* LTR */
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/search/search.theme-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/search/search.theme-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,27 @@
+/**
+ * @file
+ * Right to left search module theme.
+ */
+
+/**
+ * Search Results
+ */
+.search-result__snippet {
+ padding-left: 0;
+ padding-right: 1em;
+}
+
+/**
+ * Advanced Search Form
+ */
+.search-advanced {
+ .criterion {
+ float: right;
+ margin-right: 0;
+ margin-left: 2em;
+ }
+ .action {
+ float: right;
+ clear: right;
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/search/search.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/search/search.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,28 @@
+/**
+ * @file
+ * Search module theme.
+ */
+
+/**
+ * Search Results
+ */
+.search-result__snippet {
+ padding-left: 1em; /* LTR */
+}
+.search-result__info {
+ font-size: 0.85em;
+}
+
+/**
+ * Advanced Search Form
+ */
+.search-advanced {
+ .criterion {
+ float: left; /* LTR */
+ margin-right: 2em; /* LTR */
+ }
+ .action {
+ float: left; /* LTR */
+ clear: left; /* LTR */
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/admin/adminlink/_adminlink.admin.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/admin/adminlink/_adminlink.admin.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,11 @@
+/**
+ * @file
+ * Administration styles for quick inline admin links.
+ */
+
+small .admin-link:before {
+ content: '[';
+}
+small .admin-link:after {
+ content: ']';
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/admin/adminpanel/_adminpanel.admin-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/admin/adminpanel/_adminpanel.admin-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,28 @@
+/**
+ * @file
+ * Right to left administration style for administration blocks.
+ */
+
+/* Admin Panels */
+.admin-panel {
+ .admin-panel__body {
+ padding-right: 1em;
+ }
+}
+
+/* Admin Panel Page Layout */
+.admin {
+ .left {
+ float: right;
+ }
+ .right {
+ float: left;
+ }
+ .expert-link {
+ margin-left: 0;
+ margin-right: 1em;
+ padding-left: 0;
+ padding-right: 4px;
+ text-align: left;
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/admin/adminpanel/_adminpanel.admin.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/admin/adminpanel/_adminpanel.admin.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,30 @@
+/**
+ * @file
+ * Administration styles for the administration panels.
+ */
+
+/* Admin Panels */
+.admin-panel {
+ .admin-panel__body {
+ padding-left: 1em; /* LTR */
+ }
+}
+
+/* Admin Panel Page Layout */
+.admin {
+ padding-top: 15px;
+
+ .left {
+ float: left; /* LTR */
+ width: 47%;
+ }
+ .right {
+ float: right; /* LTR */
+ width: 47%;
+ }
+ .expert-link {
+ margin-right: 1em; /* LTR */
+ padding-right: 4px; /* LTR */
+ text-align: right; /* LTR */
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/admin/appearance/_appearance.admin-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/admin/appearance/_appearance.admin-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,30 @@
+/**
+ * @file
+ * Right to left administration styles for the appearance page.
+ */
+
+/**
+ * Disabled/Enabled Theme Lists
+ */
+
+/* Theme Selector Links */
+.theme-selector__operations {
+ li {
+ float: right;
+ }
+}
+
+/* Theme Selector Enabled State */
+.theme-selector--enabled {
+ .theme-selector__info {
+ float: left;
+ }
+ .theme-selector__screenshot {
+ float: right;
+ }
+}
+/* Theme Selector Disabled State */
+.theme-selector--disabled {
+ float: right;
+ padding: 20px 20px 20px;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/admin/appearance/_appearance.admin.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/admin/appearance/_appearance.admin.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,101 @@
+/**
+ * @file
+ * Administration styles for the appearance page.
+ */
+
+/**
+ * Disabled/Enabled Theme Lists
+ */
+.system-themes-list {
+ margin-bottom: 20px;
+
+ h2 {
+ margin: 0;
+ }
+}
+.system-themes-list--disabled {
+ padding-top: 20px;
+ border-top: 1px solid #cdcdcd;
+}
+
+/**
+ * Theme Selector
+ */
+.theme-selector {
+ padding-top: 20px;
+
+ h3 {
+ font-weight: normal;
+ }
+}
+/* Theme Selector Screenshot */
+.theme-selector__screenshot {
+ padding: 2px;
+ width: 294px;
+ height: 219px;
+ border: 1px solid #e0e0d8;
+ line-height: 219px;
+ text-align: center;
+}
+/* Theme Selector Incompatible Message */
+.theme-selector__incompatible {
+ margin-top: 10px;
+ font-weight: bold;
+}
+/* Theme Selector Links */
+.theme-selector__operations {
+ margin: 10px 0 0 0;
+ padding: 0;
+
+ li {
+ float: left; /* LTR */
+ margin: 0 1em 0 0;
+ list-style-type: none;
+ }
+}
+/* Theme Selector Default State */
+.theme-selector--default {
+ h3 {
+ font-weight: bold;
+ }
+ .theme-selector__screenshot {
+ border: 1px solid #aaa;
+ }
+}
+/* Theme Selector Enabled State */
+.theme-selector--enabled {
+ width: 820px;
+
+ .theme-selector__info {
+ float: right; /* LTR */
+ width: 500px;
+ }
+ h3 {
+ margin-top: 0;
+ }
+ .theme-selector__screenshot {
+ float: left; /* LTR */
+ }
+}
+/* Theme Selector Disabled State */
+.theme-selector--disabled {
+ float: left; /* LTR */
+ width: 300px;
+ padding: 20px 20px 20px 0; /* LTR */
+
+ .theme-selector__info {
+ min-height: 170px;
+ }
+ .theme-selector__screenshot {
+ width: 194px;
+ height: 144px;
+ line-height: 144px;
+ }
+}
+
+/**
+ * Admin Theme Selector Form
+ */
+.system-themes-admin-form {
+ clear: left;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/admin/compactlink/_compactlink.admin.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/admin/compactlink/_compactlink.admin.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,8 @@
+/**
+ * @file
+ * Administration styles for compact links.
+ */
+
+.compact-link {
+ margin: 0 0 0.5em 0;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/admin/modules/_modules.admin-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/admin/modules/_modules.admin-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,25 @@
+/**
+ * @file
+ * Right to left administration styles for the modules table.
+ */
+
+/* Module Operation Links */
+.module-link {
+ padding: 1px 20px 1px 0;
+}
+.module-link-help {
+ background: image-url('misc/help.png') 0 50% no-repeat; /* LTR */
+}
+.module-link-permissions {
+ background: image-url('misc/permissions.png') 0 50% no-repeat; /* LTR */
+}
+.module-link-configure {
+ background: image-url('misc/configure.png') 0 50% no-repeat; /* LTR */
+}
+
+/* Module Help */
+.module-help {
+ float: left;
+ margin-left: 0;
+ margin-right: 1em;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/admin/modules/_modules.admin.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/admin/modules/_modules.admin.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,49 @@
+/**
+ * @file
+ * Administration styles for the modules table and help.
+ */
+
+/* Module State Flags */
+.admin-disabled {
+ color: #800;
+}
+.admin-enabled {
+ color: #080;
+}
+.admin-missing {
+ color: #f00;
+}
+
+/* Incompatible Modules */
+.incompatible {
+ font-weight: bold;
+}
+
+/* Module Requirements */
+.admin-requirements,
+.admin-required {
+ font-size: 0.9em;
+ color: #444;
+}
+
+/* Module Operation Links */
+.module-link {
+ display: block;
+ padding: 1px 0 1px 20px; /* LTR */
+ white-space: nowrap;
+}
+.module-link-help {
+ background: image-url('misc/help.png') 0 50% no-repeat; /* LTR */
+}
+.module-link-permissions {
+ background: image-url('misc/permissions.png') 0 50% no-repeat; /* LTR */
+}
+.module-link-configure {
+ background: image-url('misc/configure.png') 0 50% no-repeat; /* LTR */
+}
+
+/* Module Help */
+.module-help {
+ float: right; /* LTR */
+ margin-left: 1em; /* LTR */
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/admin/statusreport/_statusreport.admin-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/admin/statusreport/_statusreport.admin-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,8 @@
+/**
+ * @file
+ * Right to left administration styles for the system status report.
+ */
+
+.merge-up td {
+ padding: 0 28px 8px 6px;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/admin/statusreport/_statusreport.admin.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/admin/statusreport/_statusreport.admin.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,33 @@
+/**
+ * @file
+ * Administration styles for the system status report.
+ */
+
+/* Status Icons */
+.system-status-report {
+ .status-icon {
+ height: 16px;
+ width: 16px;
+ background-repeat: no-repeat;
+ }
+ .error .status-icon {
+ background-image: image-url('misc/message-16-error.png');
+ }
+ .warning .status-icon {
+ background-image: image-url('misc/message-16-warning.png');
+ }
+}
+
+/* Merge Cells */
+.merge-down,
+.merge-down td {
+ border-bottom-width: 0 !important;
+}
+
+.merge-up,
+.merge-up td {
+ border-top-width: 0 !important;
+}
+.merge-up td {
+ padding: 0 6px 8px 28px; /* LTR */
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/admin/themesettings/_themesettings.admin.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/admin/themesettings/_themesettings.admin.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,16 @@
+/**
+ * @file
+ * Administration styles for the theme settings.
+ */
+
+.theme-settings-left {
+ float: left;
+ width: 49%;
+}
+.theme-settings-right {
+ float: right;
+ width: 49%;
+}
+.theme-settings-bottom {
+ clear: both;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/autocomplete/_autocomplete.base-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/autocomplete/_autocomplete.base-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,14 @@
+/**
+ * @file
+ * Right to left base styles for autocomplete functionality.
+ *
+ * @see autocomplete.js
+ */
+
+/* Animated throbber */
+html.js .form-autocomplete {
+ background-position: 0% 2px;
+}
+html.js .throbbing {
+ background-position: 0% -18px;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/autocomplete/_autocomplete.base.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/autocomplete/_autocomplete.base.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,35 @@
+/**
+ * @file
+ * Base styles for autocomplete functionality.
+ *
+ * @see autocomplete.js
+ */
+
+/* Suggestion list */
+#autocomplete {
+ position: absolute;
+ z-index: 100;
+ overflow: hidden;
+
+ ul {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ list-style-image: none;
+ }
+ li {
+ cursor: default;
+ white-space: pre;
+ zoom: 1; /* IE7 */
+ }
+}
+
+/* Animated throbber */
+html.js .form-autocomplete {
+ background-image: image-url('misc/throbber.gif');
+ background-position: 100% 2px; /* LTR */
+ background-repeat: no-repeat;
+}
+html.js .throbbing {
+ background-position: 100% -18px; /* LTR */
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/autocomplete/_autocomplete.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/autocomplete/_autocomplete.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,17 @@
+/**
+ * @file
+ * Theme for autocomplete.
+ *
+ * @see autocomplete.js
+ */
+
+#autocomplete {
+ background: #fff;
+ border: 1px solid;
+ color: #000;
+
+ .selected {
+ background: #0072b9;
+ color: #fff;
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/collapsible/_collapsible.base.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/collapsible/_collapsible.base.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,19 @@
+/**
+ * @file
+ * Base styles for collapsible fieldset functionality.
+ *
+ * @see collapse.js
+ */
+
+html.js fieldset.collapsed {
+ height: 1em;
+}
+html.js fieldset.collapsed .fieldset-wrapper {
+ display: none;
+}
+fieldset.collapsible {
+ position: relative;
+}
+fieldset.collapsible .fieldset-legend {
+ display: block;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/collapsible/_collapsible.theme-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/collapsible/_collapsible.theme-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,16 @@
+/**
+ * @file
+ * Right to left theme for collapsible fieldsets.
+ *
+ * @see collapse.js
+ */
+
+html.js fieldset.collapsible .fieldset-legend {
+ padding-left: 0;
+ padding-right: 15px;
+ background-position: 98% 75%;
+}
+html.js fieldset.collapsed .fieldset-legend {
+ background-image: image-url('misc/menu-collapsed-rtl.png');
+ background-position: 98% 50%;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/collapsible/_collapsible.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/collapsible/_collapsible.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,26 @@
+/**
+ * @file
+ * Theme for collapsible fieldsets.
+ *
+ * @see collapse.js
+ */
+
+html.js fieldset.collapsible .fieldset-legend {
+ padding-left: 15px; /* LTR */
+ background: image-url('misc/menu-expanded.png') 5px 65% no-repeat; /* LTR */
+}
+html.js fieldset.collapsed {
+ border-bottom-width: 0;
+ border-left-width: 0;
+ border-right-width: 0;
+
+ .fieldset-legend {
+ background-image: image-url('misc/menu-collapsed.png'); /* LTR */
+ background-position: 5px 50%; /* LTR */
+ }
+}
+.fieldset-legend .summary {
+ margin-left: 0.5em;
+ color: #999;
+ font-size: 0.9em;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/elements/_elements.theme-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/elements/_elements.theme-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,11 @@
+/**
+ * @file
+ * Basic right to left styling for common HTML elements.
+ */
+
+/* Tables */
+th {
+ padding-left: 1em;
+ padding-right: 0;
+ text-align: right;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/elements/_elements.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/elements/_elements.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,26 @@
+/**
+ * @file
+ * Basic styling for common HTML elements.
+ */
+
+/* Fieldsets */
+fieldset {
+ margin-bottom: 1em;
+}
+
+/* Tables */
+table {
+ border-collapse: collapse;
+}
+th {
+ padding-right: 1em; /* LTR */
+ background-color: #bbb;
+ text-align: left; /* LTR */
+}
+tr.even,
+tr.odd {
+ background-color: #eee;
+}
+tr.odd {
+ background-color: #ddd;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/exposed/_exposed.admin-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/exposed/_exposed.admin-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,17 @@
+/**
+ * Exposed filters.
+ */
+.exposed-filters .filters {
+ float: right;
+ margin-left: 1em;
+ margin-right: 0;
+}
+.exposed-filters .form-item label {
+ float: right;
+}
+/* Current filters */
+.exposed-filters .additional-filters {
+ float: right;
+ margin-left: 1em;
+ margin-right: 0;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/exposed/_exposed.admin.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/exposed/_exposed.admin.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,32 @@
+/**
+ * Exposed filters.
+ */
+.exposed-filters .filters {
+ float: left; /* LTR */
+ margin-right: 1em; /* LTR */
+ width: 25em; /* IE6 */
+}
+.exposed-filters .form-item {
+ margin: 0 0 0.1em 0;
+ padding: 0;
+}
+.exposed-filters .form-item label {
+ float: left; /* LTR */
+ width: 10em;
+ font-weight: normal;
+}
+.exposed-filters .form-select {
+ width: 14em;
+}
+/* Current filters */
+.exposed-filters .current-filters {
+ margin-bottom: 1em;
+}
+.exposed-filters .current-filters .placeholder {
+ font-style: normal;
+ font-weight: bold;
+}
+.exposed-filters .additional-filters {
+ float: left; /* LTR */
+ margin-right: 1em; /* LTR */
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/form/_form.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/form/_form.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,62 @@
+/**
+ * @form
+ * Theme for markup generated by Form API.
+ */
+
+/* Generic Form Items. */
+.form-item,
+.form-actions {
+ margin-bottom: 1em;
+
+ label {
+ display: block;
+ font-weight: bold;
+ }
+ .description {
+ font-size: 0.85em;
+ }
+}
+
+/* Checkboxes and Radios */
+.form-checkboxes,
+.form-radios {
+ .form-item {
+ margin-bottom: 0.4em;
+ }
+ .description {
+ margin-left: 2.4em;
+ }
+}
+label.option {
+ display: inline;
+ font-weight: normal;
+}
+.form-checkbox,
+.form-radio {
+ vertical-align: middle;
+}
+
+/* Errors */
+.marker,
+.form-required {
+ color: #f00;
+}
+input.error,
+textarea.error,
+select.error {
+ border: 2px solid red;
+}
+
+/* Table Form Items */
+tr .form-item {
+ margin-top: 0;
+ margin-bottom: 0;
+ white-space: nowrap;
+}
+
+/* Inline Items */
+.container-inline .form-actions,
+.container-inline.form-actions {
+ margin-top: 0;
+ margin-bottom: 0;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/menus/_links.theme-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/menus/_links.theme-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,12 @@
+/**
+ * @file
+ * Inline links as generated by theme_links().
+ */
+
+ul.inline {
+ li {
+ float: right;
+ margin-right: 0;
+ margin-left: 1em;
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/menus/_links.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/menus/_links.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,20 @@
+/**
+ * @file
+ * Inline links as generated by theme_links().
+ */
+
+@import "compass/utilities/general/clearfix";
+
+.links--inline {
+ @include pie-clearfix;
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+
+ li {
+ float: left; /* LTR */
+ margin-right: 1em; /* LTR */
+
+ & > a { display: block; }
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/menus/_localtasks.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/menus/_localtasks.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,37 @@
+/**
+ * @file
+ * Theme styles for markup generated by theme_menu_local_tasks().
+ */
+
+/* Tabs */
+.tabs {
+ a {
+ background-color: #eee;
+ text-decoration: none;
+
+ &.active {
+ background-color: #ccc;
+ }
+ &:hover,
+ &:focus {
+ background-color: #bbb;
+ }
+ }
+}
+
+/* Primary Tabs */
+.tabs--primary {
+ margin-bottom: 1em;
+ border-bottom: 1px solid #bbb;
+
+ a {
+ padding: 0.3em 0.8em;
+ }
+}
+
+/* Secondary Tabs */
+.tabs--secondary a {
+ padding: 0.2em 0.5em;
+ margin: 0.4em 0;
+ font-size: 0.9em;
+}
\ No newline at end of file
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/menus/_menutree.theme-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/menus/_menutree.theme-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,13 @@
+/**
+ * @file
+ * Styles for a hierarchical menu as generated by theme_menu_tree().
+ */
+
+.menu {
+ text-align: right;
+
+ /* Menu Item Hierarchy Modifiers */
+ .collapsed {
+ list-style-image: image-url('misc/menu-collapsed-rtl.png');
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/menus/_menutree.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/menus/_menutree.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,32 @@
+/**
+ * @file
+ * Styles for a hierarchical menu as generated by theme_menu_tree().
+ */
+
+.menu {
+ border: none;
+ list-style: none;
+ text-align: left; /* LTR */
+
+ /* Menu Item Hierarchy Modifiers */
+ .expanded {
+ list-style-image: image-url('misc/menu-expanded.png');
+ list-style-type: circle;
+ }
+ .collapsed {
+ list-style-image: image-url('misc/menu-collapsed.png'); /* LTR */
+ list-style-type: disc;
+ }
+ .leaf {
+ list-style-image: image-url('misc/menu-leaf.png');
+ list-style-type: square;
+ }
+}
+
+/* Menu State Modifiers */
+.active {
+ color: #000;
+}
+.menu-disabled {
+ background: #ccc;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/morelink/_morelink.theme-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/morelink/_morelink.theme-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,8 @@
+/**
+ * @file
+ * Right to left theme for the more link.
+ */
+
+.more-link {
+ text-align: left;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/morelink/_morelink.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/morelink/_morelink.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,9 @@
+/**
+ * @file
+ * Theme for more links.
+ */
+
+.more-link {
+ display: block;
+ text-align: right; /* LTR */
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/pager/_pager.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/pager/_pager.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,20 @@
+/**
+ * @file
+ * Theme for markup generated by theme_pager().
+ */
+
+.pager {
+ clear: both;
+ padding: 0;
+ text-align: center;
+}
+.pager__item {
+ display: inline;
+ padding: 0.5em;
+ background-image: none;
+ list-style-type: none;
+
+}
+.pager__item--current {
+ font-weight: bold;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/progress/_progress.base-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/progress/_progress.base-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,20 @@
+/**
+ * @file
+ * Right to left base styles for the progress behavior.
+ *
+ * @see progress.js
+ */
+
+/* Bar */
+.progress .percentage {
+ float: left;
+}
+.progress-disabled {
+ float: right;
+}
+.ajax-progress {
+ float: right;
+}
+.ajax-progress .throbber {
+ float: right;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/progress/_progress.base.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/progress/_progress.base.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,45 @@
+/**
+ * @file
+ * Base styles for the progress behavior.
+ *
+ * @see progress.js
+ */
+
+/* Bar */
+.progress {
+ .bar {
+ background-color: #fff;
+ border: 1px solid;
+ }
+ .filled {
+ height: 1.5em;
+ width: 5px;
+ background-color: #000;
+ }
+ .percentage {
+ float: right; /* LTR */
+ }
+}
+
+/* Throbber */
+.ajax-progress {
+ display: inline-block;
+
+ .throbber {
+ float: left; /* LTR */
+ height: 15px;
+ width: 15px;
+ margin: 2px;
+ background: transparent image-url('misc/throbber.gif') no-repeat 0px -18px;
+ }
+ .message {
+ padding-left: 20px;
+ }
+}
+
+tr .ajax-progress .throbber {
+ margin: 0 2px;
+}
+.ajax-progress-bar {
+ width: 16em;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/progress/_progress.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/progress/_progress.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,21 @@
+/**
+ * @file
+ * Theme for the progress behavior.
+ *
+ * @see progress.js
+ */
+.progress {
+ font-weight: bold;
+
+ .bar {
+ background: #ccc;
+ border-color: #666;
+ margin: 0 0.2em;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
+ }
+ .filled {
+ background: #0072b9 image-url('misc/progress.gif');
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/resizable/_resizable.base.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/resizable/_resizable.base.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,23 @@
+/**
+ * @file
+ * Base styles for the resizable textareas functionality.
+ *
+ * @see textarea.js
+ */
+
+@import "compass";
+
+.form-textarea-wrapper textarea {
+ display: block;
+ @include box-sizing(border-box);
+ width: 100%;
+ margin: 0;
+}
+.resizable-textarea .grippie {
+ height: 9px;
+ background: #eee image-url('misc/grippie.png') no-repeat center 2px;
+ border: 1px solid #ddd;
+ border-top-width: 0;
+ cursor: s-resize;
+ overflow: hidden;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/system.admin-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/system.admin-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,9 @@
+/**
+ * @file
+ * Right to left system wide administration styles.
+ */
+
+@import "admin/adminpanel/adminpanel.admin-rtl";
+@import "admin/appearance/appearance.admin-rtl";
+@import "admin/modules/modules.admin-rtl";
+@import "admin/statusreport/statusreport.admin-rtl";
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/system.admin.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/system.admin.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,12 @@
+/**
+ * @file
+ * System wide administration styles.
+ */
+
+@import "admin/adminlink/adminlink.admin";
+@import "admin/adminpanel/adminpanel.admin";
+@import "admin/appearance/appearance.admin";
+@import "admin/compactlink/compactlink.admin";
+@import "admin/modules/modules.admin";
+@import "admin/statusreport/statusreport.admin";
+@import "admin/themesettings/themesettings.admin";
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/system.base-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/system.base-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,8 @@
+/**
+ * @file
+ * Right to left system wide base styles.
+ */
+
+@import "autocomplete/autocomplete.base-rtl";
+@import "tabledrag/tabledrag.base-rtl";
+@import "progress/progress.base-rtl";
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/system.base.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/system.base.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,12 @@
+/**
+ * @file
+ * System wide base styles.
+ */
+
+@import "autocomplete/autocomplete.base";
+@import "collapsible/collapsible.base";
+@import "resizable/resizable.base";
+@import "tabledrag/tabledrag.base";
+@import "tableheader/tableheader.base";
+@import "progress/progress.base";
+@import "utilities/utilities.base";
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/system.menus.theme-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/system.menus.theme-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,7 @@
+/**
+ * @file
+ * Right to left menu and navigational styles.
+ */
+
+@import "menus/menutree.theme-rtl";
+@import "menus/links.theme-rtl";
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/system.menus.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/system.menus.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,8 @@
+/**
+ * @file
+ * Menu and navigational styles.
+ */
+
+@import "menus/menutree.theme";
+@import "menus/links.theme";
+@import "menus/localtasks.theme";
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/system.messages.theme-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/system.messages.theme-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,14 @@
+/**
+ * @file
+ * Right to left theme for for system messages.
+ */
+
+/* Message */
+.messages {
+ padding: 10px 50px 10px 10px;
+ background-position: 99% 8px;
+
+ ul {
+ margin: 0 1em 0 0;
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/system.messages.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/system.messages.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,67 @@
+/**
+ * @file
+ * Theme for for system messages.
+ */
+
+/* Message */
+.messages {
+ margin: 6px 0;
+ padding: 10px 10px 10px 50px; /* LTR */
+ background-position: 8px 8px; /* LTR */
+ background-repeat: no-repeat;
+ border: 1px solid;
+
+ ul {
+ margin: 0 0 0 1em; /* LTR */
+ padding: 0;
+ }
+ li {
+ list-style-image: none;
+ }
+}
+
+/* Status Messages */
+.messages--status {
+ background-image: image-url('misc/message-24-ok.png');
+ border-color: #be7;
+}
+.messages--status,
+tr.ok {
+ background-color: #f8fff0;
+}
+.messages--status,
+.ok {
+ color: #234600;
+}
+
+/* Warning Messages */
+.messages--warning {
+ background-image: image-url('misc/message-24-warning.png');
+ border-color: #ed5;
+}
+.messages--warning,
+tr.warning {
+ background-color: #fffce5;
+}
+.messages--warning,
+.warning {
+ color: #333;
+}
+
+/* Error Messages */
+.messages--error {
+ background-image: image-url('misc/message-24-error.png');
+ border-color: #ed541d;
+}
+.messages--error,
+tr.error {
+ background-color: #fef5f1;
+}
+.messages--error,
+.error {
+ color: #333;
+}
+
+.error /*p*/.error {
+ color: #8c2e0b;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/system.theme-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/system.theme-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,8 @@
+/**
+ * @file
+ * Right to left system wide theme styles.
+ */
+
+@import "elements/elements.theme-rtl";
+@import "collapsible/collapsible.theme-rtl";
+@import "morelink/morelink.theme-rtl";
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/system.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/system.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,15 @@
+/**
+ * @file
+ * System wide theme styles.
+ */
+
+@import "elements/elements.theme";
+@import "autocomplete/autocomplete.theme";
+@import "collapsible/collapsible.theme";
+@import "tabledrag/tabledrag.theme";
+@import "progress/progress.theme";
+@import "tableselect/tableselect.theme";
+@import "form/form.theme";
+@import "tablesort/tablesort.theme";
+@import "morelink/morelink.theme";
+@import "pager/pager.theme";
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/tabledrag/_tabledrag.base-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/tabledrag/_tabledrag.base-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,21 @@
+/**
+ * @file
+ * Right to left base styling for the tabledrag behavior.
+ *
+ * @see tabledrag.js
+ */
+
+.draggable .tabledrag-handle {
+ float: right;
+ margin-left: 0;
+}
+.indentation {
+ float: right;
+}
+.tree-child,
+.tree-child-last {
+ background-position: -65px center;
+}
+.tabledrag-toggle-weight-wrapper {
+ text-align: left;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/tabledrag/_tabledrag.base.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/tabledrag/_tabledrag.base.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,53 @@
+/**
+ * @file
+ * Base styling for the tabledrag behavior.
+ *
+ * @see tabledrag.js
+ */
+
+body.drag {
+ cursor: move;
+}
+/* Tabledrag Handle */
+.tabledrag-handle {
+ float: left; /* LTR */
+ overflow: hidden;
+ text-decoration: none;
+ cursor: move;
+
+ .handle {
+ height: 15px;
+ width: 15px;
+ margin: -0.4em 0;
+ padding: 0.4em;
+ background: image-url('misc/draggable.png') no-repeat 6px 9px;
+ }
+ &:hover {
+ text-decoration: none;
+ }
+}
+.tabledrag-handle-hover .handle {
+ background-position: 6px -11px;
+}
+
+/* Indentation */
+.indentation {
+ float: left; /* LTR */
+ width: 20px;
+}
+
+/* Tree Images */
+.tree-child {
+ background: image-url('misc/tree.png') no-repeat 12px center; /* LTR */
+}
+.tree-child-last {
+ background: image-url('misc/tree-bottom.png') no-repeat 12px center; /* LTR */
+}
+.tree-child-horizontal {
+ background: image-url('misc/tree.png') no-repeat -12px center;
+}
+
+/* Toggle Weight Link */
+.tabledrag-toggle-weight-wrapper {
+ text-align: right; /* LTR */
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/tabledrag/_tabledrag.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/tabledrag/_tabledrag.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,13 @@
+/**
+ * @file
+ * Theme for the tabledrag behavior.
+ *
+ * @see tabledrag.js
+ */
+
+.drag {
+ background-color: #fffff0;
+}
+.drag-previous {
+ background-color: #ffd;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/tableheader/_tableheader.base.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/tableheader/_tableheader.base.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,11 @@
+/**
+ * @file
+ * Base styling for the tableheader behavior.
+ *
+ * @see tableheader.js
+ */
+
+.sticky-header {
+ margin-top: 0;
+ background-color: #fff;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/tableselect/_tableselect.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/tableselect/_tableselect.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,14 @@
+/**
+ * @file
+ * Theme for the tableselect behavior.
+ *
+ * @see tableselect.js
+*/
+
+.selected td {
+ background: #ffc;
+}
+.checkbox,
+.checkbox {
+ text-align: center;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/tablesort/_tablesort.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/tablesort/_tablesort.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,11 @@
+/**
+ * @file
+ * Theme for the markup generated by theme_tablesort_indicator().
+ */
+
+th.active img {
+ display: inline;
+}
+td.active {
+ background-color: #ddd;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/system/utilities/_utilities.base.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/system/utilities/_utilities.base.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,80 @@
+/**
+ * @file
+ * System utility classes.
+ */
+
+@import "compass/utilities/general/clearfix";
+
+/**
+ * Inline items.
+ */
+.container-inline div,
+.container-inline label {
+ display: inline;
+}
+/* Fieldset contents always need to be rendered as block. */
+.container-inline .fieldset-wrapper {
+ display: block;
+}
+
+/**
+ * Prevent text wrapping.
+ */
+.nowrap {
+ white-space: nowrap;
+}
+
+/**
+ * For anything you want to hide on page load when JS is enabled, so
+ * that you can use the JS to control visibility and avoid flicker.
+ */
+html.js .js-hide {
+ display: none;
+}
+
+/**
+ * Hide elements from all users.
+ *
+ * Used for elements which should not be immediately displayed to any user. An
+ * example would be a collapsible fieldset that will be expanded with a click
+ * from a user. The effect of this class can be toggled with the jQuery show()
+ * and hide() functions.
+ */
+.element-hidden {
+ display: none;
+}
+
+/**
+ * Hide elements visually, but keep them available for screen-readers.
+ *
+ * Used for information required for screen-reader users to understand and use
+ * the site where visual display is undesirable. Information provided in this
+ * manner should be kept concise, to avoid unnecessary burden on the user.
+ * "!important" is used to prevent unintentional overrides.
+ */
+.element-invisible {
+ position: absolute !important;
+ clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
+ clip: rect(1px, 1px, 1px, 1px);
+ overflow: hidden;
+ height: 1px;
+}
+
+/**
+ * The .element-focusable class extends the .element-invisible class to allow
+ * the element to be focusable when navigated to via the keyboard.
+ */
+.element-invisible.element-focusable:active,
+.element-invisible.element-focusable:focus {
+ position: static !important;
+ clip: auto;
+ overflow: visible;
+ height: auto;
+}
+
+/**
+ * Use the clearfix from Compass.
+ */
+.clearfix {
+ @include pie-clearfix;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/taxonomy/taxonomy.admin.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/taxonomy/taxonomy.admin.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,11 @@
+/**
+ * @file
+ * Administrative styling for the taxonomy module.
+ */
+
+.taxonomy-term-divider-top {
+ border-bottom: none;
+}
+.taxonomy-term-divider-bottom {
+ border-top: 1px dotted #CCC;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/user/user.admin-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/user/user.admin-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,27 @@
+/**
+ * @file
+ * Right to left administrative styling for the user module.
+ */
+/**
+ * User Permissions Page
+ */
+.user-admin-permissions {
+ .permission {
+ padding-left: 0;
+ padding-right: 1.5em;
+ }
+}
+
+/**
+ * User Roles Page
+ *
+ * Override default textfield float to put the "Add role" button next to
+ * the input textfield.
+ */
+.user-admin-roles {
+ .form-item-name {
+ float: right;
+ margin-left: 1em;
+ margin-right: 0;
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/user/user.admin.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/user/user.admin.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,34 @@
+/**
+ * @file
+ * Administrative styling for the user module.
+ */
+/**
+ * User Permissions Page
+ */
+.user-admin-permissions {
+ .module {
+ font-weight: bold;
+ }
+ .permission {
+ padding-left: 1.5em; /* LTR */
+ }
+ .form-item {
+ white-space: normal;
+ }
+}
+
+/**
+ * User Roles Page
+ *
+ * Override default textfield float to put the "Add role" button next to
+ * the input textfield.
+ */
+.user-admin-roles {
+ .edit-name {
+ clear: both;
+ }
+ .form-item-name {
+ float: left; /* LTR */
+ margin-right: 1em; /* LTR */
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/user/user.base.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/user/user.base.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,7 @@
+/**
+ * @file
+ * Base styles for the user module.
+ */
+div.password-confirm {
+ visibility: hidden;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/user/user.theme-rtl.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/user/user.theme-rtl.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,33 @@
+/**
+ * @file
+ * Right to left theme styling for the user module.
+ */
+/**
+ * Password Strength Indicator.
+ */
+.password-strength {
+ float: left;
+}
+.password-strength-title {
+ float: right;
+}
+.password-strength-text {
+ float: left;
+}
+
+/**
+ * Password Confirm.
+ */
+.password-confirm {
+ float: left;
+}
+
+/*
+ * User Profile
+ *
+ * Generated by user.module but used by profile.module.
+ */
+.profile .user-picture {
+ float: left;
+ margin: 0 0 1em 1em;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/modules/user/user.theme.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/modules/user/user.theme.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,91 @@
+/**
+ * @file
+ * Theme styling for the user module.
+ */
+/**
+ * Password Strength Indicator.
+ */
+.password-strength {
+ float: right; /* LTR */
+ margin-top: 1.2em;
+ width: 17em;
+}
+.password-strength-title {
+ float: left; /* LTR */
+}
+.password-strength-text {
+ float: right; /* LTR */
+ font-weight: bold;
+}
+.password-indicator {
+ clear: both;
+ height: 0.3em;
+ width: 100%;
+ background-color: #C4C4C4;
+
+ .indicator {
+ height: 100%;
+ width: 0%;
+ background-color: #47C965;
+ }
+}
+
+/**
+ * Password Confirm.
+ */
+div.password-confirm {
+ float: right; /* LTR */
+ clear: both;
+ width: 17em;
+ margin-top: 1.5em;
+}
+
+/**
+ * Password Confirm Inputs.
+ */
+.form-type-password-confirm input {
+ width: 16em;
+}
+
+/**
+ * Password Suggestions.
+ */
+.password-suggestions {
+ margin: 0.7em 0;
+ padding: 0.2em 0.5em;
+ border: 1px solid #B4B4B4;
+}
+
+
+/*
+ * User Profile
+ */
+.user-profile-item__label {
+ font-weight: bold;
+}
+
+
+
+/* Generated by user.module but used by profile.module. */
+.profile {
+ clear: both;
+ margin: 1em 0;
+
+ .user-picture {
+ float: right; /* LTR */
+ margin: 0 1em 1em 0; /* LTR */
+ }
+ h3 {
+ border-bottom: 1px solid #ccc;
+ }
+ dl {
+ margin: 0 0 1.5em 0;
+ }
+ dt {
+ margin: 0 0 0.2em 0;
+ font-weight: bold;
+ }
+ dd {
+ margin: 0 0 1em 0;
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/omega.admin.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/omega.admin.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,63 @@
+.form-item.form-item-omega-conditional-comments-html-options,
+.form-item.form-item-omega-viewport-widget-minimal,
+.omega-settings-container {
+ border: 1px solid #ccc;
+ margin-left: 18px;
+ margin-bottom: 12px;
+ padding: 9px 18px;
+ background-color: #f2f2f2;
+}
+
+.fieldset-description {
+ margin-bottom: 15px;
+}
+
+div.vertical-tabs .vertical-tabs-panes .vertical-tabs-pane fieldset {
+ border: 1px solid #CCC;
+ padding: 2.5em 0 0 0;
+ margin: 1em 0;
+
+ legend {
+ display: block;
+ }
+}
+
+.omega-assets-missing-files {
+ color: #8c2e0b;
+ margin: 1em 0 1em 1.5em;
+
+ h3 {
+ font-size: .9em;
+ text-transform: uppercase;
+ margin-bottom: 0;
+ }
+}
+
+.omega-layout-selection-wrapper {
+ margin-bottom: 20px;
+ min-height: 75px;
+ position: relative;
+
+ .form-item {
+ label.option,
+ div.description {
+ padding-left: 80px;
+ }
+ }
+
+ img {
+ height: 75px;
+ width: 64px;
+ position: absolute;
+ top: 8px;
+ margin-left: 1.5em;
+ }
+}
+
+.form-item.form-item-omega-requirements {
+ border: 1px solid #ed541d;
+ color: #8c2e0b;
+ background-color: #fef5f1;
+ margin: 6px 0 16px;
+ padding: 10px;
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/omega.development.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/omega.development.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,37 @@
+@import "rgbapng";
+@import "compass";
+
+.omega-browser-width {
+ @include border-radius(5px);
+ @include rgba-background(rgba(0, 0, 0, 0.75));
+ z-index: 1000;
+ position: fixed;
+ bottom: 0;
+ right: 0;
+ font-family: 'Lucida Grande', 'Lucida Sans Unicode', sans-serif;
+ font-size: 13px;
+ color: #fff;
+ max-width: 100%;
+ margin: 5px;
+ padding: 5px 10px;
+}
+
+.region--debug {
+ @include rgba-background(rgba(0, 0, 0, 0.1));
+ position: relative;
+ min-height: 29px;
+ outline: 1px dashed #ccc;
+
+ &:before {
+ @include border-radius(3px);
+ @include rgba-background(rgba(#077dc3, 0.75));
+ font-family: 'Lucida Grande', 'Lucida Sans Unicode', sans-serif;
+ font-size: 11px;
+ z-index: 50;
+ position: absolute;
+ right: 5px;
+ top: 5px;
+ padding: 3px 6px;
+ color: #fff;
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/sass/omega.messages.scss
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/sass/omega.messages.scss Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,24 @@
+@import "compass";
+
+// Use the default message layout.
+div.messages {
+ position: relative;
+}
+
+.close-message {
+ @include single-text-shadow(none);
+ position: absolute;
+ right: .4em;
+ top: -.2em;
+ text-decoration: none;
+ color: rgba(0, 0, 0, .3);
+
+ &:before {
+ font-size: 1.4em;
+ content: "×";
+ }
+
+ &:hover, &:focus, &:active {
+ color: #000;
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/screenshot.png
Binary file sites/all/themes/omega/omega/screenshot.png has changed
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/.bowerrc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/.bowerrc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,3 @@
+{
+ "directory" : "libraries"
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/.gitignore
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/.gitignore Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,5 @@
+# Ignore the node modules folder (created by 'npm install').
+node_modules
+
+# We absolutely don't want to have the .sass-cache in git.
+.sass-cache
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/.jshintrc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/.jshintrc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,24 @@
+{
+ "browser": true,
+ "bitwise": true,
+ "devel": true,
+ "curly": true,
+ "eqeqeq": true,
+ "forin": true,
+ "immed": true,
+ "indent": 2,
+ "jquery": true,
+ "latedef": true,
+ "newcap": true,
+ "noarg": true,
+ "quotmark": true,
+ "regexp": true,
+ "undef": true,
+ "unused": true,
+ "trailing": true,
+ "smarttabs": true,
+ "predef": [
+ "Drupal",
+ "Modernizr"
+ ]
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/.ruby-gemset
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/.ruby-gemset Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,1 @@
+omega.{{ THEME }}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/.ruby-version
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/.ruby-version Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,1 @@
+1.9.3
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/Gemfile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/Gemfile Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,33 @@
+source 'https://rubygems.org'
+
+group :development do
+
+ # Sass, Compass and extensions.
+ gem 'sass' # Sass.
+ gem 'sass-globbing' # Import Sass files based on globbing pattern.
+ gem 'compass' # Framework built on Sass.
+ gem 'compass-validator' # So you can `compass validate`.
+ gem 'compass-normalize' # Compass version of normalize.css.
+ gem 'compass-rgbapng' # Turns rgba() into .png's for backwards compatibility.
+ gem 'susy' # Susy grid framework.
+ gem 'singularitygs' # Alternative to the Susy grid framework.
+ gem 'toolkit' # Compass utility from the fabulous Snugug.
+ gem 'breakpoint' # Manages CSS media queries.
+ gem 'oily_png' # Faster Compass sprite generation.
+ gem 'css_parser' # Helps `compass stats` output statistics.
+
+ # Guard
+ gem 'guard' # Guard event handler.
+ gem 'guard-compass' # Compile on sass/scss change.
+ gem 'guard-shell' # Run shell commands.
+ gem 'guard-livereload' # Browser reload.
+ gem 'yajl-ruby' # Faster JSON with LiveReload in the browser.
+
+ # Dependency to prevent polling. Setup for multiple OS environments.
+ # Optionally remove the lines not specific to your OS.
+ # https://github.com/guard/guard#efficient-filesystem-handling
+ gem 'rb-inotify', '~> 0.9', :require => false # Linux
+ gem 'rb-fsevent', :require => false # Mac OSX
+ gem 'rb-fchange', :require => false # Windows
+
+end
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/Gruntfile.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/Gruntfile.js Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,111 @@
+'use strict';
+
+module.exports = function (grunt) {
+
+ grunt.initConfig({
+ watch: {
+ options: {
+ livereload: true
+ },
+ sass: {
+ files: ['sass/{,**/}*.{scss,sass}'],
+ tasks: ['compass:dev'],
+ options: {
+ livereload: false
+ }
+ },
+ registry: {
+ files: ['*.info', '{,**}/*.{php,inc}'],
+ tasks: ['shell'],
+ options: {
+ livereload: false
+ }
+ },
+ images: {
+ files: ['images/**']
+ },
+ css: {
+ files: ['css/{,**/}*.css']
+ },
+ js: {
+ files: ['js/{,**/}*.js', '!js/{,**/}*.min.js'],
+ tasks: ['jshint', 'uglify:dev']
+ }
+ },
+
+ shell: {
+ all: {
+ command: 'drush cache-clear theme-registry'
+ }
+ },
+
+ compass: {
+ options: {
+ config: 'config.rb',
+ bundleExec: true
+ },
+ dev: {
+ options: {
+ environment: 'development',
+ force: true
+ }
+ },
+ dist: {
+ options: {
+ environment: 'production',
+ force: true
+ }
+ }
+ },
+
+ jshint: {
+ options: {
+ jshintrc: '.jshintrc'
+ },
+ all: ['js/{,**/}*.js', '!js/{,**/}*.min.js']
+ },
+
+ uglify: {
+ dev: {
+ options: {
+ mangle: false,
+ compress: false,
+ beautify: true
+ },
+ files: [{
+ expand: true,
+ cwd: 'js',
+ src: ['**/*.js', '!**/*.min.js'],
+ dest: 'js',
+ ext: '.min.js'
+ }]
+ },
+ dist: {
+ options: {
+ mangle: true,
+ compress: true
+ },
+ files: [{
+ expand: true,
+ cwd: 'js',
+ src: ['**/*.js', '!**/*.min.js'],
+ dest: 'js',
+ ext: '.min.js'
+ }]
+ }
+ }
+ });
+
+ grunt.loadNpmTasks('grunt-contrib-watch');
+ grunt.loadNpmTasks('grunt-contrib-compass');
+ grunt.loadNpmTasks('grunt-contrib-jshint');
+ grunt.loadNpmTasks('grunt-contrib-uglify');
+ grunt.loadNpmTasks('grunt-shell');
+
+ grunt.registerTask('build', [
+ 'uglify:dist',
+ 'compass:dist',
+ 'jshint'
+ ]);
+
+};
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/Guardfile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/Guardfile Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,33 @@
+notification :off
+
+group :development do
+
+ # Only run Compass if we have a config.rb file in place.
+ if File.exists?("config.rb")
+ # Compile on start.
+ puts `compass compile --time --quiet`
+
+ # https://github.com/guard/guard-compass
+ guard :compass do
+ watch(%r{.+\.s[ac]ss$})
+ end
+ end
+
+ ## Uncomment this if you wish to clear the theme registry every time you
+ ## change one of the relevant theme files.
+ #guard :shell do
+ # puts 'Monitoring theme files.'
+ #
+ # watch(%r{.+\.(php|inc|info)$}) { |m|
+ # puts 'Change detected: ' + m[0]
+ # `drush cache-clear theme-registry`
+ # puts 'Cleared theme registry.'
+ # }
+ #end
+
+ # https://github.com/guard/guard-livereload.
+ guard :livereload do
+ watch(%r{.+\.(css|js)$})
+ end
+
+end
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/README.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/README.txt Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,1 @@
+Fill me.
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/basic.starterkit.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/basic.starterkit.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,19 @@
+name = Basic
+description = Provides a simple Sass setup.
+screenshot = screenshot.png
+engine = phptemplate
+core = 7.x
+
+; Styles
+stylesheets[all][] = css/{{ THEME }}.normalize.css
+stylesheets[all][] = css/{{ THEME }}.styles.css
+
+; Regions
+regions[header] = Header
+regions[navigation] = Navigation
+regions[highlighted] = Highlighted
+regions[help] = Help
+regions[content] = Content
+regions[sidebar_first] = First Sidebar
+regions[sidebar_second] = Second Sidebar
+regions[footer] = Footer
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/bower.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/bower.json Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,11 @@
+{
+ "name": "{{ THEME }}",
+ "version": "1.0.0",
+ "dependencies": {
+ "respond": "fubhy/respond",
+ "selectivizr": "fubhy/selectivizr",
+ "html5shiv": "fubhy/html5shiv",
+ "matchmedia": "fubhy/matchmedia",
+ "pie": "fubhy/pie"
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/config.rb
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/config.rb Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,48 @@
+##
+## This file is only needed for Compass/Sass integration. If you are not using
+## Compass, you may safely ignore or delete this file.
+##
+## If you'd like to learn more about Sass and Compass, see the sass/README.txt
+## file for more information.
+##
+
+# Default to development if environment is not set.
+saved = environment
+if (environment.nil?)
+ environment = :development
+else
+ environment = saved
+end
+
+# Location of the theme's resources.
+css_dir = "css"
+sass_dir = "sass"
+images_dir = "images"
+generated_images_dir = images_dir + "/generated"
+javascripts_dir = "js"
+
+# Require any additional compass plugins installed on your system.
+require 'compass-normalize'
+require 'rgbapng'
+require 'toolkit'
+require 'susy'
+require 'sass-globbing'
+
+##
+## You probably don't need to edit anything below this.
+##
+
+# You can select your preferred output style here (:expanded, :nested, :compact
+# or :compressed).
+output_style = (environment == :production) ? :expanded : :nested
+
+# To enable relative paths to assets via compass helper functions. Since Drupal
+# themes can be installed in multiple locations, we don't need to worry about
+# the absolute path to the theme from the server omega.
+relative_assets = true
+
+# Conditionally enable line comments when in development mode.
+line_comments = (environment == :production) ? false : true
+
+# Output debugging info in development mode.
+sass_options = (environment == :production) ? {} : {:debug_info => true}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/css/README.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/css/README.txt Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,1 @@
+Fill me.
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/css/{{ THEME }}.normalize.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/css/{{ THEME }}.normalize.css Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,328 @@
+/*******************************************************************************
+ * _utils.scss
+ *
+ * Sass offers come very useful features, these include variables functions and
+ * mixins. Extensions such as Compass and Susy can also be used to provide extra
+ * functions and mixins to be used throughout the theme. This file acts as a
+ * single place for defining these things, which can then be accessed by
+ * importing _utils.scss where required. The following should be defined in this
+ * file:
+ * - Custom Sass mixins for the theme.
+ * - Custom Sass functions for the theme.
+ * - Overriding the default variables provided by extensions such as Compass.
+ * - Defining new variables for:
+ * - Colors.
+ * - Font sizes and families.
+ * - Layout and grid sizing.
+ ******************************************************************************/
+/*! normalize.css v1.1.0 | MIT License | git.io/normalize */
+/*! normalize.css v1.1.0 | HTML5 Display Definitions | MIT License | git.io/normalize */
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+nav,
+section,
+summary {
+ display: block;
+}
+
+audio,
+canvas,
+video {
+ display: inline-block;
+ *display: inline;
+ *zoom: 1;
+}
+
+audio:not([controls]) {
+ display: none;
+ height: 0;
+}
+
+[hidden] {
+ display: none;
+}
+
+/*! normalize.css v1.1.0 | Base | MIT License | git.io/normalize */
+html {
+ font-size: 100%;
+ font-family: sans-serif;
+ -webkit-text-size-adjust: 100%;
+ -ms-text-size-adjust: 100%;
+}
+
+html,
+button,
+input,
+select,
+textarea {
+ font-family: sans-serif;
+}
+
+body {
+ margin: 0;
+}
+
+/*! normalize.css v1.1.0 | Links | MIT License | git.io/normalize */
+a:focus {
+ outline: thin dotted;
+}
+
+a:active,
+a:hover {
+ outline: 0;
+}
+
+/*! normalize.css v1.1.0 | Typography | MIT License | git.io/normalize */
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+
+h2 {
+ font-size: 1.5em;
+ margin: 0.83em 0;
+}
+
+h3 {
+ font-size: 1.17em;
+ margin: 1em 0;
+}
+
+h4 {
+ font-size: 1em;
+ margin: 1.33em 0;
+}
+
+h5 {
+ font-size: 0.83em;
+ margin: 1.67em 0;
+}
+
+h6 {
+ font-size: 0.67em;
+ margin: 2.33em 0;
+}
+
+abbr[title] {
+ border-bottom: 1px dotted;
+}
+
+b,
+strong {
+ font-weight: bold;
+}
+
+blockquote {
+ margin: 1em 40px;
+}
+
+dfn {
+ font-style: italic;
+}
+
+hr {
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+ height: 0;
+}
+
+mark {
+ background: #ff0;
+ color: #000;
+}
+
+p,
+pre {
+ margin: 1em 0;
+}
+
+code,
+kbd,
+pre,
+samp {
+ font-family: monospace, serif;
+ _font-family: 'courier new', monospace;
+ font-size: 1em;
+}
+
+pre {
+ white-space: pre;
+ white-space: pre-wrap;
+ word-wrap: break-word;
+}
+
+q {
+ quotes: "\201C" "\201D" "\2018" "\2019";
+}
+
+q {
+ quotes: none;
+}
+
+q:before,
+q:after {
+ content: '';
+ content: none;
+}
+
+small {
+ font-size: 80%;
+}
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sup {
+ top: -0.5em;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+dl,
+menu,
+ol,
+ul {
+ margin: 1em 0;
+}
+
+dd {
+ margin: 0 0 0 40px;
+}
+
+menu,
+ol,
+ul {
+ padding: 0 0 0 40px;
+}
+
+nav ul,
+nav ol {
+ list-style: none;
+ list-style-image: none;
+}
+
+/*! normalize.css v1.1.0 | Embedded Content | MIT License | git.io/normalize */
+img {
+ border: 0;
+ -ms-interpolation-mode: bicubic;
+}
+
+svg:not(:root) {
+ overflow: hidden;
+}
+
+/*! normalize.css v1.1.0 | Figures | MIT License | git.io/normalize */
+figure {
+ margin: 0;
+}
+
+/*! normalize.css v1.1.0 | Forms | MIT License | git.io/normalize */
+form {
+ margin: 0;
+}
+
+fieldset {
+ border: 1px solid #c0c0c0;
+ margin: 0 2px;
+ padding: 0.35em 0.625em 0.75em;
+}
+
+legend {
+ border: 0;
+ padding: 0;
+ white-space: normal;
+ *margin-left: -7px;
+}
+
+button,
+input,
+select,
+textarea {
+ font-family: inherit;
+ font-size: 100%;
+ margin: 0;
+ vertical-align: baseline;
+ *vertical-align: middle;
+}
+
+button,
+input {
+ line-height: normal;
+}
+
+button,
+select {
+ text-transform: none;
+}
+
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ -webkit-appearance: button;
+ cursor: pointer;
+ *overflow: visible;
+}
+
+button[disabled],
+html input[disabled] {
+ cursor: default;
+}
+
+input[type="checkbox"],
+input[type="radio"] {
+ box-sizing: border-box;
+ padding: 0;
+ *height: 13px;
+ *width: 13px;
+}
+
+input[type="search"] {
+ -webkit-appearance: textfield;
+ -moz-box-sizing: content-box;
+ -webkit-box-sizing: content-box;
+ box-sizing: content-box;
+}
+
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+
+textarea {
+ overflow: auto;
+ vertical-align: top;
+}
+
+/*! normalize.css v1.1.0 | Tables | MIT License | git.io/normalize */
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+*, *:after, *:before {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ *behavior: url('../behaviors/box-sizing/boxsizing.php');
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/css/{{ THEME }}.styles.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/css/{{ THEME }}.styles.css Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * style.scss
+ *
+ * This file shouldn't directly contain any SCSS code, instead it only serves to
+ * combine the SCSS contained in other Sass partials through @import directives.
+ *
+ * BASE............Styling for common HTML and Drupal elements.
+ * LAYOUT..........Styles for the page structure that contain components.
+ * COMPONENTS......Components, their modifiers and sub-components.
+ ******************************************************************************/
+/*******************************************************************************
+ * _utils.scss
+ *
+ * Sass offers come very useful features, these include variables functions and
+ * mixins. Extensions such as Compass and Susy can also be used to provide extra
+ * functions and mixins to be used throughout the theme. This file acts as a
+ * single place for defining these things, which can then be accessed by
+ * importing _utils.scss where required. The following should be defined in this
+ * file:
+ * - Custom Sass mixins for the theme.
+ * - Custom Sass functions for the theme.
+ * - Overriding the default variables provided by extensions such as Compass.
+ * - Defining new variables for:
+ * - Colors.
+ * - Font sizes and families.
+ * - Layout and grid sizing.
+ ******************************************************************************/
+/*******************************************************************************
+ * _base.scss
+
+ * Base styles define the default look for HTML and common Drupal elements.
+ *
+ * These rules will generally be made up of element selectors for HTML elements
+ * such as headings, paragraphs and lists. Common Drupal elements such as form
+ * items, collapsible fieldsets and messages should be included in this partial.
+ *
+ * The styleguide module (http://drupal.org/project/styleguide) gives you a good
+ * overview of Drupals common elements for styling. By setting a solid baseline
+ * before adding any more specific customisations you ensure that as any new
+ * features are added they will be correctly styled without any extra work.
+ ******************************************************************************/
+/*******************************************************************************
+ * _layout.scss
+ *
+ * The layout of the major regions (usually, but not necessarily Drupal regions)
+ * that components will be placed within. Layout styles for the theme's
+ * components should not be placed here and should instead be kept with the
+ * relevant SCSS for that component.
+ ******************************************************************************/
+/*******************************************************************************
+ * _components.scss
+ *
+ * Imports more partials that contain full components (modules in SMACSS), their
+ * sub-components and modifiers.
+ *
+ * Components are discrete parts of your page that should sit within the regions
+ * of your layouts. You should try to abstract your components as much as
+ * possible to promote reuse throughout the theme. Components should be flexible
+ * enough to respond to any width and should never rely on context
+ * (e.g. .sidebar-first .component) for styling. This allows modules to be
+ * placed throughout the theme with no risk of them breaking.
+ *
+ * If you find you need to change the look of a component depending on it's
+ * context you should avoid using context based classes at all costs. Instead it
+ * is better to add another "modifier" class to the component to alter the
+ * styling. Again, this promotes reuse.
+ *
+ * Sub-components are the individual parts that make up a component. As a
+ * general rule, adding a class to target a sub-component is a much better
+ * option than using descendant selectors or element selectors. In many cases
+ * sub-components can be made more reusable by making them components in their
+ * own right, so they can then be used within other components.
+ *
+ * Almost everything that doesn't belong in base should be made a component.
+ * Here's some common examples throughout Drupal:
+ *
+ * - Blocks
+ * - Content Types - For example, you may have a generic node component that
+ * contains sub-components for the submitted by line and links. Specific
+ * components can then be created for each content type to style the
+ * specifics of each. Finally, by using entity view modes you can easily
+ * apply modifications based on the .node-[view-mode] classes.
+ * - Forms - For instance the log in form.
+ * - Views - Each views output style could be made into a component, the content
+ * of each row should be provided my a view mode styled by it's component
+ * CSS. Exposed filter forms, views pagers and other views elements are
+ * also good candidates for components.
+ ******************************************************************************/
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/images/README.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/images/README.txt Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,1 @@
+Fill me.
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/js/README.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/js/README.txt Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,1 @@
+Fill me.
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/js/example.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/js/example.js Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,60 @@
+(function ($) {
+
+ /**
+ * The recommended way for producing HTML markup through JavaScript is to write
+ * theming functions. These are similiar to the theming functions that you might
+ * know from 'phptemplate' (the default PHP templating engine used by most
+ * Drupal themes including Omega). JavaScript theme functions accept arguments
+ * and can be overriden by sub-themes.
+ *
+ * In most cases, there is no good reason to NOT wrap your markup producing
+ * JavaScript in a theme function.
+ */
+ Drupal.theme.prototype.{{ THEME }}ExampleButton = function (path, title) {
+ // Create an anchor element with jQuery.
+ return $('' + title + '');
+ };
+
+ /**
+ * Behaviors are Drupal's way of applying JavaScript to a page. The advantage
+ * of behaviors over simIn short, the advantage of Behaviors over a simple
+ * document.ready() lies in how it interacts with content loaded through Ajax.
+ * Opposed to the 'document.ready()' event which is only fired once when the
+ * page is initially loaded, behaviors get re-executed whenever something is
+ * added to the page through Ajax.
+ *
+ * You can attach as many behaviors as you wish. In fact, instead of overloading
+ * a single behavior with multiple, completely unrelated tasks you should create
+ * a separate behavior for every separate task.
+ *
+ * In most cases, there is no good reason to NOT wrap your JavaScript code in a
+ * behavior.
+ *
+ * @param context
+ * The context for which the behavior is being executed. This is either the
+ * full page or a piece of HTML that was just added through Ajax.
+ * @param settings
+ * An array of settings (added through drupal_add_js()). Instead of accessing
+ * Drupal.settings directly you should use this because of potential
+ * modifications made by the Ajax callback that also produced 'context'.
+ */
+ Drupal.behaviors.{{ THEME }}ExampleBehavior = {
+ attach: function (context, settings) {
+ // By using the 'context' variable we make sure that our code only runs on
+ // the relevant HTML. Furthermore, by using jQuery.once() we make sure that
+ // we don't run the same piece of code for an HTML snippet that we already
+ // processed previously. By using .once('foo') all processed elements will
+ // get tagged with a 'foo-processed' class, causing all future invocations
+ // of this behavior to ignore them.
+ $('.some-selector', context).once('foo', function () {
+ // Now, we are invoking the previously declared theme function using two
+ // settings as arguments.
+ var $anchor = Drupal.theme('{{ THEME }}ExampleButton', settings.myExampleLinkPath, settings.myExampleLinkTitle);
+
+ // The anchor is then appended to the current element.
+ $anchor.appendTo(this);
+ });
+ }
+ };
+
+})(jQuery);
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/libraries.make
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/libraries.make Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,39 @@
+; ##############################################################################
+;
+; This is a Drush make file that will automatically download the front-end
+; libraries used by Omega. Alternatively, you can use Bower (http://bower.io) to
+; accomplish this.
+;
+; Running Drush make in your sub-theme will cause the libraries to be downloaded
+; into your theme. If you want to download them into Omega directly to make them
+; available to all of your sub-themes (if you have multiple) then you should
+; instead run omega.make from the Omega theme directory.
+;
+; To run this file with 'drush make' you first have to navigate into your theme.
+; Normally, this would be 'sites/all/themes/{{ THEME }}'.
+;
+; $ cd sites/all/themes/{{ THEME }}
+;
+; Now you can invoke 'drush make' using the following command:
+;
+; $ drush make libraries.make --no-core --contrib-destination=.
+;
+; ##############################################################################
+
+core = 7.x
+api = 2
+
+libraries[selectivizr][download][type] = "file"
+libraries[selectivizr][download][url] = "https://github.com/fubhy/selectivizr/archive/master.zip"
+
+libraries[html5shiv][download][type] = "file"
+libraries[html5shiv][download][url] = "https://github.com/fubhy/html5shiv/archive/master.zip"
+
+libraries[respond][download][type] = "file"
+libraries[respond][download][url] = "https://github.com/fubhy/respond/archive/master.zip"
+
+libraries[matchmedia][download][type] = "file"
+libraries[matchmedia][download][url] = "https://github.com/fubhy/matchmedia/archive/master.zip"
+
+libraries[pie][download][type] = "file"
+libraries[pie][download][url] = "https://github.com/fubhy/pie/archive/master.zip"
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/logo.png
Binary file sites/all/themes/omega/omega/starterkits/basic/logo.png has changed
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/package.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/package.json Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,16 @@
+{
+ "name": "{{ THEME }}",
+ "version": "1.0.0",
+ "dependencies": {},
+ "devDependencies": {
+ "grunt": "~0.4.0",
+ "grunt-contrib-watch": "~0.4.3",
+ "grunt-contrib-compass": "~0.2.0",
+ "grunt-contrib-jshint": "~0.1.1",
+ "grunt-contrib-uglify": "~0.2.0",
+ "grunt-shell": "~0.3.1"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/preprocess/README.md
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/preprocess/README.md Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,23 @@
+# Defining preprocess hooks
+Rather than placing your preprocess hooks directly in the template.php file you can manage them in automatically discovered and lazy-loaded include files. It is even possible to organize them in sub-folders. This feature greatly improves the maintainability of large themes that would otherwise contain hundreds of lines of unrelated code in your template.php file.
+
+The include files have to follow a certain naming pattern (HOOK.preprocess.inc) for them to be automatically discovered:
+
+* THEMENAME_preprocess_html() = html.preprocess.inc
+* THEMENAME_preprocess_page() = page.preprocess.inc
+* THEMENAME_preprocess_node() = node.preprocess.inc
+* THEMENAME_preprocess_comment() = comment.preprocess.inc
+* THEMENAME_preprocess_region() = region.preprocess.inc
+
+As with template files, you should replace underscores from the hook names with hyphens:
+
+* THEMENAME_preprocess_comment_wrapper() = comment-wrapper.preprocess.inc
+* THEMENAME_preprocess_html_tag() = html-tag.preprocess.inc
+
+Inside of each of these files you define the preprocess hook just as you would otherwise do in your template.php file:
+
+```
+function THEMENAME_preprocess_HOOK(&$variables) {
+ // Your code here.
+}
+```
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/basic/preprocess/page.preprocess.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/basic/preprocess/page.preprocess.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,9 @@
+ 0.9', :require => false # Linux
+ gem 'rb-fsevent', :require => false # Mac OSX
+ gem 'rb-fchange', :require => false # Windows
+
+end
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/extended/Gruntfile.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/extended/Gruntfile.js Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,111 @@
+'use strict';
+
+module.exports = function (grunt) {
+
+ grunt.initConfig({
+ watch: {
+ options: {
+ livereload: true
+ },
+ sass: {
+ files: ['sass/{,**/}*.{scss,sass}'],
+ tasks: ['compass:dev'],
+ options: {
+ livereload: false
+ }
+ },
+ registry: {
+ files: ['*.info', '{,**}/*.{php,inc}'],
+ tasks: ['shell'],
+ options: {
+ livereload: false
+ }
+ },
+ images: {
+ files: ['images/**']
+ },
+ css: {
+ files: ['css/{,**/}*.css']
+ },
+ js: {
+ files: ['js/{,**/}*.js', '!js/{,**/}*.min.js'],
+ tasks: ['jshint', 'uglify:dev']
+ }
+ },
+
+ shell: {
+ all: {
+ command: 'drush cache-clear theme-registry'
+ }
+ },
+
+ compass: {
+ options: {
+ config: 'config.rb',
+ bundleExec: true
+ },
+ dev: {
+ options: {
+ environment: 'development',
+ force: true
+ }
+ },
+ dist: {
+ options: {
+ environment: 'production',
+ force: true
+ }
+ }
+ },
+
+ jshint: {
+ options: {
+ jshintrc: '.jshintrc'
+ },
+ all: ['js/{,**/}*.js', '!js/{,**/}*.min.js']
+ },
+
+ uglify: {
+ dev: {
+ options: {
+ mangle: false,
+ compress: false,
+ beautify: true
+ },
+ files: [{
+ expand: true,
+ cwd: 'js',
+ src: ['**/*.js', '!**/*.min.js'],
+ dest: 'js',
+ ext: '.min.js'
+ }]
+ },
+ dist: {
+ options: {
+ mangle: true,
+ compress: true
+ },
+ files: [{
+ expand: true,
+ cwd: 'js',
+ src: ['**/*.js', '!**/*.min.js'],
+ dest: 'js',
+ ext: '.min.js'
+ }]
+ }
+ }
+ });
+
+ grunt.loadNpmTasks('grunt-contrib-watch');
+ grunt.loadNpmTasks('grunt-contrib-compass');
+ grunt.loadNpmTasks('grunt-contrib-jshint');
+ grunt.loadNpmTasks('grunt-contrib-uglify');
+ grunt.loadNpmTasks('grunt-shell');
+
+ grunt.registerTask('build', [
+ 'uglify:dist',
+ 'compass:dist',
+ 'jshint'
+ ]);
+
+};
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/extended/Guardfile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/extended/Guardfile Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,33 @@
+notification :off
+
+group :development do
+
+ # Only run Compass if we have a config.rb file in place.
+ if File.exists?("config.rb")
+ # Compile on start.
+ puts `compass compile --time --quiet`
+
+ # https://github.com/guard/guard-compass
+ guard :compass do
+ watch(%r{.+\.s[ac]ss$})
+ end
+ end
+
+ ## Uncomment this if you wish to clear the theme registry every time you
+ ## change one of the relevant theme files.
+ #guard :shell do
+ # puts 'Monitoring theme files.'
+ #
+ # watch(%r{.+\.(php|inc|info)$}) { |m|
+ # puts 'Change detected: ' + m[0]
+ # `drush cache-clear theme-registry`
+ # puts 'Cleared theme registry.'
+ # }
+ #end
+
+ # https://github.com/guard/guard-livereload.
+ guard :livereload do
+ watch(%r{.+\.(css|js)$})
+ end
+
+end
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/extended/README.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/extended/README.txt Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,1 @@
+Fill me.
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/extended/bower.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/extended/bower.json Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,11 @@
+{
+ "name": "{{ THEME }}",
+ "version": "1.0.0",
+ "dependencies": {
+ "respond": "fubhy/respond",
+ "selectivizr": "fubhy/selectivizr",
+ "html5shiv": "fubhy/html5shiv",
+ "matchmedia": "fubhy/matchmedia",
+ "pie": "fubhy/pie"
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/extended/config.rb
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/extended/config.rb Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,51 @@
+##
+## This file is only needed for Compass/Sass integration. If you are not using
+## Compass, you may safely ignore or delete this file.
+##
+## If you'd like to learn more about Sass and Compass, see the sass/README.txt
+## file for more information.
+##
+
+# Default to development if environment is not set.
+saved = environment
+if (environment.nil?)
+ environment = :development
+else
+ environment = saved
+end
+
+# Location of the theme's resources.
+css_dir = "css"
+sass_dir = "sass"
+images_dir = "images"
+generated_images_dir = images_dir + "/generated"
+javascripts_dir = "js"
+
+# Require any additional compass plugins installed on your system.
+require 'compass-normalize'
+require 'rgbapng'
+require 'toolkit'
+require 'susy'
+require 'sass-globbing'
+
+##
+## You probably don't need to edit anything below this.
+##
+
+# You can select your preferred output style here (:expanded, :nested, :compact
+# or :compressed).
+output_style = (environment == :production) ? :expanded : :nested
+
+# To enable relative paths to assets via compass helper functions. Since Drupal
+# themes can be installed in multiple locations, we don't need to worry about
+# the absolute path to the theme from the server omega.
+relative_assets = true
+
+# Conditionally enable line comments when in development mode.
+line_comments = (environment == :production) ? false : true
+
+# Output debugging info in development mode.
+sass_options = (environment == :production) ? {} : {:debug_info => true}
+
+# Add the 'sass' directory itself as an import path to ease imports.
+add_import_path 'sass'
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/extended/css/README.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/extended/css/README.txt Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,1 @@
+Fill me.
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/extended/css/{{ THEME }}.hacks.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/extended/css/{{ THEME }}.hacks.css Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,10 @@
+@media all and (max-width: 800px) {
+ #toolbar, #admin-menu {
+ display: none;
+ }
+
+ html body.toolbar, html body.admin-menu {
+ padding-top: 0 !important;
+ margin-top: 0 !important;
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/extended/css/{{ THEME }}.no-query.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/extended/css/{{ THEME }}.no-query.css Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,5 @@
+img, media {
+ max-width: 100%;
+}
+
+/* No files to import found in partials/components/**\/* */
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/extended/css/{{ THEME }}.normalize.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/extended/css/{{ THEME }}.normalize.css Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,310 @@
+/* normalize.css v1.1.0 | MIT License | git.io/normalize */
+/* normalize.css v1.1.0 | HTML5 Display Definitions | MIT License | git.io/normalize */
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+nav,
+section,
+summary {
+ display: block;
+}
+
+audio,
+canvas,
+video {
+ display: inline-block;
+ *display: inline;
+ *zoom: 1;
+}
+
+audio:not([controls]) {
+ display: none;
+ height: 0;
+}
+
+[hidden] {
+ display: none;
+}
+
+/* normalize.css v1.1.0 | Base | MIT License | git.io/normalize */
+html {
+ font-size: 100%;
+ font-family: sans-serif;
+ -webkit-text-size-adjust: 100%;
+ -ms-text-size-adjust: 100%;
+}
+
+html,
+button,
+input,
+select,
+textarea {
+ font-family: sans-serif;
+}
+
+body {
+ margin: 0;
+}
+
+/* normalize.css v1.1.0 | Links | MIT License | git.io/normalize */
+a:focus {
+ outline: thin dotted;
+}
+
+a:active,
+a:hover {
+ outline: 0;
+}
+
+/* normalize.css v1.1.0 | Typography | MIT License | git.io/normalize */
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+
+h2 {
+ font-size: 1.5em;
+ margin: 0.83em 0;
+}
+
+h3 {
+ font-size: 1.17em;
+ margin: 1em 0;
+}
+
+h4 {
+ font-size: 1em;
+ margin: 1.33em 0;
+}
+
+h5 {
+ font-size: 0.83em;
+ margin: 1.67em 0;
+}
+
+h6 {
+ font-size: 0.67em;
+ margin: 2.33em 0;
+}
+
+abbr[title] {
+ border-bottom: 1px dotted;
+}
+
+b,
+strong {
+ font-weight: bold;
+}
+
+blockquote {
+ margin: 1em 40px;
+}
+
+dfn {
+ font-style: italic;
+}
+
+hr {
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+ height: 0;
+}
+
+mark {
+ background: #ff0;
+ color: #000;
+}
+
+p,
+pre {
+ margin: 1em 0;
+}
+
+code,
+kbd,
+pre,
+samp {
+ font-family: monospace, serif;
+ font-size: 1em;
+}
+
+pre {
+ white-space: pre;
+ white-space: pre-wrap;
+ word-wrap: break-word;
+}
+
+q {
+ quotes: "\201C" "\201D" "\2018" "\2019";
+}
+
+q {
+ quotes: none;
+}
+
+q:before,
+q:after {
+ content: '';
+ content: none;
+}
+
+small {
+ font-size: 80%;
+}
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sup {
+ top: -0.5em;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+dl,
+menu,
+ol,
+ul {
+ margin: 1em 0;
+}
+
+dd {
+ margin: 0 0 0 40px;
+}
+
+menu,
+ol,
+ul {
+ padding: 0 0 0 40px;
+}
+
+nav ul,
+nav ol {
+ list-style: none;
+ list-style-image: none;
+}
+
+/* normalize.css v1.1.0 | Embedded Content | MIT License | git.io/normalize */
+img {
+ border: 0;
+ -ms-interpolation-mode: bicubic;
+}
+
+svg:not(:root) {
+ overflow: hidden;
+}
+
+/* normalize.css v1.1.0 | Figures | MIT License | git.io/normalize */
+figure {
+ margin: 0;
+}
+
+/* normalize.css v1.1.0 | Forms | MIT License | git.io/normalize */
+form {
+ margin: 0;
+}
+
+fieldset {
+ border: 1px solid #c0c0c0;
+ margin: 0 2px;
+ padding: 0.35em 0.625em 0.75em;
+}
+
+legend {
+ border: 0;
+ padding: 0;
+ white-space: normal;
+ *margin-left: -7px;
+}
+
+button,
+input,
+select,
+textarea {
+ font-family: inherit;
+ font-size: 100%;
+ margin: 0;
+ vertical-align: baseline;
+ *vertical-align: middle;
+}
+
+button,
+input {
+ line-height: normal;
+}
+
+button,
+select {
+ text-transform: none;
+}
+
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ -webkit-appearance: button;
+ cursor: pointer;
+ *overflow: visible;
+}
+
+button[disabled],
+html input[disabled] {
+ cursor: default;
+}
+
+input[type="checkbox"],
+input[type="radio"] {
+ box-sizing: border-box;
+ padding: 0;
+ *height: 13px;
+ *width: 13px;
+}
+
+input[type="search"] {
+ -webkit-appearance: textfield;
+ -moz-box-sizing: content-box;
+ -webkit-box-sizing: content-box;
+ box-sizing: content-box;
+}
+
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+
+textarea {
+ overflow: auto;
+ vertical-align: top;
+}
+
+/* normalize.css v1.1.0 | Tables | MIT License | git.io/normalize */
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+*, *:after, *:before {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ *behavior: url('../behaviors/box-sizing/boxsizing.php');
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/extended/css/{{ THEME }}.styles.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/extended/css/{{ THEME }}.styles.css Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,5 @@
+img, media {
+ max-width: 100%;
+}
+
+/* No files to import found in partials/components/**\/* */
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/extended/extended.starterkit.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/extended/extended.starterkit.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,21 @@
+name = Extended
+description = Comes with a well organized Sass setup with heavy use of partials.
+screenshot = screenshot.png
+engine = phptemplate
+core = 7.x
+
+; Styles
+stylesheets[all][] = css/{{ THEME }}.normalize.css
+stylesheets[all][] = css/{{ THEME }}.hacks.css
+stylesheets[all][] = css/{{ THEME }}.styles.css
+stylesheets[all][] = css/{{ THEME }}.no-query.css
+
+; Regions
+regions[header] = Header
+regions[navigation] = Navigation
+regions[highlighted] = Highlighted
+regions[help] = Help
+regions[content] = Content
+regions[sidebar_first] = First Sidebar
+regions[sidebar_second] = Second Sidebar
+regions[footer] = Footer
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/extended/images/README.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/extended/images/README.txt Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,1 @@
+Fill me.
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/extended/js/README.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/extended/js/README.txt Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,1 @@
+Fill me.
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/extended/js/example.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/extended/js/example.js Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,60 @@
+(function ($) {
+
+ /**
+ * The recommended way for producing HTML markup through JavaScript is to write
+ * theming functions. These are similiar to the theming functions that you might
+ * know from 'phptemplate' (the default PHP templating engine used by most
+ * Drupal themes including Omega). JavaScript theme functions accept arguments
+ * and can be overriden by sub-themes.
+ *
+ * In most cases, there is no good reason to NOT wrap your markup producing
+ * JavaScript in a theme function.
+ */
+ Drupal.theme.prototype.{{ THEME }}ExampleButton = function (path, title) {
+ // Create an anchor element with jQuery.
+ return $('' + title + '');
+ };
+
+ /**
+ * Behaviors are Drupal's way of applying JavaScript to a page. The advantage
+ * of behaviors over simIn short, the advantage of Behaviors over a simple
+ * document.ready() lies in how it interacts with content loaded through Ajax.
+ * Opposed to the 'document.ready()' event which is only fired once when the
+ * page is initially loaded, behaviors get re-executed whenever something is
+ * added to the page through Ajax.
+ *
+ * You can attach as many behaviors as you wish. In fact, instead of overloading
+ * a single behavior with multiple, completely unrelated tasks you should create
+ * a separate behavior for every separate task.
+ *
+ * In most cases, there is no good reason to NOT wrap your JavaScript code in a
+ * behavior.
+ *
+ * @param context
+ * The context for which the behavior is being executed. This is either the
+ * full page or a piece of HTML that was just added through Ajax.
+ * @param settings
+ * An array of settings (added through drupal_add_js()). Instead of accessing
+ * Drupal.settings directly you should use this because of potential
+ * modifications made by the Ajax callback that also produced 'context'.
+ */
+ Drupal.behaviors.{{ THEME }}ExampleBehavior = {
+ attach: function (context, settings) {
+ // By using the 'context' variable we make sure that our code only runs on
+ // the relevant HTML. Furthermore, by using jQuery.once() we make sure that
+ // we don't run the same piece of code for an HTML snippet that we already
+ // processed previously. By using .once('foo') all processed elements will
+ // get tagged with a 'foo-processed' class, causing all future invocations
+ // of this behavior to ignore them.
+ $('.some-selector', context).once('foo', function () {
+ // Now, we are invoking the previously declared theme function using two
+ // settings as arguments.
+ var $anchor = Drupal.theme('{{ THEME }}ExampleButton', settings.myExampleLinkPath, settings.myExampleLinkTitle);
+
+ // The anchor is then appended to the current element.
+ $anchor.appendTo(this);
+ });
+ }
+ };
+
+})(jQuery);
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/extended/libraries.make
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/extended/libraries.make Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,39 @@
+; ##############################################################################
+;
+; This is a Drush make file that will automatically download the front-end
+; libraries used by Omega. Alternatively, you can use Bower (http://bower.io) to
+; accomplish this.
+;
+; Running Drush make in your sub-theme will cause the libraries to be downloaded
+; into your theme. If you want to download them into Omega directly to make them
+; available to all of your sub-themes (if you have multiple) then you should
+; instead run omega.make from the Omega theme directory.
+;
+; To run this file with 'drush make' you first have to navigate into your theme.
+; Normally, this would be 'sites/all/themes/{{ THEME }}'.
+;
+; $ cd sites/all/themes/{{ THEME }}
+;
+; Now you can invoke 'drush make' using the following command:
+;
+; $ drush make libraries.make --no-core --contrib-destination=.
+;
+; ##############################################################################
+
+core = 7.x
+api = 2
+
+libraries[selectivizr][download][type] = "file"
+libraries[selectivizr][download][url] = "https://github.com/fubhy/selectivizr/archive/master.zip"
+
+libraries[html5shiv][download][type] = "file"
+libraries[html5shiv][download][url] = "https://github.com/fubhy/html5shiv/archive/master.zip"
+
+libraries[respond][download][type] = "file"
+libraries[respond][download][url] = "https://github.com/fubhy/respond/archive/master.zip"
+
+libraries[matchmedia][download][type] = "file"
+libraries[matchmedia][download][url] = "https://github.com/fubhy/matchmedia/archive/master.zip"
+
+libraries[pie][download][type] = "file"
+libraries[pie][download][url] = "https://github.com/fubhy/pie/archive/master.zip"
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/extended/logo.png
Binary file sites/all/themes/omega/omega/starterkits/extended/logo.png has changed
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/extended/package.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/extended/package.json Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,16 @@
+{
+ "name": "{{ THEME }}",
+ "version": "1.0.0",
+ "dependencies": {},
+ "devDependencies": {
+ "grunt": "~0.4.0",
+ "grunt-contrib-watch": "~0.4.3",
+ "grunt-contrib-compass": "~0.2.0",
+ "grunt-contrib-jshint": "~0.1.1",
+ "grunt-contrib-uglify": "~0.2.0",
+ "grunt-shell": "~0.3.1"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/extended/preprocess/README.md
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/extended/preprocess/README.md Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,23 @@
+# Defining preprocess hooks
+Rather than placing your preprocess hooks directly in the template.php file you can manage them in automatically discovered and lazy-loaded include files. It is even possible to organize them in sub-folders. This feature greatly improves the maintainability of large themes that would otherwise contain hundreds of lines of unrelated code in your template.php file.
+
+The include files have to follow a certain naming pattern (HOOK.preprocess.inc) for them to be automatically discovered:
+
+* THEMENAME_preprocess_html() = html.preprocess.inc
+* THEMENAME_preprocess_page() = page.preprocess.inc
+* THEMENAME_preprocess_node() = node.preprocess.inc
+* THEMENAME_preprocess_comment() = comment.preprocess.inc
+* THEMENAME_preprocess_region() = region.preprocess.inc
+
+As with template files, you should replace underscores from the hook names with hyphens:
+
+* THEMENAME_preprocess_comment_wrapper() = comment-wrapper.preprocess.inc
+* THEMENAME_preprocess_html_tag() = html-tag.preprocess.inc
+
+Inside of each of these files you define the preprocess hook just as you would otherwise do in your template.php file:
+
+```
+function THEMENAME_preprocess_HOOK(&$variables) {
+ // Your code here.
+}
+```
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/starterkits/extended/preprocess/page.preprocess.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/starterkits/extended/preprocess/page.preprocess.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,9 @@
+ $info) {
+ if (omega_extension_enabled($extension) && ($file = $info['path'] . '/' . $extension . '.inc') && is_file($file)) {
+ require_once $file;
+ }
+}
+
+/**
+ * Implements hook_element_info_alter().
+ */
+function omega_element_info_alter(&$elements) {
+ $elements['scripts'] = array(
+ '#items' => array(),
+ '#pre_render' => array('omega_pre_render_scripts'),
+ '#group_callback' => 'omega_group_js',
+ '#aggregate_callback' => 'omega_aggregate_js',
+ );
+}
+
+/**
+ * Implements hook_css_alter().
+ */
+function omega_css_alter(&$css) {
+ $omega = drupal_get_path('theme', 'omega');
+
+ // The CSS_SYSTEM aggregation group doesn't make any sense. Therefore, we are
+ // pre-pending it to the CSS_DEFAULT group. This has the same effect as giving
+ // it a separate (low-weighted) group but also allows it to be aggregated
+ // together with the rest of the CSS.
+ foreach ($css as &$item) {
+ if ($item['group'] == CSS_SYSTEM) {
+ $item['group'] = CSS_DEFAULT;
+ $item['weight'] = $item['weight'] - 100;
+ }
+ }
+
+ // Clean up core and contrib module CSS.
+ $overrides = array(
+ 'aggregator' => array(
+ 'aggregator.css' => array(
+ 'theme' => 'aggregator.theme.css',
+ ),
+ 'aggregator-rtl.css' => array(
+ 'theme' => 'aggregator.theme-rtl.css',
+ ),
+ ),
+ 'block' => array(
+ 'block.css' => array(
+ 'admin' => 'block.admin.css',
+ 'demo' => 'block.demo.css',
+ ),
+ ),
+ 'book' => array(
+ 'book.css' => array(
+ 'theme' => 'book.theme.css',
+ 'admin' => 'book.admin.css',
+ ),
+ 'book-rtl.css' => array(
+ 'theme' => 'book.theme-rtl.css',
+ ),
+ ),
+ 'color' => array(
+ 'color.css' => array(
+ 'admin' => 'color.admin.css',
+ ),
+ 'color-rtl.css' => array(
+ 'admin' => 'color.admin-rtl.css',
+ ),
+ ),
+ 'comment' => array(
+ 'comment.css' => array(
+ 'theme' => 'comment.theme.css',
+ ),
+ 'comment-rtl.css' => array(
+ 'theme' => 'comment.theme-rtl.css',
+ ),
+ ),
+ 'contextual' => array(
+ 'contextual.css' => array(
+ 'base' => 'contextual.base.css',
+ 'theme' => 'contextual.theme.css',
+ ),
+ 'contextual-rtl.css' => array(
+ 'base' => 'contextual.base-rtl.css',
+ 'theme' => 'contextual.theme-rtl.css',
+ ),
+ ),
+ 'field' => array(
+ 'theme/field.css' => array(
+ 'theme' => 'field.theme.css',
+ ),
+ 'theme/field-rtl.css' => array(
+ 'theme' => 'field.theme-rtl.css',
+ ),
+ ),
+ 'field_ui' => array(
+ 'field_ui.css' => array(
+ 'admin' => 'field_ui.admin.css',
+ ),
+ 'field_ui-rtl.css' => array(
+ 'admin' => 'field_ui.admin-rtl.css',
+ ),
+ ),
+ 'file' => array(
+ 'file.css' => array(
+ 'theme' => 'file.theme.css',
+ ),
+ ),
+ 'filter' => array(
+ 'filter.css' => array(
+ 'theme' => 'filter.theme.css',
+ ),
+ ),
+ 'forum' => array(
+ 'forum.css' => array(
+ 'theme' => 'forum.theme.css',
+ ),
+ 'forum-rtl.css' => array(
+ 'theme' => 'forum.theme-rtl.css',
+ ),
+ ),
+ 'image' => array(
+ 'image.css' => array(
+ 'theme' => 'image.theme.css',
+ ),
+ 'image-rtl.css' => array(
+ 'theme' => 'image.theme-rtl.css',
+ ),
+ 'image.admin.css' => array(
+ 'admin' => 'image.admin.css',
+ ),
+ ),
+ 'locale' => array(
+ 'locale.css' => array(
+ 'admin' => 'locale.admin.css',
+ ),
+ 'locale-rtl.css' => array(
+ 'admin' => 'locale.admin-rtl.css',
+ ),
+ ),
+ 'openid' => array(
+ 'openid.css' => array(
+ 'base' => 'openid.base.css',
+ 'theme' => 'openid.theme.css',
+ ),
+ 'openid-rtl.css' => array(
+ 'base' => 'openid.base-rtl.css',
+ 'theme' => 'openid.theme-rtl.css',
+ ),
+ ),
+ 'poll' => array(
+ 'poll.css' => array(
+ 'admin' => 'poll.admin.css',
+ 'theme' => 'poll.theme.css',
+ ),
+ 'poll-rtl.css' => array(
+ 'theme' => 'poll.theme-rtl.css',
+ ),
+ ),
+ 'search' => array(
+ 'search.css' => array(
+ 'theme' => 'search.theme.css',
+ ),
+ 'search-rtl.css' => array(
+ 'theme' => 'search.theme-rtl.css',
+ ),
+ ),
+ 'system' => array(
+ 'system.base.css' => array(
+ 'base' => 'system.base.css',
+ ),
+ 'system.base-rtl.css' => array(
+ 'base' => 'system.base-rtl.css',
+ ),
+ 'system.theme.css' => array(
+ 'theme' => 'system.theme.css',
+ ),
+ 'system.theme-rtl.css' => array(
+ 'theme' => 'system.theme-rtl.css',
+ ),
+ 'system.admin.css' => array(
+ 'admin' => 'system.admin.css',
+ ),
+ 'system.admin-rtl.css' => array(
+ 'admin' => 'system.admin-rtl.css',
+ ),
+ 'system.menus.css' => array(
+ 'theme' => 'system.menus.theme.css',
+ ),
+ 'system.menus-rtl.css' => array(
+ 'theme' => 'system.menus.theme-rtl.css',
+ ),
+ 'system.messages.css' => array(
+ 'theme' => 'system.messages.theme.css',
+ ),
+ 'system.messages-rtl.css' => array(
+ 'theme' => 'system.messages.theme-rtl.css',
+ ),
+ ),
+ 'taxonomy' => array(
+ 'taxonomy.css' => array(
+ 'admin' => 'taxonomy.admin.css',
+ ),
+ ),
+ 'user' => array(
+ 'user.css' => array(
+ 'base' => 'user.base.css',
+ 'admin' => 'user.admin.css',
+ 'theme' => 'user.theme.css',
+ ),
+ 'user-rtl.css' => array(
+ 'admin' => 'user.admin-rtl.css',
+ 'theme' => 'user.theme-rtl.css',
+ ),
+ ),
+ );
+
+ // Check if we are on an admin page. Otherwise, we can skip admin CSS.
+ $path = current_path();
+ $types = path_is_admin($path) ? array('base', 'theme', 'admin') : array('base', 'theme');
+ // Add a special case for the block demo page.
+ $types = strpos($path, 'admin/structure/block/demo') === 0 ? array_merge($types, array('demo')) : $types;
+
+ // Override module provided CSS with clean and modern alternatives provided
+ // by Omega.
+ foreach ($overrides as $module => $files) {
+ // We gathered the CSS files with paths relative to the providing module.
+ $path = drupal_get_path('module', $module);
+
+ foreach ($files as $file => $items) {
+ if (isset($css[$path . '/' . $file])) {
+ // Keep a copy of the original file array so we can merge that with our
+ // overrides in order to keep the 'weight' and 'group' declarations.
+ $original = $css[$path . '/' . $file];
+ unset($css[$path . '/' . $file]);
+
+ // Omega 4.x tries to follow the pattern described in
+ // http://drupal.org/node/1089868 for declaring CSS files. Therefore, it
+ // may take more than a single file to override a .css file added by
+ // core. This gives us better granularity when overriding .css files
+ // in a sub-theme.
+ foreach ($types as $type) {
+ if (isset($items[$type])) {
+ $css[$omega . '/css/modules/' . $module . '/' . $items[$type]] = array(
+ 'data' => $omega . '/css/modules/' . $module . '/' . $items[$type],
+ ) + $original;
+ }
+ }
+ }
+ }
+ }
+
+ // Exclude CSS files as declared in the theme settings.
+ if (omega_extension_enabled('assets') && $regex = omega_theme_get_setting('omega_css_exclude_regex')) {
+ // Make sure that RTL styles are excluded as well when a file name has been
+ // specified with it's full .css file extension.
+ $regex = preg_replace('/\\\.css$/', '(\.css|-rtl\.css)', $regex);
+ omega_exclude_assets($css, $regex);
+ }
+
+ // Allow themes to specify no-query fallback CSS files.
+ $mapping = omega_generate_asset_mapping($css);
+ foreach (preg_grep('/\.no-query(-rtl)?\.css$/', $mapping) as $key => $fallback) {
+ // Don't modify browser settings if they have already been modified.
+ if ($css[$key]['browsers']['IE'] === TRUE && $css[$key]['browsers']['!IE'] === TRUE) {
+ $css[$key]['browsers'] = array(
+ '!IE' => FALSE,
+ 'IE' => 'lte IE 8',
+ );
+
+ // Make sure that we don't break any CSS aggregation groups.
+ $css[$key]['weight'] += 100;
+ }
+ }
+}
+
+/**
+ * Implements hook_js_alter().
+ */
+function omega_js_alter(&$js) {
+ // If the AJAX.js isn't included... we don't need the ajaxPageState settings!
+ if (!isset($js['misc/ajax.js']) && isset($js['settings']['data'])) {
+ foreach ($js['settings']['data'] as $delta => $setting) {
+ if (array_key_exists('ajaxPageState', $setting)) {
+ if (count($setting) == 1) {
+ unset($js['settings']['data'][$delta]);
+ }
+ else {
+ unset($js['settings']['data'][$delta]['ajaxPageState']);
+ }
+ }
+ }
+ }
+
+ if (!omega_extension_enabled('assets')) {
+ return;
+ }
+
+ if ($regex = omega_theme_get_setting('omega_js_exclude_regex')) {
+ omega_exclude_assets($js, $regex);
+ }
+
+ // Move the specified JavaScript files to the footer.
+ if (($footer = omega_theme_get_setting('omega_js_footer')) && is_array($footer)) {
+ $regex = omega_generate_path_regex($footer);
+ $mapping = omega_generate_asset_mapping($js);
+
+ foreach (preg_grep($regex, $mapping) as $key => $match) {
+ $js[$key]['scope'] = 'footer';
+ }
+ }
+}
+
+/**
+ * Implements hook_form_alter().
+ */
+function omega_form_alter(&$form, &$form_state, $form_id) {
+ // Duplicate the form ID as a class so we can reduce specificity in our CSS.
+ $form['#attributes']['class'][] = drupal_clean_css_identifier($form['#id']);
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function omega_form_field_ui_display_overview_form_alter(&$form, &$form_state, $form_id) {
+ // Add a class to use as a styling hook, instead of the ID attribute.
+ $form['fields']['#attributes']['class'][] = 'field-display-overview';
+}
+
+/**
+ * Implements hook_theme().
+ */
+function omega_theme() {
+ $info['omega_chrome'] = array(
+ 'render element' => 'element',
+ );
+
+ $info['omega_layout'] = array(
+ 'base hook' => 'page',
+ );
+
+ $info = array_merge($info, _omega_theme_layouts());
+
+ return $info;
+}
+
+/**
+ * Helper function for registering theme hooks for Omega layouts.
+ */
+function _omega_theme_layouts() {
+ $info = array();
+
+ foreach (omega_layouts_info() as $layout) {
+ $hook = str_replace('-', '_', $layout['template']);
+ $info[$hook] = array(
+ 'template' => $layout['template'],
+ 'path' => $layout['path'],
+ );
+ }
+
+ return $info;
+}
+
+/**
+ * Implements hook_theme_registry_alter().
+ */
+function omega_theme_registry_alter(&$registry) {
+ require_once dirname(__FILE__) . '/includes/registry.inc';
+
+ // Fix for integration with the theme developer module.
+ if (module_exists('devel_themer')) {
+ foreach ($registry as $hook => $data) {
+ if (isset($data['original'])) {
+ $registry[$hook] = $data['original'];
+ }
+ }
+ }
+
+ // For maintainability reasons, some of this code lives in a class.
+ $handler = new OmegaThemeRegistryHandler($registry, $GLOBALS['theme']);
+
+ // Allows themers to split preprocess / process / theme code across separate
+ // files to keep the main template.php file clean. This is really fast because
+ // it uses the theme registry to cache the paths to the files that it finds.
+ $trail = omega_theme_trail($GLOBALS['theme']);
+ foreach ($trail as $theme => $name) {
+ $handler->registerHooks($theme);
+ $handler->registerThemeFunctions($theme, $trail);
+ }
+
+ // Override the default 'template_process_html' hook implementation.
+ $handler->overrideHook('html', 'template_process_html', 'omega_template_process_html_override');
+
+ // We prefer the attributes array instead of the plain classes array used by
+ // many core and contrib modules. In Drupal 8, we are going to convert all
+ // occurrences of that into an attributes object. For now, we simply
+ // synchronize our attributes array with the classes array to encourage
+ // themers to use it.
+ foreach ($registry as $hook => $item) {
+ if (empty($item['base hook']) && empty($item['function'])) {
+ if (($index = array_search('template_preprocess', $registry[$hook]['preprocess functions'], TRUE)) !== FALSE) {
+ // Make sure that omega_initialize_attributes() is invoked first.
+ array_unshift($registry[$hook]['process functions'], 'omega_cleanup_attributes');
+ // Add omega_cleanup_attributes() right after template_preprocess().
+ array_splice($registry[$hook]['preprocess functions'], $index + 1, 0, 'omega_initialize_attributes');
+ }
+ }
+ }
+
+ // Allow extensions to register hooks in the theme registry.
+ foreach (omega_extensions() as $extension => $info) {
+ // Invoke the according hooks for every enabled extension.
+ if (omega_extension_enabled($extension)) {
+ // Give every enabled extension a chance to alter the theme registry.
+ $hook = $info['theme'] . '_extension_' . $extension . '_theme_registry_alter';
+
+ if (function_exists($hook)) {
+ $hook($registry);
+ }
+ }
+ }
+
+ // Fix for integration with the theme developer module.
+ if (module_exists('devel_themer') && function_exists('devel_themer_theme_registry_alter')) {
+ devel_themer_theme_registry_alter($registry);
+ }
+}
+
+/**
+ * Initializes the attributes array from the classes array.
+ */
+function omega_initialize_attributes(&$variables) {
+ $variables['attributes_array']['class'] = &$variables['classes_array'];
+}
+
+/**
+ * Processes the attributes and classes array.
+ */
+function omega_cleanup_attributes(&$variables, $hook) {
+ // Break the reference between the classes array and the attributes array.
+ $classes = !empty($variables['classes_array']) ? $variables['classes_array'] : array();
+ unset($variables['attributes_array']['class'], $variables['classes_array']);
+
+ // Clone the attributes array classes into the classes array for backwards
+ // compatibility reasons. Note that we do not recommend using the classes in
+ // classes array anyways.
+ $variables['classes_array'] = $classes;
+
+ if (!empty($classes)) {
+ // Only write the 'class' attribute if it's not empty.
+ $variables['attributes_array']['class'] = $classes;
+ }
+}
+
+/**
+ * Overrides template_process_html().
+ */
+function omega_template_process_html_override(&$variables) {
+ // Render page_top and page_bottom into top level variables.
+ $variables['page_top'] = drupal_render($variables['page']['page_top']);
+ $variables['page_bottom'] = drupal_render($variables['page']['page_bottom']);
+ // Place the rendered HTML for the page body into a top level variable.
+ $variables['page'] = $variables['page']['#children'];
+ $variables['page_bottom'] .= omega_get_js('footer');
+
+ $variables['head'] = drupal_get_html_head();
+ $variables['css'] = drupal_add_css();
+ $variables['styles'] = drupal_get_css();
+ $variables['scripts'] = omega_get_js();
+}
+
+/**
+ * Implements hook_block_list_alter().
+ */
+function omega_block_list_alter(&$blocks) {
+ if (omega_extension_enabled('layouts') && $layout = omega_layout()) {
+ $callers = debug_backtrace();
+
+ // Check if drupal_alter() was invoked from _block_load_blocks(). This is
+ // required as we do not want to interfere with contrib modules like ctools.
+ if ($callers['2']['function'] === '_block_load_blocks') {
+ // In case we are currently serving a Omega layout we have to make sure that
+ // we don't process blocks that will never be shown because the active layout
+ // does not even have a region for them.
+ foreach ($blocks as $id => $block) {
+ if (!array_key_exists($block->region, $layout['info']['regions'])) {
+ unset($blocks[$id]);
+ }
+ }
+ }
+ }
+
+ // Hide the main content block on the front page if the theme settings are
+ // configured that way.
+ if (!omega_theme_get_setting('omega_toggle_front_page_content', TRUE) && drupal_is_front_page()) {
+ foreach ($blocks as $key => $block) {
+ if ($block->module == 'system' && $block->delta == 'main') {
+ unset($blocks[$key]);
+ }
+ }
+
+ drupal_set_page_content();
+ }
+}
+
+/**
+ * Implements hook_page_delivery_callback_alter().
+ */
+function omega_page_delivery_callback_alter(&$callback) {
+ if (module_exists('overlay') && overlay_display_empty_page()) {
+ $callback = 'omega_override_overlay_deliver_empty_page';
+ }
+}
+
+/**
+ * Delivery callback to display an empty page.
+ *
+ * This function is used to print out a bare minimum empty page which still has
+ * the scripts and styles necessary in order to trigger the overlay to close.
+ */
+function omega_override_overlay_deliver_empty_page() {
+ $empty_page = '' . drupal_get_css() . omega_get_js() . '';
+ print $empty_page;
+ drupal_exit();
+}
+
+/**
+ * Implements hook_page_alter().
+ */
+function omega_page_alter(&$page) {
+ // Place dummy blocks in each region if the 'demo regions' setting is active
+ // to force regions to be rendered.
+ if (omega_extension_enabled('development') && omega_theme_get_setting ('omega_demo_regions', TRUE) && user_access('administer site configuration')) {
+ $item = menu_get_item();
+
+ // Don't interfere with the 'Demonstrate block regions' page.
+ if (strpos('admin/structure/block/demo/', $item['path']) !== 0) {
+ $regions = system_region_list($GLOBALS['theme_key'], REGIONS_VISIBLE);
+ $configured = omega_theme_get_setting('omega_demo_regions_list', array_keys($regions));
+
+ // We don't explicitly load possible layout regions and instead really
+ // just show demo regions for those regions that we can actually place
+ // blocks in. Hence, there will only be demo regions for those regions
+ // that have been declared through the theme's .info file.
+ foreach (array_intersect_key($regions, array_flip($configured)) as $region => $name) {
+ if (empty($page[$region])) {
+ $page[$region]['#theme_wrappers'] = array('region');
+ $page[$region]['#region'] = $region;
+ }
+
+ $page[$region]['#name'] = $name;
+ $page[$region]['#debug'] = TRUE;
+ }
+ }
+ }
+
+ if (omega_extension_enabled('compatibility') && omega_theme_get_setting('omega_chrome_edge', TRUE) && omega_theme_get_setting('omega_chrome_notice', TRUE)) {
+ $supported = omega_theme_get_setting('omega_internet_explorer_support', FALSE);
+
+ $page['page_top']['omega_chrome'] = array(
+ '#theme' => 'omega_chrome',
+ '#pre_render' => array('drupal_pre_render_conditional_comments'),
+ '#browsers' => array(
+ 'IE' => !$supported ? TRUE : 'lte IE ' . $supported,
+ '!IE' => FALSE,
+ ),
+ );
+ }
+}
+
+/**
+ * Implements hook_html_head_alter().
+ */
+function omega_html_head_alter(&$head) {
+ // Simplify the meta tag for character encoding.
+ $head['system_meta_content_type']['#attributes'] = array('charset' => str_replace('text/html; charset=', '', $head['system_meta_content_type']['#attributes']['content']));
+}
+
+/**
+ * Implements hook_omega_theme_libraries_info().
+ */
+function omega_omega_theme_libraries_info($theme) {
+ $libraries['selectivizr'] = array(
+ 'name' => t('Selectivizr'),
+ 'description' => t('Selectivizr is a JavaScript utility that emulates CSS3 pseudo-classes and attribute selectors in Internet Explorer 6-8. Simply include the script in your pages and selectivizr will do the rest.'),
+ 'vendor' => 'Keith Clark',
+ 'vendor url' => 'http://selectivizr.com/',
+ 'package' => t('Polyfills'),
+ 'files' => array(
+ 'js' => array(
+ omega_theme_trail_file('libraries/selectivizr/selectivizr.min.js') => array(
+ 'browsers' => array('IE' => '(gte IE 6)&(lte IE 8)', '!IE' => FALSE),
+ 'weight' => 110,
+ 'every_page' => TRUE,
+ ),
+ ),
+ ),
+ 'variants' => array(
+ 'source' => array(
+ 'name' => t('Source'),
+ 'description' => t('During development it might be useful to include the source files instead of the minified version.'),
+ 'files' => array(
+ 'js' => array(
+ omega_theme_trail_file('libraries/selectivizr/selectivizr.js') => array(
+ 'browsers' => array('IE' => '(gte IE 6)&(lte IE 8)', '!IE' => FALSE),
+ 'weight' => 110,
+ 'every_page' => TRUE,
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+
+ $libraries['respond'] = array(
+ 'name' => t('Respond'),
+ 'description' => t('Respond is a fast & lightweight polyfill for min/max-width CSS3 Media Queries (for IE 6-8, and more). Note: This library requires CSS aggregation to be enabled for it to work properly.', array('!url' => url('admin/config/development/performance', array('alias' => TRUE)))),
+ 'vendor' => 'Scott Jehl',
+ 'vendor url' => 'http://scottjehl.com/',
+ 'package' => t('Polyfills'),
+ 'callbacks' => array('omega_extension_library_requirements_css_aggregation'),
+ 'files' => array(
+ 'js' => array(
+ omega_theme_trail_file('libraries/respond/respond.min.js') => array(
+ 'browsers' => array('IE' => '(gte IE 6)&(lte IE 8)', '!IE' => FALSE),
+ 'weight' => 120,
+ 'every_page' => TRUE,
+ ),
+ ),
+ ),
+ 'variants' => array(
+ 'source' => array(
+ 'name' => t('Source'),
+ 'description' => t('During development it might be useful to include the source files instead of the minified version.'),
+ 'files' => array(
+ 'js' => array(
+ omega_theme_trail_file('libraries/respond/respond.js') => array(
+ 'browsers' => array('IE' => '(gte IE 6)&(lte IE 8)', '!IE' => FALSE),
+ 'weight' => 120,
+ 'every_page' => TRUE,
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+
+ $libraries['css3pie'] = array(
+ 'name' => t('CSS3 PIE'),
+ 'description' => t('PIE makes Internet Explorer 6-9 capable of rendering several of the most useful CSS3 decoration features.'),
+ 'vendor' => 'Keith Clark',
+ 'vendor url' => 'http://css3pie.com/',
+ 'options form' => 'omega_library_pie_options_form',
+ 'package' => t('Polyfills'),
+ 'files' => array(),
+ 'variants' => array(
+ 'js' => array(
+ 'name' => t('JavaScript'),
+ 'description' => t('While the .htc behavior is still the recommended approach for most users, the JS version has some advantages that may be a better fit for some users.'),
+ 'files' => array(
+ 'js' => array(
+ omega_theme_trail_file('libraries/pie/PIE.js') => array(
+ 'browsers' => array('IE' => '(gte IE 6)&(lte IE 8)', '!IE' => FALSE),
+ 'weight' => 100,
+ 'every_page' => TRUE,
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+
+ $settings = omega_theme_get_setting('omega_libraries');
+ if (!empty($settings['css3pie']['selectors'])) {
+ // Add the generated .css file to the corresponding variant.
+ $destination = file_create_url('public://omega/' . $theme );
+ $destination = substr($destination, strlen($GLOBALS['base_url']) + 1);
+ file_prepare_directory($destination, FILE_CREATE_DIRECTORY);
+
+ // Save the generated CSS in the public file system.
+ $file = $destination . '/pie-selectors.css';
+ $htc = base_path() . omega_theme_trail_file('libraries/pie/PIE.htc');
+ $contents = implode(",", $settings['css3pie']['selectors']) . "{behavior:url($htc)}";
+ file_unmanaged_save_data($contents, $file, FILE_EXISTS_REPLACE);
+
+ $libraries['css3pie']['files']['css'][$file] = array(
+ 'browsers' => array('IE' => '(gte IE 6)&(lte IE 8)', '!IE' => FALSE),
+ 'weight' => 100,
+ 'every_page' => TRUE,
+ );
+
+ // Save the generated JS in the public file system.
+ $file = $destination . '/pie-selectors.js';
+ $contents = '$(function(){Drupal.behaviors.css3pie={attach:function(context,settings){if(window.PIE){$("' . implode(",", $settings['css3pie']['selectors']) . '").each(function(){PIE.attach(this)})}}}})(jQuery);';
+ file_unmanaged_save_data($contents, $file, FILE_EXISTS_REPLACE);
+
+ $libraries['css3pie']['variants']['js']['files']['js'][$file] = array(
+ 'browsers' => array('IE' => '(gte IE 6)&(lte IE 8)', '!IE' => FALSE),
+ 'weight' => 100,
+ 'every_page' => TRUE,
+ );
+ }
+
+ $libraries['html5shiv'] = array(
+ 'name' => t('HTML5 Shiv'),
+ 'description' => t('This script is the defacto way to enable use of HTML5 sectioning elements in legacy Internet Explorer, as well as default HTML5 styling in Internet Explorer 6 - 9, Safari 4.x (and iPhone 3.x), and Firefox 3.x.'),
+ 'vendor' => 'Alexander Farkas',
+ 'package' => t('Polyfills'),
+ 'files' => array(
+ 'js' => array(
+ omega_theme_trail_file('libraries/html5shiv/html5shiv.js') => array(
+ 'browsers' => array('IE' => '(gte IE 6)&(lte IE 8)', '!IE' => FALSE),
+ 'weight' => 100,
+ 'every_page' => TRUE,
+ ),
+ omega_theme_trail_file('libraries/html5shiv/html5shiv-printshiv.js') => array(
+ 'browsers' => array('IE' => '(gte IE 6)&(lte IE 8)', '!IE' => FALSE),
+ 'weight' => 100,
+ 'every_page' => TRUE,
+ ),
+ ),
+ ),
+ 'variants' => array(
+ 'source' => array(
+ 'name' => t('Source'),
+ 'description' => t('During development it might be useful to include the source files instead of the minified version.'),
+ 'files' => array(
+ 'js' => array(
+ omega_theme_trail_file('libraries/html5shiv/html5shiv.min.js') => array(
+ 'browsers' => array('IE' => '(gte IE 6)&(lte IE 8)', '!IE' => FALSE),
+ 'weight' => 100,
+ 'every_page' => TRUE,
+ ),
+ omega_theme_trail_file('libraries/html5shiv/html5shiv-printshiv.min.js') => array(
+ 'browsers' => array('IE' => '(gte IE 6)&(lte IE 8)', '!IE' => FALSE),
+ 'weight' => 100,
+ 'every_page' => TRUE,
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+
+ $libraries['messages'] = array(
+ 'name' => t('Discardable messages'),
+ 'description' => t("Adds a 'close' button to each message."),
+ 'package' => t('Goodies'),
+ 'files' => array(
+ 'js' => array(
+ omega_theme_trail_file('js/omega.messages.min.js') => array(
+ 'weight' => -100,
+ 'every_page' => TRUE,
+ ),
+ ),
+ 'css' => array(
+ omega_theme_trail_file('css/omega.messages.css') => array(
+ 'weight' => -100,
+ 'every_page' => TRUE,
+ ),
+ ),
+ ),
+ );
+
+ return $libraries;
+}
+
+/**
+ * Theme callback for rendering an Omega layout.
+ */
+function omega_omega_layout($variables) {
+ drupal_process_attached(array('#attached' => $variables['omega_layout']['attached']));
+
+ // Clean up the theme hook suggestion so we don't end up in an infinite loop.
+ unset($variables['theme_hook_suggestion'], $variables['theme_hook_suggestions']);
+ $hook = str_replace('-', '_', $variables['omega_layout']['template']);
+ return theme($hook, $variables);
+}
+
+/**
+ * Shows a notice when Google Chrome Frame is not installed.
+ */
+function omega_omega_chrome($variables) {
+ $message = t('You are using an outdated browser! Upgrade your browser today or install Google Chrome Frame to better experience this site.', array(
+ '!upgrade' => url('http://browsehappy.com'),
+ '!install' => url('http://www.google.com/chromeframe', array(
+ 'query' => array('redirect' => 'true')
+ )),
+ ));
+
+ return '
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/templates/block/block--minimal.tpl.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/templates/block/block--minimal.tpl.php Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,52 @@
+subject: Block title.
+ * - $content: Block content.
+ * - $block->module: Module that generated the block.
+ * - $block->delta: An ID for the block, unique within each module.
+ * - $block->region: The block region embedding the current block.
+ * - $classes: String of classes that can be used to style contextually through
+ * CSS. It can be manipulated through the variable $classes_array from
+ * preprocess functions. The default values can be one or more of the
+ * following:
+ * - block: The current template type, i.e., "theming hook".
+ * - block-[module]: The module generating the block. For example, the user
+ * module is responsible for handling the default user navigation block. In
+ * that case the class would be 'block-user'.
+ * - $title_prefix (array): An array containing additional output populated by
+ * modules, intended to be displayed in front of the main title tag that
+ * appears in the template.
+ * - $title_suffix (array): An array containing additional output populated by
+ * modules, intended to be displayed after the main title tag that appears in
+ * the template.
+ *
+ * Helper variables:
+ * - $classes_array: Array of html class attribute values. It is flattened
+ * into a string within the variable $classes.
+ * - $block_zebra: Outputs 'odd' and 'even' dependent on each block region.
+ * - $zebra: Same output as $block_zebra but independent of any block region.
+ * - $block_id: Counter dependent on each block region.
+ * - $id: Same output as $block_id but independent of any block region.
+ * - $is_front: Flags true when presented in the front page.
+ * - $logged_in: Flags true when the current user is a logged-in member.
+ * - $is_admin: Flags true when the current user is an administrator.
+ * - $block_html_id: A valid HTML ID and guaranteed unique.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_block()
+ * @see template_process()
+ *
+ * @ingroup themeable
+ */
+?>
+
+subject): ?>
+
>subject; ?>
+
+
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/templates/block/block--nav.tpl.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/templates/block/block--nav.tpl.php Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,55 @@
+subject: Block title.
+ * - $content: Block content.
+ * - $block->module: Module that generated the block.
+ * - $block->delta: An ID for the block, unique within each module.
+ * - $block->region: The block region embedding the current block.
+ * - $classes: String of classes that can be used to style contextually through
+ * CSS. It can be manipulated through the variable $classes_array from
+ * preprocess functions. The default values can be one or more of the
+ * following:
+ * - block: The current template type, i.e., "theming hook".
+ * - block-[module]: The module generating the block. For example, the user
+ * module is responsible for handling the default user navigation block. In
+ * that case the class would be 'block-user'.
+ * - $title_prefix (array): An array containing additional output populated by
+ * modules, intended to be displayed in front of the main title tag that
+ * appears in the template.
+ * - $title_suffix (array): An array containing additional output populated by
+ * modules, intended to be displayed after the main title tag that appears in
+ * the template.
+ *
+ * Helper variables:
+ * - $classes_array: Array of html class attribute values. It is flattened
+ * into a string within the variable $classes.
+ * - $block_zebra: Outputs 'odd' and 'even' dependent on each block region.
+ * - $zebra: Same output as $block_zebra but independent of any block region.
+ * - $block_id: Counter dependent on each block region.
+ * - $id: Same output as $block_id but independent of any block region.
+ * - $is_front: Flags true when presented in the front page.
+ * - $logged_in: Flags true when the current user is a logged-in member.
+ * - $is_admin: Flags true when the current user is an administrator.
+ * - $block_html_id: A valid HTML ID and guaranteed unique.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_block()
+ * @see template_process()
+ *
+ * @ingroup themeable
+ */
+?>
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/templates/block/block-admin-display-form.tpl.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/templates/block/block-admin-display-form.tpl.php Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,60 @@
+region_title: Region title for the listed block.
+ * - $data->block_title: Block title.
+ * - $data->region_select: Drop-down menu for assigning a region.
+ * - $data->weight_select: Drop-down menu for setting weights.
+ * - $data->configure_link: Block configuration link.
+ * - $data->delete_link: For deleting user added blocks.
+ *
+ * @see template_preprocess_block_admin_display_form()
+ * @see theme_block_admin_display()
+ *
+ * @ingroup themeable
+ */
+?>
+
+
+
+
+
+
+
+
+
+
+
+ $title): ?>
+
+
+
+
+
+
+ $data): ?>
+
+
block_title; ?>
+
region_select; ?>
+
weight_select; ?>
+
configure_link; ?>
+
delete_link; ?>
+
+
+
+
+
+
+
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/templates/block/block.tpl.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/templates/block/block.tpl.php Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,56 @@
+subject: Block title.
+ * - $content: Block content.
+ * - $block->module: Module that generated the block.
+ * - $block->delta: An ID for the block, unique within each module.
+ * - $block->region: The block region embedding the current block.
+ * - $classes: String of classes that can be used to style contextually through
+ * CSS. It can be manipulated through the variable $classes_array from
+ * preprocess functions. The default values can be one or more of the
+ * following:
+ * - block: The current template type, i.e., "theming hook".
+ * - block-[module]: The module generating the block. For example, the user
+ * module is responsible for handling the default user navigation block. In
+ * that case the class would be 'block-user'.
+ * - $title_prefix (array): An array containing additional output populated by
+ * modules, intended to be displayed in front of the main title tag that
+ * appears in the template.
+ * - $title_suffix (array): An array containing additional output populated by
+ * modules, intended to be displayed after the main title tag that appears in
+ * the template.
+ *
+ * Helper variables:
+ * - $classes_array: Array of html class attribute values. It is flattened
+ * into a string within the variable $classes.
+ * - $block_zebra: Outputs 'odd' and 'even' dependent on each block region.
+ * - $zebra: Same output as $block_zebra but independent of any block region.
+ * - $block_id: Counter dependent on each block region.
+ * - $id: Same output as $block_id but independent of any block region.
+ * - $is_front: Flags true when presented in the front page.
+ * - $logged_in: Flags true when the current user is a logged-in member.
+ * - $is_admin: Flags true when the current user is an administrator.
+ * - $block_html_id: A valid HTML ID and guaranteed unique.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_block()
+ * @see template_process()
+ *
+ * @ingroup themeable
+ */
+?>
+
+
+
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/templates/comment/comment.tpl.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/templates/comment/comment.tpl.php Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,90 @@
+created variable.
+ * - $changed: Formatted date and time for when the comment was last changed.
+ * Preprocess functions can reformat it by calling format_date() with the
+ * desired parameters on the $comment->changed variable.
+ * - $new: New comment marker.
+ * - $permalink: Comment permalink.
+ * - $submitted: Submission information created from $author and $created during
+ * template_preprocess_comment().
+ * - $user_picture: The comment author's picture from user-picture.tpl.php.
+ * - $signature: Authors signature.
+ * - $status: Comment status. Possible values are:
+ * comment-unpublished, comment-published or comment-preview.
+ * - $title: Linked title.
+ * - $classes: String of classes that can be used to style contextually through
+ * CSS. It can be manipulated through the variable $classes_array from
+ * preprocess functions. The default values can be one or more of the
+ * following:
+ * - comment: The current template type, i.e., "theming hook".
+ * - comment-by-anonymous: Comment by an unregistered user.
+ * - comment-by-node-author: Comment by the author of the parent node.
+ * - comment-preview: When previewing a new or edited comment.
+ * The following applies only to viewers who are registered users:
+ * - comment-unpublished: An unpublished comment visible only to
+ * administrators.
+ * - comment-by-viewer: Comment by the user currently viewing the page.
+ * - comment-new: New comment since last the visit.
+ * - $title_prefix (array): An array containing additional output populated by
+ * modules, intended to be displayed in front of the main title tag that
+ * appears in the template.
+ * - $title_suffix (array): An array containing additional output populated by
+ * modules, intended to be displayed after the main title tag that appears in
+ * the template.
+ *
+ * These two variables are provided for context:
+ * - $comment: Full comment object.
+ * - $node: Node object the comments are attached to.
+ *
+ * Other variables:
+ * - $classes_array: Array of html class attribute values. It is flattened
+ * into a string within the variable $classes.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_comment()
+ * @see template_process()
+ * @see theme_comment()
+ */
+?>
+>
+
+
+
+
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/templates/forum/forum-list.tpl.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/templates/forum/forum-list.tpl.php Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,78 @@
+is_container: TRUE if the forum can contain other forums. FALSE
+ * if the forum can contain only topics.
+ * - $forum->depth: How deep the forum is in the current hierarchy.
+ * - $forum->zebra: 'even' or 'odd' string used for row class.
+ * - $forum->icon_class: 'default' or 'new' string used for forum icon class.
+ * - $forum->icon_title: Text alternative for the forum icon.
+ * - $forum->name: The name of the forum.
+ * - $forum->link: The URL to link to this forum.
+ * - $forum->description: The description of this forum.
+ * - $forum->new_topics: TRUE if the forum contains unread posts.
+ * - $forum->new_url: A URL to the forum's unread posts.
+ * - $forum->new_text: Text for the above URL, which tells how many new posts.
+ * - $forum->old_topics: A count of posts that have already been read.
+ * - $forum->num_posts: The total number of posts in the forum.
+ * - $forum->last_reply: Text representing the last time a forum was posted or
+ * commented in.
+ * - $forum_id: Forum ID for the current forum. Parent to all items within the
+ * $forums array.
+ *
+ * @see template_preprocess_forum_list()
+ * @see theme_forum_list()
+ *
+ * @ingroup themeable
+ */
+?>
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/templates/forum/forum-topic-list.tpl.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/templates/forum/forum-topic-list.tpl.php Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,72 @@
+icon: The icon to display.
+ * - $topic->moved: A flag to indicate whether the topic has been moved to
+ * another forum.
+ * - $topic->title: The title of the topic. Safe to output.
+ * - $topic->message: If the topic has been moved, this contains an
+ * explanation and a link.
+ * - $topic->zebra: 'even' or 'odd' string used for row class.
+ * - $topic->comment_count: The number of replies on this topic.
+ * - $topic->new_replies: A flag to indicate whether there are unread
+ * comments.
+ * - $topic->new_url: If there are unread replies, this is a link to them.
+ * - $topic->new_text: Text containing the translated, properly pluralized
+ * count.
+ * - $topic->created: A string representing when the topic was posted. Safe
+ * to output.
+ * - $topic->last_reply: An outputtable string representing when the topic was
+ * last replied to.
+ * - $topic->timestamp: The raw timestamp this topic was posted.
+ * - $topic_id: Numeric ID for the current forum topic.
+ *
+ * @see template_preprocess_forum_topic_list()
+ * @see theme_forum_topic_list()
+ *
+ * @ingroup themeable
+ */
+?>
+
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/templates/node/node.tpl.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/templates/node/node.tpl.php Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,110 @@
+body becomes $body. When needing to access
+ * a field's raw values, developers/themers are strongly encouraged to use these
+ * variables. Otherwise they will have to explicitly specify the desired field
+ * language, e.g. $node->body['en'], thus overriding any language negotiation
+ * rule that was previously applied.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_node()
+ * @see template_process()
+ */
+?>
+>
+
+
+
+
+
+
+
+
+
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/templates/search/search-results.tpl.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/templates/search/search-results.tpl.php Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/templates/system/html.tpl.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/templates/system/html.tpl.php Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,66 @@
+language contains its textual representation.
+ * $language->dir contains the language direction. It will either be 'ltr' or 'rtl'.
+ * - $rdf_namespaces: All the RDF namespace prefixes used in the HTML document.
+ * - $grddl_profile: A GRDDL profile allowing agents to extract the RDF data.
+ * - $head_title: A modified version of the page title, for use in the TITLE
+ * tag.
+ * - $head_title_array: (array) An associative array containing the string parts
+ * that were used to generate the $head_title variable, already prepared to be
+ * output as TITLE tag. The key/value pairs may contain one or more of the
+ * following, depending on conditions:
+ * - title: The title of the current page, if any.
+ * - name: The name of the site.
+ * - slogan: The slogan of the site, if any, and if there is no title.
+ * - $head: Markup for the HEAD section (including meta tags, keyword tags, and
+ * so on).
+ * - $styles: Style tags necessary to import all CSS files for the page.
+ * - $scripts: Script tags necessary to load the JavaScript files and settings
+ * for the page.
+ * - $page_top: Initial markup from any modules that have altered the
+ * page. This variable should always be output first, before all other dynamic
+ * content.
+ * - $page: The rendered page content.
+ * - $page_bottom: Final closing markup from any modules that have altered the
+ * page. This variable should always be output last, after all other dynamic
+ * content.
+ * - $classes String of classes that can be used to style contextually through
+ * CSS.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_html()
+ * @see template_process()
+ */
+?>
+
+
+
+
+
+
+ >
+
+ >
+
+
+
+
+
+
+
+>
+
+
+
+
+
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/templates/system/maintenance-page.tpl.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/templates/system/maintenance-page.tpl.php Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>
+
+
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/theme-settings.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/theme-settings.php Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,215 @@
+ $name) {
+ $path = drupal_get_path('theme', $theme);
+
+ $filename = DRUPAL_ROOT . '/' . $path . '/template.php';
+ if (file_exists($filename)) {
+ require_once $filename;
+ }
+
+ $filename = DRUPAL_ROOT . '/' . $path . '/theme-settings.php';
+ if (file_exists($filename)) {
+ require_once $filename;
+ }
+ }
+
+ // Get the admin theme so we can set a class for styling this form.
+ $admin = drupal_html_class(variable_get('admin_theme', $GLOBALS['theme']));
+ $form['#prefix'] = '
';
+ $form['#suffix'] = '
';
+
+ // Add some custom styling and functionality to our theme settings form.
+ $form['#attached']['css'][] = drupal_get_path('theme', 'omega') . '/css/omega.admin.css';
+ $form['#attached']['js'][] = drupal_get_path('theme', 'omega') . '/js/omega.admin.min.js';
+
+ // Collapse all the core theme settings tabs in order to have the form actions
+ // visible all the time without having to scroll.
+ foreach (element_children($form) as $key) {
+ if ($form[$key]['#type'] == 'fieldset') {
+ $form[$key]['#collapsible'] = TRUE;
+ $form[$key]['#collapsed'] = TRUE;
+ }
+ }
+
+ if ($extensions = omega_extensions(NULL, TRUE)) {
+ $form['omega'] = array(
+ '#type' => 'vertical_tabs',
+ '#weight' => -10,
+ );
+
+ // Load the theme settings for all enabled extensions.
+ foreach ($extensions as $extension => $info) {
+ $form['omega'][$extension] = array(
+ '#type' => 'fieldset',
+ '#title' => $info['info']['name'],
+ '#attributes' => array(
+ 'class' => array('omega-extension'),
+ ),
+ );
+
+ $errors = array();
+ if (!empty($info['info']['dependencies'])) {
+ foreach ($info['info']['dependencies'] as $dependency) {
+ $dependency = drupal_parse_dependency($dependency);
+
+ // Check if the module exists.
+ if (!$module = system_get_info('module', $dependency['name'])) {
+ $errors[] = t('This extension requires the @module module.', array(
+ '@module' => ucwords(str_replace('_', ' ', $dependency['name'])),
+ ));
+ }
+ // Check if the module version is compatible.
+ elseif (($version = omega_check_incompatibility($dependency, $module['version'])) !== NULL) {
+ $errors[] = t('This extension requires @module @version. The currently installed version is @installed.', array(
+ '@module' => $module['name'],
+ '@version' => $version,
+ '@installed' => !empty($module['version']) ? $module['version'] : t('undetermined'),
+ ));
+ }
+ }
+
+ if (!empty($errors)) {
+ $form['omega'][$extension]['errors'] = array(
+ '#type' => 'item',
+ '#title' => t('Missing requirements'),
+ '#markup' => '
' . implode('
', $errors) . '
',
+ '#weight' => -20,
+ // Abuse the #name attribute to add a class to the form item.
+ '#name' => 'omega-requirements',
+ );
+ }
+ }
+
+ // Disable all options if there were any errors.
+ $form['omega'][$extension]['#disabled'] = !empty($errors) || variable_get('omega_toggle_extension_' . $extension) !== NULL;
+
+ $form['omega'][$extension]['omega_toggle_extension_' . $extension] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Enable @extension extension', array('@extension' => $info['info']['name'])) . (variable_get('omega_toggle_extension_' . $extension) !== NULL ? ' (' . t('overridden') . ')' : ''),
+ '#description' => t('This setting can be overridden with an equally named variable (@name) so you can control it on a per-environment basis by setting it in your settings.php file.', array('@name' => 'omega_toggle_extension_' . $extension)),
+ '#default_value' => omega_extension_enabled($extension),
+ '#weight' => -10,
+ );
+
+ $element = array();
+
+ // Load the implementation for this extensions and invoke the according
+ // hook.
+ $file = $info['path'] . '/' . $extension . '.settings.inc';
+ if (is_file($file)) {
+ require_once $file;
+ }
+
+ $function = $info['theme'] . '_extension_' . $extension . '_settings_form';
+ if (function_exists($function)) {
+ // By default, each extension resides in a vertical tab
+ $element = $function($element, $form, $form_state) + array(
+ '#type' => 'fieldset',
+ '#title' => t('@extension extension configuration', array('@extension' => $info['info']['name'])),
+ '#description' => $info['info']['description'],
+ '#states' => array(
+ 'disabled' => array(
+ 'input[name="omega_toggle_extension_' . $extension . '"]' => array('checked' => FALSE),
+ ),
+ ),
+ );
+ }
+
+ drupal_alter('extension_' . $extension . '_settings_form', $element, $form, $form_state);
+
+ if (element_children($element)) {
+ // Append the extension form to the theme settings form if it has any
+ // children.
+ $form['omega'][$extension]['settings'] = $element;
+ }
+ }
+ }
+
+ // Custom option for toggling the main content blog on the front page.
+ $form['theme_settings']['omega_toggle_front_page_content'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Front page content'),
+ '#description' => t('Allow the main content block to be rendered on the front page.'),
+ '#default_value' => omega_theme_get_setting('omega_toggle_front_page_content', TRUE),
+ );
+
+ // We need a custom form submit handler for processing some of the values.
+ $form['#submit'][] = 'omega_theme_settings_form_submit';
+
+ // Store the extensions in an array so we can loop over them in the submit
+ // callback.
+ $form_state['extensions'] = array_keys($extensions);
+}
+
+/**
+ * Form submit handler for the theme settings form.
+ */
+function omega_theme_settings_form_submit($form, &$form_state) {
+ // Clear the theme cache.
+ $theme = $form_state['build_info']['args'][0];
+ cache_clear_all('omega:' . $theme . ':', 'cache', TRUE);
+
+ // We also need to clear the static right away.
+ drupal_static_reset('omega_extensions');
+
+ // Rebuild the theme registry. This has quite a performance impact but since
+ // this only happens once after we (re-)saved the theme settings this is fine.
+ // Also, this is actually required because we are caching certain things in
+ // the theme registry.
+ drupal_theme_rebuild();
+
+ // We really don't want to reset theme settings for disabled extensions.
+ foreach ($form_state['extensions'] as $extension) {
+ if (!$form_state['values']['omega_toggle_extension_' . $extension]) {
+ _omega_retain_extension_settings($form, $form_state, $extension, $theme);
+ }
+ }
+
+ // This is a relict from the vertical tabs and should be removed so it doesn't
+ // end up in the theme settings array.
+ unset($form_state['values']['omega__active_tab']);
+}
+
+/**
+ * Helper function for retaining settings of an extension.
+ */
+function _omega_retain_extension_settings($form, &$form_state, $extension, $theme, $parents = array()) {
+ $current = array_merge(array('omega', $extension, 'settings'), $parents);
+
+ if ($items = drupal_array_get_nested_value($form, $current)) {
+ foreach (element_children($items) as $key) {
+ if (array_key_exists($key, $form_state['values'])) {
+ $form_state['values'][$key] = omega_theme_get_setting($key, NULL, $theme);
+ }
+
+ $next = array_merge($parents, array($key));
+ _omega_retain_extension_settings($form, $form_state, $extension, $theme, $next);
+ }
+ }
+}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/omega/theme/admin-block.theme.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/theme/admin-block.theme.inc Fri Sep 20 11:24:36 2013 +0100
@@ -0,0 +1,39 @@
+';
+ if (!empty($block['title'])) {
+ $output .= '
' . t('This theme requires PHP version @php_required and is incompatible with PHP version !php_version.', array('@php_required' => $theme->info['php'], '!php_version' => phpversion())) . '
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/templates/block/block--minimal.tpl.php
--- a/sites/all/themes/omega/templates/block/block--minimal.tpl.php Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-subject: Block title.
- * - $content: Block content.
- * - $block->module: Module that generated the block.
- * - $block->delta: An ID for the block, unique within each module.
- * - $block->region: The block region embedding the current block.
- * - $classes: String of classes that can be used to style contextually through
- * CSS. It can be manipulated through the variable $classes_array from
- * preprocess functions. The default values can be one or more of the
- * following:
- * - block: The current template type, i.e., "theming hook".
- * - block-[module]: The module generating the block. For example, the user
- * module is responsible for handling the default user navigation block. In
- * that case the class would be 'block-user'.
- * - $title_prefix (array): An array containing additional output populated by
- * modules, intended to be displayed in front of the main title tag that
- * appears in the template.
- * - $title_suffix (array): An array containing additional output populated by
- * modules, intended to be displayed after the main title tag that appears in
- * the template.
- *
- * Helper variables:
- * - $classes_array: Array of html class attribute values. It is flattened
- * into a string within the variable $classes.
- * - $block_zebra: Outputs 'odd' and 'even' dependent on each block region.
- * - $zebra: Same output as $block_zebra but independent of any block region.
- * - $block_id: Counter dependent on each block region.
- * - $id: Same output as $block_id but independent of any block region.
- * - $is_front: Flags true when presented in the front page.
- * - $logged_in: Flags true when the current user is a logged-in member.
- * - $is_admin: Flags true when the current user is an administrator.
- * - $block_html_id: A valid HTML ID and guaranteed unique.
- *
- * @see template_preprocess()
- * @see template_preprocess_block()
- * @see template_process()
- *
- * @ingroup themeable
- */
-?>
-
-subject): ?>
-
>subject; ?>
-
-
-
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/templates/block/block--nav.tpl.php
--- a/sites/all/themes/omega/templates/block/block--nav.tpl.php Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-subject: Block title.
- * - $content: Block content.
- * - $block->module: Module that generated the block.
- * - $block->delta: An ID for the block, unique within each module.
- * - $block->region: The block region embedding the current block.
- * - $classes: String of classes that can be used to style contextually through
- * CSS. It can be manipulated through the variable $classes_array from
- * preprocess functions. The default values can be one or more of the
- * following:
- * - block: The current template type, i.e., "theming hook".
- * - block-[module]: The module generating the block. For example, the user
- * module is responsible for handling the default user navigation block. In
- * that case the class would be 'block-user'.
- * - $title_prefix (array): An array containing additional output populated by
- * modules, intended to be displayed in front of the main title tag that
- * appears in the template.
- * - $title_suffix (array): An array containing additional output populated by
- * modules, intended to be displayed after the main title tag that appears in
- * the template.
- *
- * Helper variables:
- * - $classes_array: Array of html class attribute values. It is flattened
- * into a string within the variable $classes.
- * - $block_zebra: Outputs 'odd' and 'even' dependent on each block region.
- * - $zebra: Same output as $block_zebra but independent of any block region.
- * - $block_id: Counter dependent on each block region.
- * - $id: Same output as $block_id but independent of any block region.
- * - $is_front: Flags true when presented in the front page.
- * - $logged_in: Flags true when the current user is a logged-in member.
- * - $is_admin: Flags true when the current user is an administrator.
- * - $block_html_id: A valid HTML ID and guaranteed unique.
- *
- * @see template_preprocess()
- * @see template_preprocess_block()
- * @see template_process()
- *
- * @ingroup themeable
- */
-?>
-
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/templates/block/block-admin-display-form.tpl.php
--- a/sites/all/themes/omega/templates/block/block-admin-display-form.tpl.php Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-region_title: Region title for the listed block.
- * - $data->block_title: Block title.
- * - $data->region_select: Drop-down menu for assigning a region.
- * - $data->weight_select: Drop-down menu for setting weights.
- * - $data->configure_link: Block configuration link.
- * - $data->delete_link: For deleting user added blocks.
- *
- * @see template_preprocess_block_admin_display_form()
- * @see theme_block_admin_display()
- *
- * @ingroup themeable
- */
-?>
-
-
-
-
-
-
-
-
-
-
-
- $title): ?>
-
-
-
-
-
-
- $data): ?>
-
-
block_title; ?>
-
region_select; ?>
-
weight_select; ?>
-
configure_link; ?>
-
delete_link; ?>
-
-
-
-
-
-
-
-
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/templates/block/block.tpl.php
--- a/sites/all/themes/omega/templates/block/block.tpl.php Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-subject: Block title.
- * - $content: Block content.
- * - $block->module: Module that generated the block.
- * - $block->delta: An ID for the block, unique within each module.
- * - $block->region: The block region embedding the current block.
- * - $classes: String of classes that can be used to style contextually through
- * CSS. It can be manipulated through the variable $classes_array from
- * preprocess functions. The default values can be one or more of the
- * following:
- * - block: The current template type, i.e., "theming hook".
- * - block-[module]: The module generating the block. For example, the user
- * module is responsible for handling the default user navigation block. In
- * that case the class would be 'block-user'.
- * - $title_prefix (array): An array containing additional output populated by
- * modules, intended to be displayed in front of the main title tag that
- * appears in the template.
- * - $title_suffix (array): An array containing additional output populated by
- * modules, intended to be displayed after the main title tag that appears in
- * the template.
- *
- * Helper variables:
- * - $classes_array: Array of html class attribute values. It is flattened
- * into a string within the variable $classes.
- * - $block_zebra: Outputs 'odd' and 'even' dependent on each block region.
- * - $zebra: Same output as $block_zebra but independent of any block region.
- * - $block_id: Counter dependent on each block region.
- * - $id: Same output as $block_id but independent of any block region.
- * - $is_front: Flags true when presented in the front page.
- * - $logged_in: Flags true when the current user is a logged-in member.
- * - $is_admin: Flags true when the current user is an administrator.
- * - $block_html_id: A valid HTML ID and guaranteed unique.
- *
- * @see template_preprocess()
- * @see template_preprocess_block()
- * @see template_process()
- *
- * @ingroup themeable
- */
-?>
-
-
-
-
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/templates/comment/comment.tpl.php
--- a/sites/all/themes/omega/templates/comment/comment.tpl.php Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-created variable.
- * - $changed: Formatted date and time for when the comment was last changed.
- * Preprocess functions can reformat it by calling format_date() with the
- * desired parameters on the $comment->changed variable.
- * - $new: New comment marker.
- * - $permalink: Comment permalink.
- * - $submitted: Submission information created from $author and $created during
- * template_preprocess_comment().
- * - $user_picture: The comment author's picture from user-picture.tpl.php.
- * - $signature: Authors signature.
- * - $status: Comment status. Possible values are:
- * comment-unpublished, comment-published or comment-preview.
- * - $title: Linked title.
- * - $classes: String of classes that can be used to style contextually through
- * CSS. It can be manipulated through the variable $classes_array from
- * preprocess functions. The default values can be one or more of the
- * following:
- * - comment: The current template type, i.e., "theming hook".
- * - comment-by-anonymous: Comment by an unregistered user.
- * - comment-by-node-author: Comment by the author of the parent node.
- * - comment-preview: When previewing a new or edited comment.
- * The following applies only to viewers who are registered users:
- * - comment-unpublished: An unpublished comment visible only to
- * administrators.
- * - comment-by-viewer: Comment by the user currently viewing the page.
- * - comment-new: New comment since last the visit.
- * - $title_prefix (array): An array containing additional output populated by
- * modules, intended to be displayed in front of the main title tag that
- * appears in the template.
- * - $title_suffix (array): An array containing additional output populated by
- * modules, intended to be displayed after the main title tag that appears in
- * the template.
- *
- * These two variables are provided for context:
- * - $comment: Full comment object.
- * - $node: Node object the comments are attached to.
- *
- * Other variables:
- * - $classes_array: Array of html class attribute values. It is flattened
- * into a string within the variable $classes.
- *
- * @see template_preprocess()
- * @see template_preprocess_comment()
- * @see template_process()
- * @see theme_comment()
- */
-?>
->
-
-
-
-
-
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/templates/forum/forum-list.tpl.php
--- a/sites/all/themes/omega/templates/forum/forum-list.tpl.php Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-is_container: TRUE if the forum can contain other forums. FALSE
- * if the forum can contain only topics.
- * - $forum->depth: How deep the forum is in the current hierarchy.
- * - $forum->zebra: 'even' or 'odd' string used for row class.
- * - $forum->icon_class: 'default' or 'new' string used for forum icon class.
- * - $forum->icon_title: Text alternative for the forum icon.
- * - $forum->name: The name of the forum.
- * - $forum->link: The URL to link to this forum.
- * - $forum->description: The description of this forum.
- * - $forum->new_topics: TRUE if the forum contains unread posts.
- * - $forum->new_url: A URL to the forum's unread posts.
- * - $forum->new_text: Text for the above URL, which tells how many new posts.
- * - $forum->old_topics: A count of posts that have already been read.
- * - $forum->num_posts: The total number of posts in the forum.
- * - $forum->last_reply: Text representing the last time a forum was posted or
- * commented in.
- * - $forum_id: Forum ID for the current forum. Parent to all items within the
- * $forums array.
- *
- * @see template_preprocess_forum_list()
- * @see theme_forum_list()
- *
- * @ingroup themeable
- */
-?>
-
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/templates/forum/forum-topic-list.tpl.php
--- a/sites/all/themes/omega/templates/forum/forum-topic-list.tpl.php Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-icon: The icon to display.
- * - $topic->moved: A flag to indicate whether the topic has been moved to
- * another forum.
- * - $topic->title: The title of the topic. Safe to output.
- * - $topic->message: If the topic has been moved, this contains an
- * explanation and a link.
- * - $topic->zebra: 'even' or 'odd' string used for row class.
- * - $topic->comment_count: The number of replies on this topic.
- * - $topic->new_replies: A flag to indicate whether there are unread
- * comments.
- * - $topic->new_url: If there are unread replies, this is a link to them.
- * - $topic->new_text: Text containing the translated, properly pluralized
- * count.
- * - $topic->created: A string representing when the topic was posted. Safe
- * to output.
- * - $topic->last_reply: An outputtable string representing when the topic was
- * last replied to.
- * - $topic->timestamp: The raw timestamp this topic was posted.
- * - $topic_id: Numeric ID for the current forum topic.
- *
- * @see template_preprocess_forum_topic_list()
- * @see theme_forum_topic_list()
- *
- * @ingroup themeable
- */
-?>
-
-
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/templates/node/node.tpl.php
--- a/sites/all/themes/omega/templates/node/node.tpl.php Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-body becomes $body. When needing to access
- * a field's raw values, developers/themers are strongly encouraged to use these
- * variables. Otherwise they will have to explicitly specify the desired field
- * language, e.g. $node->body['en'], thus overriding any language negotiation
- * rule that was previously applied.
- *
- * @see template_preprocess()
- * @see template_preprocess_node()
- * @see template_process()
- */
-?>
->
-
-
-
-
-
-
-
-
-
-
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/templates/search/search-results.tpl.php
--- a/sites/all/themes/omega/templates/search/search-results.tpl.php Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/templates/system/html.tpl.php
--- a/sites/all/themes/omega/templates/system/html.tpl.php Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-language contains its textual representation.
- * $language->dir contains the language direction. It will either be 'ltr' or 'rtl'.
- * - $rdf_namespaces: All the RDF namespace prefixes used in the HTML document.
- * - $grddl_profile: A GRDDL profile allowing agents to extract the RDF data.
- * - $head_title: A modified version of the page title, for use in the TITLE
- * tag.
- * - $head_title_array: (array) An associative array containing the string parts
- * that were used to generate the $head_title variable, already prepared to be
- * output as TITLE tag. The key/value pairs may contain one or more of the
- * following, depending on conditions:
- * - title: The title of the current page, if any.
- * - name: The name of the site.
- * - slogan: The slogan of the site, if any, and if there is no title.
- * - $head: Markup for the HEAD section (including meta tags, keyword tags, and
- * so on).
- * - $styles: Style tags necessary to import all CSS files for the page.
- * - $scripts: Script tags necessary to load the JavaScript files and settings
- * for the page.
- * - $page_top: Initial markup from any modules that have altered the
- * page. This variable should always be output first, before all other dynamic
- * content.
- * - $page: The rendered page content.
- * - $page_bottom: Final closing markup from any modules that have altered the
- * page. This variable should always be output last, after all other dynamic
- * content.
- * - $classes String of classes that can be used to style contextually through
- * CSS.
- *
- * @see template_preprocess()
- * @see template_preprocess_html()
- * @see template_process()
- */
-?>
-
-
-
-
-
-
- >
-
- >
-
-
-
-
-
-
-
->
-
-
-
-
-
-
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/templates/system/maintenance-page.tpl.php
--- a/sites/all/themes/omega/templates/system/maintenance-page.tpl.php Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
->
-
-
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/theme-settings.php
--- a/sites/all/themes/omega/theme-settings.php Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,215 +0,0 @@
- $name) {
- $path = drupal_get_path('theme', $theme);
-
- $filename = DRUPAL_ROOT . '/' . $path . '/template.php';
- if (file_exists($filename)) {
- require_once $filename;
- }
-
- $filename = DRUPAL_ROOT . '/' . $path . '/theme-settings.php';
- if (file_exists($filename)) {
- require_once $filename;
- }
- }
-
- // Get the admin theme so we can set a class for styling this form.
- $admin = drupal_html_class(variable_get('admin_theme', $GLOBALS['theme']));
- $form['#prefix'] = '
';
- $form['#suffix'] = '
';
-
- // Add some custom styling and functionality to our theme settings form.
- $form['#attached']['css'][] = drupal_get_path('theme', 'omega') . '/css/omega.admin.css';
- $form['#attached']['js'][] = drupal_get_path('theme', 'omega') . '/js/omega.admin.min.js';
-
- // Collapse all the core theme settings tabs in order to have the form actions
- // visible all the time without having to scroll.
- foreach (element_children($form) as $key) {
- if ($form[$key]['#type'] == 'fieldset') {
- $form[$key]['#collapsible'] = TRUE;
- $form[$key]['#collapsed'] = TRUE;
- }
- }
-
- if ($extensions = omega_extensions(NULL, TRUE)) {
- $form['omega'] = array(
- '#type' => 'vertical_tabs',
- '#weight' => -10,
- );
-
- // Load the theme settings for all enabled extensions.
- foreach ($extensions as $extension => $info) {
- $form['omega'][$extension] = array(
- '#type' => 'fieldset',
- '#title' => $info['info']['name'],
- '#attributes' => array(
- 'class' => array('omega-extension'),
- ),
- );
-
- $errors = array();
- if (!empty($info['info']['dependencies'])) {
- foreach ($info['info']['dependencies'] as $dependency) {
- $dependency = drupal_parse_dependency($dependency);
-
- // Check if the module exists.
- if (!$module = system_get_info('module', $dependency['name'])) {
- $errors[] = t('This extension requires the @module module.', array(
- '@module' => ucwords(str_replace('_', ' ', $dependency['name'])),
- ));
- }
- // Check if the module version is compatible.
- elseif (($version = omega_check_incompatibility($dependency, $module['version'])) !== NULL) {
- $errors[] = t('This extension requires @module @version. The currently installed version is @installed.', array(
- '@module' => $module['name'],
- '@version' => $version,
- '@installed' => !empty($module['version']) ? $module['version'] : t('undetermined'),
- ));
- }
- }
-
- if (!empty($errors)) {
- $form['omega'][$extension]['errors'] = array(
- '#type' => 'item',
- '#title' => t('Missing requirements'),
- '#markup' => '
' . implode('
', $errors) . '
',
- '#weight' => -20,
- // Abuse the #name attribute to add a class to the form item.
- '#name' => 'omega-requirements',
- );
- }
- }
-
- // Disable all options if there were any errors.
- $form['omega'][$extension]['#disabled'] = !empty($errors) || variable_get('omega_toggle_extension_' . $extension) !== NULL;
-
- $form['omega'][$extension]['omega_toggle_extension_' . $extension] = array(
- '#type' => 'checkbox',
- '#title' => t('Enable @extension extension', array('@extension' => $info['info']['name'])) . (variable_get('omega_toggle_extension_' . $extension) !== NULL ? ' (' . t('overridden') . ')' : ''),
- '#description' => t('This setting can be overridden with an equally named variable (@name) so you can control it on a per-environment basis by setting it in your settings.php file.', array('@name' => 'omega_toggle_extension_' . $extension)),
- '#default_value' => omega_extension_enabled($extension),
- '#weight' => -10,
- );
-
- $element = array();
-
- // Load the implementation for this extensions and invoke the according
- // hook.
- $file = $info['path'] . '/' . $extension . '.settings.inc';
- if (is_file($file)) {
- require_once $file;
- }
-
- $function = $info['theme'] . '_extension_' . $extension . '_settings_form';
- if (function_exists($function)) {
- // By default, each extension resides in a vertical tab
- $element = $function($element, $form, $form_state) + array(
- '#type' => 'fieldset',
- '#title' => t('@extension extension configuration', array('@extension' => $info['info']['name'])),
- '#description' => $info['info']['description'],
- '#states' => array(
- 'disabled' => array(
- 'input[name="omega_toggle_extension_' . $extension . '"]' => array('checked' => FALSE),
- ),
- ),
- );
- }
-
- drupal_alter('extension_' . $extension . '_settings_form', $element, $form, $form_state);
-
- if (element_children($element)) {
- // Append the extension form to the theme settings form if it has any
- // children.
- $form['omega'][$extension]['settings'] = $element;
- }
- }
- }
-
- // Custom option for toggling the main content blog on the front page.
- $form['theme_settings']['omega_toggle_front_page_content'] = array(
- '#type' => 'checkbox',
- '#title' => t('Front page content'),
- '#description' => t('Allow the main content block to be rendered on the front page.'),
- '#default_value' => omega_theme_get_setting('omega_toggle_front_page_content', TRUE),
- );
-
- // We need a custom form submit handler for processing some of the values.
- $form['#submit'][] = 'omega_theme_settings_form_submit';
-
- // Store the extensions in an array so we can loop over them in the submit
- // callback.
- $form_state['extensions'] = array_keys($extensions);
-}
-
-/**
- * Form submit handler for the theme settings form.
- */
-function omega_theme_settings_form_submit($form, &$form_state) {
- // Clear the theme cache.
- $theme = $form_state['build_info']['args'][0];
- cache_clear_all('omega:' . $theme . ':', 'cache', TRUE);
-
- // We also need to clear the static right away.
- drupal_static_reset('omega_extensions');
-
- // Rebuild the theme registry. This has quite a performance impact but since
- // this only happens once after we (re-)saved the theme settings this is fine.
- // Also, this is actually required because we are caching certain things in
- // the theme registry.
- drupal_theme_rebuild();
-
- // We really don't want to reset theme settings for disabled extensions.
- foreach ($form_state['extensions'] as $extension) {
- if (!$form_state['values']['omega_toggle_extension_' . $extension]) {
- _omega_retain_extension_settings($form, $form_state, $extension, $theme);
- }
- }
-
- // This is a relict from the vertical tabs and should be removed so it doesn't
- // end up in the theme settings array.
- unset($form_state['values']['omega__active_tab']);
-}
-
-/**
- * Helper function for retaining settings of an extension.
- */
-function _omega_retain_extension_settings($form, &$form_state, $extension, $theme, $parents = array()) {
- $current = array_merge(array('omega', $extension, 'settings'), $parents);
-
- if ($items = drupal_array_get_nested_value($form, $current)) {
- foreach (element_children($items) as $key) {
- if (array_key_exists($key, $form_state['values'])) {
- $form_state['values'][$key] = omega_theme_get_setting($key, NULL, $theme);
- }
-
- $next = array_merge($parents, array($key));
- _omega_retain_extension_settings($form, $form_state, $extension, $theme, $next);
- }
- }
-}
diff -r ce11bbd8f642 -r 49b8ebaaad78 sites/all/themes/omega/theme/admin-block.theme.inc
--- a/sites/all/themes/omega/theme/admin-block.theme.inc Thu Sep 19 10:38:44 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-';
- if (!empty($block['title'])) {
- $output .= '
' . t('This theme requires PHP version @php_required and is incompatible with PHP version !php_version.', array('@php_required' => $theme->info['php'], '!php_version' => phpversion())) . '